ols 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,6 @@
1
+ # encoding: utf-8
2
+
1
3
  module OLS
2
- VERSION = "0.0.1"
4
+ # OLS::VERSION - The OLS gem version
5
+ VERSION = "0.1.0"
3
6
  end
@@ -9,15 +9,10 @@ Gem::Specification.new do |s|
9
9
  s.authors = ["Darren Oakley"]
10
10
  s.email = ["daz.oakley@gmail.com"]
11
11
  s.homepage = "https://github.com/dazoakley/ols"
12
- s.summary = %q{A simple wrapper around a local copy of the OLS database}
12
+ s.summary = %q{A simple wrapper around the EBI's Ontology Lookup Service (OLS)}
13
13
  s.description = %q{
14
- OLS provides a simple interface to the EBI's Ontology Lookup Service (http://www.ebi.ac.uk/ontology-lookup/).
15
- It provides an easy lookup of ontology terms and automagically builds up ontology trees using RubyTree
16
- (http://rubytree.rubyforge.org/) as a base library.
17
-
18
- PLEASE NOTE: The current version of this gem requires a local install of the OLS database running on MySQL.
19
- Please see http://www.ebi.ac.uk/ontology-lookup/databaseExport.do I will update the code in the future
20
- to run off the soap service.
14
+ OLS provides a simple interface to the EBI's Ontology Lookup Service (http://www.ebi.ac.uk/ontology-lookup/).
15
+ It provides an easy lookup of ontology terms and automagically builds up ontology trees for you.
21
16
  }
22
17
 
23
18
  s.rubyforge_project = "ols"
@@ -27,13 +22,13 @@ Gem::Specification.new do |s|
27
22
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
28
23
  s.require_paths = ["lib"]
29
24
 
30
- s.add_dependency "rubytree"
31
- s.add_dependency "sequel"
32
- s.add_dependency "mysql2"
33
- s.add_dependency "json"
25
+ s.add_dependency "savon"
34
26
 
35
27
  s.add_development_dependency "rake"
36
28
  s.add_development_dependency "shoulda"
29
+ s.add_development_dependency "vcr"
30
+ s.add_development_dependency "webmock"
37
31
  s.add_development_dependency "simplecov"
38
32
  s.add_development_dependency "simplecov-rcov"
33
+ s.add_development_dependency "mocha"
39
34
  end
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/ols.rb'}"
7
+
8
+ puts "Loading ols gem"
9
+ exec "#{irb} #{libs} --simple-prompt"
@@ -8,27 +8,42 @@ if /^1.9/ === RUBY_VERSION
8
8
  begin
9
9
  require 'simplecov'
10
10
  require 'simplecov-rcov'
11
-
11
+
12
12
  class SimpleCov::Formatter::MergedFormatter
13
13
  def format(result)
14
14
  SimpleCov::Formatter::HTMLFormatter.new.format(result)
15
15
  SimpleCov::Formatter::RcovFormatter.new.format(result)
16
16
  end
17
17
  end
18
-
18
+
19
19
  SimpleCov.formatter = SimpleCov::Formatter::MergedFormatter
20
- SimpleCov.start
20
+ SimpleCov.start do
21
+ add_filter "/test/"
22
+ end
21
23
  rescue LoadError
22
24
  puts "[ERROR] Unable to load 'simplecov' - please run 'bundle install'"
23
25
  end
24
26
  end
25
27
 
26
28
  require 'shoulda'
29
+ require 'vcr'
30
+ require 'mocha'
27
31
  require 'ols'
28
32
 
29
- OLS.db_connection_details = {
30
- :port => 13306,
31
- :database => 'htgt_ols',
32
- :user => 'htgt',
33
- :password => 'htgt'
34
- }
33
+ # Set-up VCR for mocking up web requests.
34
+ VCR.config do |c|
35
+ if /^1\.8/ === RUBY_VERSION
36
+ c.cassette_library_dir = 'test/vcr_cassettes_ruby1.8'
37
+ elsif RUBY_VERSION == "1.9.1"
38
+ c.cassette_library_dir = 'test/vcr_cassettes_ruby1.9.1'
39
+ else
40
+ c.cassette_library_dir = 'test/vcr_cassettes_ruby1.9.2+'
41
+ end
42
+
43
+ c.stub_with :webmock
44
+ c.ignore_localhost = true
45
+ c.default_cassette_options = {
46
+ :record => :new_episodes,
47
+ :match_requests_on => [:uri, :method, :body]
48
+ }
49
+ end
@@ -1,124 +1,56 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class OLSTest < Test::Unit::TestCase
4
- include OLS
5
-
6
- context "An OntologyTerm object" do
4
+ context 'The OLS module' do
7
5
  setup do
8
- @emap_id = "EMAP:3018"
9
- @emap_name = "TS18,nose"
10
- @ont = OntologyTerm.new(@emap_id)
6
+ VCR.insert_cassette('test_ols')
11
7
  end
12
-
13
- should "have basic attributes" do
14
- assert_equal( @emap_id, @ont.name, "OntologyTerm.name does not equal '#{@emap_id}'." )
15
- assert_equal( @emap_id, @ont.term, "OntologyTerm.term does not equal '#{@emap_id}'." )
16
-
17
- assert_equal( @emap_name, @ont.content, "OntologyTerm.content does not equal '#{@emap_name}'." )
18
- assert_equal( @emap_name, @ont.term_name, "OntologyTerm.term_name does not equal '#{@emap_name}'." )
19
-
20
- assert_equal( false, @ont.term_name.nil?, "The OntologyTerm.term_name is nil." )
21
- assert_equal( false, @ont.content.nil?, "The OntologyTerm.term_name is nil." )
22
- end
23
-
24
- should "raise appropriate errors" do
25
- assert_raise(OntologyTermNotFoundError) { OntologyTerm.new("FLIBBLE:5") }
26
- end
27
-
28
- should "be able to represent itself as a String" do
29
- string = @ont.to_s
30
-
31
- assert( string.include?('Term Name'), "OntologyTerm.to_s does not include 'Term Name'." )
32
- assert( string.include?(@ont.content), "OntologyTerm.to_s does not include '@content'." )
33
- assert( string.include?('Root Term?'), "OntologyTerm.to_s does not include 'Root Term?'." )
34
- assert( string.include?('Leaf Node?'), "OntologyTerm.to_s does not include 'Leaf Node?'." )
35
- end
36
-
37
- should "respond correctly to the .parentage method" do
38
- assert( @ont.parentage.is_a?(Array), "OntologyTerm.parentage is not an Array when we have parents." )
39
- assert( @ont.parentage[0].is_a?(OntologyTerm), "OntologyTerm.parentage[0] does not return an OntologyTerm tree." )
40
- assert_equal( 4, @ont.parentage.size, "OntologyTerm.parentage is not returning the correct number of entries (we expect 4 for #{@emap_id})." )
41
- end
42
-
43
- should "be able to generate its child tree" do
44
- assert( @ont.child_tree.is_a?(OntologyTerm), "OntologyTerm.child_tree does not return an OntologyTerm tree." )
45
- assert_equal( @ont.term, @ont.child_tree.term, "OntologyTerm.child_tree.root is equal to self." )
46
- end
47
-
48
- should "respond correctly to the .children method" do
49
- assert( @ont.children.is_a?(Array), "OntologyTerm.children is not an Array when we have children." )
50
- assert( @ont.children[0].is_a?(OntologyTerm), "OntologyTerm.children[0] does not return an OntologyTerm tree." )
51
- assert_equal( 3, @ont.children.size, "OntologyTerm.children is not returning the correct number of entries (we expect 3 direct children for #{@emap_id})." )
8
+
9
+ teardown do
10
+ VCR.eject_cassette
52
11
  end
53
-
54
- should "be able to generate a flat list of all child terms/names" do
55
- assert( @ont.all_child_terms.is_a?(Array), "OntologyTerm.all_child_terms is not an Array." )
56
- assert( @ont.all_child_terms[0].is_a?(String), "OntologyTerm.all_child_terms[0] is not an String." )
57
- assert_equal( 14, @ont.all_child_terms.size, "OntologyTerm.all_child_terms is not returning the correct number of entries (we expect 14 children for #{@emap_id})." )
58
-
59
- assert( @ont.all_child_names.is_a?(Array), "OntologyTerm.all_child_names is not an Array." )
60
- assert( @ont.all_child_names[0].is_a?(String), "OntologyTerm.all_child_names[0] is not an String." )
61
- assert_equal( 14, @ont.all_child_names.size, "OntologyTerm.all_child_names is not returning the correct number of entries (we expect 14 children for #{@emap_id})." )
62
-
63
- assert_equal( @ont.all_child_terms.size, @ont.all_child_names.size, "OntologyTerm.all_child_terms and OntologyTerm.all_child_names do not produce an array of the same size." )
12
+
13
+ should 'make a connection to the OLS SOAP service' do
14
+ assert OLS.client
15
+ assert OLS.client.is_a? Savon::Client
64
16
  end
65
-
66
- should "be able to locate ontology terms via synonyms" do
67
- go_id = 'GO:0007242'
68
- ont = OntologyTerm.new(go_id)
69
-
70
- assert_equal( 'GO:0023034', ont.term, "A synonym search for GO:0007242 has not found GO:0023034." )
71
- assert_equal( 'intracellular signaling pathway', ont.term_name, "A synonym search for GO:0007242 has not found 'intracellular signaling pathway'." )
17
+
18
+ should 'give access to version metadata' do
19
+ assert OLS.version
20
+ assert OLS.version.is_a? String
72
21
  end
73
-
74
- should "be able to serialize/deserialize itself as a JSON string" do
75
- @ont.build_tree()
76
-
77
- json_string = nil
78
- assert_nothing_raised(Exception) { json_string = @ont.to_json }
79
- assert( json_string.is_a?(String) )
80
-
81
- duplicate = nil
82
- assert_nothing_raised(Exception) { duplicate = JSON.parse(json_string) }
83
- assert( duplicate.is_a?(OntologyTerm) )
84
- assert_equal( @ont.term, duplicate.term )
85
- assert_equal( @ont.term_name, duplicate.term_name )
86
- assert_equal( @ont.is_root?, duplicate.is_root? )
87
- assert_equal( @ont.is_leaf?, duplicate.is_leaf? )
22
+
23
+ should 'list the available ontologies' do
24
+ assert OLS.ontologies
25
+ assert OLS.ontologies.is_a? Hash
26
+ assert OLS.ontologies.include?('EMAP')
88
27
  end
89
-
90
- should "be able to produce a detached copy of itself" do
91
- @ont.build_tree()
92
- duplicate = @ont.detached_copy
93
-
94
- assert_equal( @ont.term, duplicate.term )
95
- assert_equal( @ont.term_name, duplicate.term_name )
96
- assert_equal( @ont.is_root?, duplicate.is_root? )
97
- assert_equal( @ont.is_leaf?, duplicate.is_leaf? )
98
-
99
- assert_equal( false, duplicate.send(:already_fetched_parents) )
100
- assert_equal( false, duplicate.send(:already_fetched_children) )
28
+
29
+ should 'provide easy access to the root terms of ontologies' do
30
+ emap_roots = OLS.root_terms('EMAP')
31
+ emap_root = emap_roots.first
32
+
33
+ assert emap_roots.is_a? Array
34
+ assert emap_root.is_a? OLS::Term
35
+ assert_equal 'EMAP:0', emap_root.term_id
36
+ assert_equal 'Mouse_anatomy_by_time_xproduct', emap_root.term_name
37
+ assert emap_root.parents.empty?
38
+ assert_equal 3, OLS.root_terms('GO').size
101
39
  end
102
-
103
- should "be able to merge two ontology trees" do
104
- @ont2 = OntologyTerm.new('EMAP:3003')
105
-
106
- @ont.build_tree
107
- @ont2.build_tree
108
-
109
- merged_tree = @ont.merge(@ont2)
110
-
111
- assert( merged_tree['EMAP:2636']['EMAP:2822']['EMAP:2987'].is_a?(OntologyTerm) )
112
- assert_equal( 2, merged_tree['EMAP:2636']['EMAP:2822']['EMAP:2987'].children.size )
113
- assert_equal( 34, merged_tree.size )
114
-
115
- another_ont = OntologyTerm.new('GO:0023034')
116
- yet_another_ont = OntologyTerm.new('EMAP:3003')
117
- another_ont.build_tree
118
- yet_another_ont.build_tree
119
-
120
- assert_raise(ArgumentError) { foo = another_ont.merge(yet_another_ont) }
121
- assert_raise(TypeError) { bar = another_ont.merge('EMAP:3003') }
40
+
41
+ should 'find terms by id' do
42
+ emap_0 = OLS.find_by_id('EMAP:0')
43
+ assert emap_0.is_a? OLS::Term
44
+ assert_equal 'Mouse_anatomy_by_time_xproduct', emap_0.term_name
45
+ assert_raise(OLS::TermNotFoundError) { OLS.find_by_id('MP:WIBBLE') }
122
46
  end
47
+
48
+ # should 'be able to find terms by name' do
49
+ # terms = OLS.find_by_name('mitochondrion','GO')
50
+ # assert terms.first.is_a? OLS::Term
51
+ # assert terms.size > 2
52
+ # assert terms.delete_if { |elm| elm.term_name =~ /mitochondrion/ }.size == 0
53
+ # end
123
54
  end
124
- end
55
+ end
56
+
@@ -0,0 +1,36 @@
1
+ require 'test_helper'
2
+
3
+ class OLSGraphTest < Test::Unit::TestCase
4
+ context 'An OLS::Graph object' do
5
+ setup do
6
+ VCR.insert_cassette('test_ols_term')
7
+ end
8
+
9
+ teardown do
10
+ VCR.eject_cassette
11
+ end
12
+
13
+ context 'once created' do
14
+ setup do
15
+ @graph = OLS::Graph.new
16
+ end
17
+
18
+ should 'initialize correctly' do
19
+ assert @graph.instance_variable_get(:@graph).is_a? Hash
20
+ assert @graph.instance_variable_get(:@graph).empty?
21
+ end
22
+
23
+ should 'only allow OLS::Term objects to be addded to the graph' do
24
+ assert_raises (TypeError) { @graph.add_to_graph('foo') }
25
+ @graph.add_to_graph( OLS.find_by_id('EMAP:3018') )
26
+ end
27
+
28
+ should 'allow access to the nodes of the graph' do
29
+ assert_nil @graph['EMAP:3018']
30
+ @graph.add_to_graph( OLS.find_by_id('EMAP:3018') )
31
+ assert @graph['EMAP:3018'].is_a? Hash
32
+ assert @graph.find('EMAP:3018').is_a? OLS::Term
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,484 @@
1
+ require 'test_helper'
2
+
3
+ class OLSTermTest < Test::Unit::TestCase
4
+ context 'An OLS::Term object' do
5
+ setup do
6
+ VCR.insert_cassette('test_ols_term')
7
+ end
8
+
9
+ teardown do
10
+ VCR.eject_cassette
11
+ end
12
+
13
+ context 'once created' do
14
+ setup do
15
+ @emap_term = OLS.find_by_id('EMAP:3018')
16
+ @mp_term = OLS.find_by_id('MP:0002115')
17
+ end
18
+
19
+ should 'have an id/term and a name' do
20
+ assert_equal 'EMAP:3018', @emap_term.term_id
21
+ assert_equal 'TS18,nose', @emap_term.term_name
22
+ assert_equal 'MP:0002115', @mp_term.term_id
23
+ assert_equal 'abnormal skeleton extremities morphology', @mp_term.term_name
24
+ end
25
+
26
+ should 'be able to represent itself as a string' do
27
+ assert_equal 'EMAP:3018 - TS18,nose', @emap_term.to_s
28
+ end
29
+
30
+ should 'be able to say if it is an obsolete term' do
31
+ assert_equal false, @emap_term.is_obsolete?
32
+ assert_equal false, OLS.find_by_id('GO:0007242').is_obsolete?
33
+ assert OLS.find_by_id('GO:0008945').is_obsolete?
34
+ end
35
+
36
+ should 'be able to give its definition' do
37
+ assert_nil @emap_term.definition
38
+ assert_equal 'any structural anomaly of the limb, autopod or tail bones', @mp_term.definition
39
+
40
+ go_term = OLS.find_by_id('GO:0007242')
41
+ assert_equal 'intracellular signal transduction', go_term.term_name
42
+ assert_equal(
43
+ 'The process in which a signal is passed on to downstream components within '+\
44
+ 'the cell, which become activated themselves to further propagate the signal '+\
45
+ 'and finally trigger a change in the function or state of the cell.',
46
+ go_term.definition
47
+ )
48
+ end
49
+
50
+ should 'be able to give a terms synonyms' do
51
+ go_term = OLS.find_by_id('GO:0007242')
52
+
53
+ assert_equal 'intracellular signal transduction', go_term.term_name
54
+
55
+ assert go_term.synonyms.keys.include? :exact
56
+ assert go_term.synonyms[:exact].include? 'intracellular signaling chain'
57
+
58
+ assert go_term.synonyms.keys.include? :related
59
+ assert go_term.synonyms[:related].include? 'intracellular signaling pathway'
60
+
61
+ assert go_term.synonyms.keys.include? :narrow
62
+ assert go_term.synonyms[:narrow].include? 'signal transmission via intracellular cascade'
63
+
64
+ assert go_term.synonyms.keys.include? :alt_id
65
+ assert go_term.synonyms[:alt_id].include? 'GO:0023013'
66
+
67
+ assert_equal Hash, @emap_term.synonyms.class
68
+ assert @emap_term.synonyms.empty?
69
+ end
70
+
71
+ should 'be able to report its parents' do
72
+ assert_equal 1, @emap_term.parents.size
73
+ assert_equal 'EMAP:2987', @emap_term.parents.first.term_id
74
+
75
+ assert_equal 2, @mp_term.parents.size
76
+
77
+ mp_term_parent_term_ids = @mp_term.parent_ids
78
+ assert mp_term_parent_term_ids.include?('MP:0000545')
79
+ assert mp_term_parent_term_ids.include?('MP:0009250')
80
+
81
+ mp_term_parent_term_names = @mp_term.parent_names
82
+ assert mp_term_parent_term_names.include? OLS.find_by_id('MP:0000545').term_name
83
+ assert mp_term_parent_term_names.include? OLS.find_by_id('MP:0009250').term_name
84
+ end
85
+
86
+ should 'be able to generate a flat list of ALL parents (up the ontology)' do
87
+ assert @emap_term.all_parents.is_a? Array
88
+ assert @emap_term.all_parents.first.is_a? OLS::Term
89
+ assert_equal 4, @emap_term.all_parents.size
90
+ assert_equal 'EMAP:0', @emap_term.all_parents.first.term_id
91
+
92
+ assert @mp_term.all_parents.is_a? Array
93
+ assert @mp_term.all_parents.first.is_a? OLS::Term
94
+ assert_equal 7, @mp_term.all_parents.size
95
+ assert_equal 'MP:0000001', @mp_term.all_parents.first.term_id
96
+ assert_equal 'MP:0000001', @mp_term.all_parents[2].term_id
97
+ assert @mp_term.all_parents.last.term_id =~ /MP:0000545|MP:0009250/
98
+ end
99
+
100
+ should 'be able to generate a flat list of ALL parent terms/names' do
101
+ assert @emap_term.all_parent_ids.is_a? Array
102
+ assert_equal 4, @emap_term.all_parent_ids.size
103
+ assert_equal 'EMAP:0', @emap_term.all_parent_ids.first
104
+
105
+ assert @emap_term.all_parent_names.is_a? Array
106
+ assert_equal 4, @emap_term.all_parent_names.size
107
+ assert_equal 'Mouse_anatomy_by_time_xproduct', @emap_term.all_parent_names.first
108
+
109
+ assert @mp_term.all_parent_ids.is_a? Array
110
+ assert_equal 6, @mp_term.all_parent_ids.size
111
+ assert_equal 'MP:0000001', @mp_term.all_parent_ids.first
112
+
113
+ assert @mp_term.all_parent_names.is_a? Array
114
+ assert_equal 6, @mp_term.all_parent_names.size
115
+ assert_equal 'mammalian phenotype', @mp_term.all_parent_names.first
116
+ end
117
+
118
+ should 'be able to report its children' do
119
+ assert @emap_term.has_children?
120
+ assert_equal 3, @emap_term.children.size
121
+ assert @emap_term['EMAP:3022'].is_a? OLS::Term
122
+ assert @emap_term.children_ids.include? 'EMAP:3022'
123
+ assert @emap_term.children_names.include? OLS.find_by_id('EMAP:3022').term_name
124
+ end
125
+
126
+ should 'be able to generate a flat list of ALL children (down the ontology)' do
127
+ assert @emap_term.all_children.is_a? Array
128
+ assert @emap_term.all_children.first.is_a? OLS::Term
129
+ assert_equal 14, @emap_term.all_children.size
130
+ emap3032_included = false
131
+ @emap_term.all_children.each do |child|
132
+ emap3032_included = true if child.term_id.eql?('EMAP:3032')
133
+ end
134
+ end
135
+
136
+ should 'be able to generate a flat list of ALL child terms/names' do
137
+ assert @emap_term.all_child_ids.is_a? Array
138
+ assert_equal 14, @emap_term.all_child_ids.size
139
+ assert @emap_term.all_child_ids.include?('EMAP:3032')
140
+
141
+ assert @emap_term.all_child_names.is_a? Array
142
+ assert_equal 14, @emap_term.all_child_names.size
143
+ assert @emap_term.all_child_names.include?('TS18,mesenchyme,medial-nasal process')
144
+ end
145
+
146
+ should 'allow easy access to child terms using the [] helper' do
147
+ emap = OLS.find_by_id('EMAP:0')
148
+ assert emap['EMAP:2636'].is_a? OLS::Term
149
+ assert emap['EMAP:2636']['EMAP:2822'].is_a? OLS::Term
150
+ assert_equal 'EMAP:2636', emap['EMAP:2636'].term_id
151
+ assert_equal 'TS18,embryo', emap['EMAP:2636'].term_name
152
+ end
153
+
154
+ should "be able to say if it's a root/leaf node" do
155
+ assert_equal false, @emap_term.is_root?
156
+ assert_equal false, @emap_term.is_leaf?
157
+
158
+ emap3032 = OLS.find_by_id('EMAP:3032')
159
+ assert_equal false, emap3032.is_root?
160
+ assert emap3032.is_leaf?
161
+
162
+ emap0 = OLS.find_by_id('EMAP:0')
163
+ assert emap0.is_root?
164
+ assert_equal false, emap0.is_leaf?
165
+ end
166
+
167
+ should 'be able to give its depth level' do
168
+ assert_equal 0, OLS.find_by_id('EMAP:0').level
169
+ assert_equal 4, @emap_term.level
170
+ assert_equal 4, @mp_term.level
171
+ end
172
+
173
+ should 'be able to "focus" a empty ontology graph around a given term' do
174
+ # First, test the following EMAP graph...
175
+ #
176
+ # * EMAP:0
177
+ # |---+ EMAP:2636
178
+ # |---+ EMAP:2822
179
+ # |---+ EMAP:2987
180
+ # |---+ EMAP:3018
181
+ # |---+ EMAP:3022
182
+ # |---+ EMAP:3023
183
+ # |---+ EMAP:3024
184
+ # |---> EMAP:3025
185
+ # |---> EMAP:3026
186
+ # |---+ EMAP:3027
187
+ # |---> EMAP:3029
188
+ # |---> EMAP:3028
189
+ # |---+ EMAP:3030
190
+ # |---> EMAP:3031
191
+ # |---> EMAP:3032
192
+ # |---> EMAP:3019
193
+ # |---+ EMAP:3020
194
+ # |---> EMAP:3021
195
+
196
+ @emap_term.focus_graph!
197
+
198
+ assert_equal 'EMAP:0', @emap_term.root.term_id
199
+ assert_equal 1, @emap_term.root.children.size
200
+ assert_equal 3, @emap_term.children.size
201
+ assert_equal 4, @emap_term.level
202
+
203
+ assert @emap_term.instance_variable_get :@already_fetched_parents
204
+ assert @emap_term.instance_variable_get :@already_fetched_children
205
+
206
+ assert @emap_term.root.instance_variable_get :@already_fetched_parents
207
+ assert @emap_term.root.instance_variable_get :@already_fetched_children
208
+
209
+ # Now test the following MP graph...
210
+ #
211
+ # * MP:0000001
212
+ # |---+ MP:0005371
213
+ # |---+ MP:0000545
214
+ # |---+ MP:0002115
215
+ # ...
216
+ # |---+ MP:0005390
217
+ # |---+ MP:0005508
218
+ # |---+ MP:0009250
219
+ # |---+ MP:0002115
220
+ # ...
221
+ #
222
+
223
+ @mp_term.focus_graph!
224
+
225
+ assert_equal 'MP:0000001', @mp_term.root.term_id
226
+ assert_equal 2, @mp_term.root.children.size
227
+ assert @mp_term.root.children.map(&:term_id).include? 'MP:0005371'
228
+ assert @mp_term.root.children.map(&:term_id).include? 'MP:0005390'
229
+ end
230
+
231
+ should 'be able to "focus" a large pre-populated graph around a single term' do
232
+ # bulk out the target graph
233
+ @emap_term.focus_graph!
234
+ assert_equal 19, @emap_term.size
235
+
236
+ # make it a touch larger
237
+ @emap_term.merge!( OLS.find_by_id('EMAP:3003') )
238
+ assert_equal 34, @emap_term.size
239
+
240
+ # cut it back to the origninal focused graph
241
+ @emap_term.focus_graph!
242
+ raw_graph = @emap_term.instance_variable_get(:@graph).raw_graph
243
+
244
+ assert_equal 19, @emap_term.size
245
+ assert_equal 19, raw_graph.keys.size
246
+ assert_equal false, raw_graph.keys.include?('EMAP:3003')
247
+ end
248
+
249
+ should 'be able to "focus" a large pre-populated graph around a single term without clobbering the existing graph' do
250
+ # bulk out the target graph
251
+ @emap_term.focus_graph!
252
+ assert_equal 19, @emap_term.size
253
+
254
+ # make it a touch larger
255
+ @emap_term.merge!( OLS.find_by_id('EMAP:3003') )
256
+ assert_equal 34, @emap_term.size
257
+
258
+ # cut it back to the origninal focused graph
259
+ new_graph = @emap_term.focus_graph
260
+
261
+ orig_raw_graph = @emap_term.instance_variable_get(:@graph).raw_graph
262
+ new_raw_graph = new_graph.instance_variable_get(:@graph).raw_graph
263
+
264
+ assert_equal 34, @emap_term.size
265
+ assert_equal 19, new_graph.size
266
+
267
+ assert_equal 34, orig_raw_graph.keys.size
268
+ assert_equal 19, new_raw_graph.keys.size
269
+
270
+ assert orig_raw_graph.keys.include?('EMAP:3003')
271
+ assert_equal false, new_raw_graph.keys.include?('EMAP:3003')
272
+ end
273
+
274
+ should 'be able to merge in another ontology graph that shares a common root term' do
275
+ # We're going to try and merge this subgraph (for EMAP:3018)
276
+ #
277
+ # * EMAP:0
278
+ # |---+ EMAP:2636
279
+ # |---+ EMAP:2822
280
+ # |---+ EMAP:2987
281
+ # |---+ EMAP:3018
282
+ # |---+ EMAP:3022
283
+ # |---+ EMAP:3023
284
+ # |---+ EMAP:3024
285
+ # |---> EMAP:3025
286
+ # |---> EMAP:3026
287
+ # |---+ EMAP:3027
288
+ # |---> EMAP:3029
289
+ # |---> EMAP:3028
290
+ # |---+ EMAP:3030
291
+ # |---> EMAP:3031
292
+ # |---> EMAP:3032
293
+ # |---> EMAP:3019
294
+ # |---+ EMAP:3020
295
+ # |---> EMAP:3021
296
+ #
297
+ # With this one (for EMAP:3003)
298
+ #
299
+ # * EMAP:0
300
+ # |---+ EMAP:2636
301
+ # |---+ EMAP:2822
302
+ # |---+ EMAP:2987
303
+ # |---+ EMAP:3003
304
+ # |---> EMAP:3012
305
+ # |---+ EMAP:3013
306
+ # |---> EMAP:3014
307
+ # |---> EMAP:3016
308
+ # |---> EMAP:3015
309
+ # |---> EMAP:3017
310
+ # |---+ EMAP:3004
311
+ # |---> EMAP:3005
312
+ # |---> EMAP:3006
313
+ # |---+ EMAP:3007
314
+ # |---> EMAP:3008
315
+ # |---> EMAP:3009
316
+ # |---+ EMAP:3010
317
+ # |---> EMAP:3011
318
+ #
319
+ # To give us...
320
+ #
321
+ # * EMAP:0
322
+ # |---+ EMAP:2636
323
+ # |---+ EMAP:2822
324
+ # |---+ EMAP:2987
325
+ # |---+ EMAP:3018
326
+ # |---+ EMAP:3022
327
+ # |---+ EMAP:3023
328
+ # |---+ EMAP:3024
329
+ # |---> EMAP:3025
330
+ # |---> EMAP:3026
331
+ # |---+ EMAP:3027
332
+ # |---> EMAP:3029
333
+ # |---> EMAP:3028
334
+ # |---+ EMAP:3030
335
+ # |---> EMAP:3031
336
+ # |---> EMAP:3032
337
+ # |---> EMAP:3019
338
+ # |---+ EMAP:3020
339
+ # |---> EMAP:3021
340
+ # |---+ EMAP:3003
341
+ # |---> EMAP:3012
342
+ # |---+ EMAP:3013
343
+ # |---> EMAP:3014
344
+ # |---> EMAP:3016
345
+ # |---> EMAP:3015
346
+ # |---> EMAP:3017
347
+ # |---+ EMAP:3004
348
+ # |---> EMAP:3005
349
+ # |---> EMAP:3006
350
+ # |---+ EMAP:3007
351
+ # |---> EMAP:3008
352
+ # |---> EMAP:3009
353
+ # |---+ EMAP:3010
354
+ # |---> EMAP:3011
355
+ #
356
+
357
+ @emap_term.focus_graph!
358
+ assert_equal 19, @emap_term.size
359
+
360
+ @emap_term.merge!( OLS.find_by_id('EMAP:3003') )
361
+ assert_equal 34, @emap_term.size
362
+
363
+ main_merge_node = @emap_term.root['EMAP:2636']['EMAP:2822']['EMAP:2987']
364
+
365
+ assert main_merge_node.is_a?(OLS::Term)
366
+ assert_equal 2, main_merge_node.children.size
367
+ assert main_merge_node.children.map(&:term_id).include? 'EMAP:3003'
368
+ assert main_merge_node.children.map(&:term_id).include? 'EMAP:3018'
369
+
370
+ # Also check that the internal graph has been merged accordingly
371
+ raw_graph = @emap_term.instance_variable_get(:@graph).raw_graph
372
+ emap3003_graph = raw_graph['EMAP:3003'][:object].instance_variable_get(:@graph).raw_graph
373
+ assert_equal 34, raw_graph.size
374
+ assert_equal raw_graph.object_id, emap3003_graph.object_id
375
+
376
+ another_ont = OLS.find_by_id('GO:0023034')
377
+ yet_another_ont = OLS.find_by_id('EMAP:3003')
378
+
379
+ assert_raise(ArgumentError) { another_ont.merge!(yet_another_ont) }
380
+ assert_raise(TypeError) { another_ont.merge!('EMAP:3003') }
381
+ end
382
+
383
+ should 'allow deep copying of objects' do
384
+ @emap_term.focus_graph!
385
+ copy = @emap_term.dup
386
+
387
+ assert @emap_term.object_id != copy.object_id
388
+ assert @emap_term.instance_variable_get(:@graph).object_id != copy.instance_variable_get(:@graph).object_id
389
+ assert @emap_term.instance_variable_get(:@graph).raw_graph.object_id != copy.instance_variable_get(:@graph).raw_graph.object_id
390
+ assert_equal @emap_term.size, copy.size
391
+ assert_equal @emap_term.root.term_id, copy.root.term_id
392
+ end
393
+
394
+ should 'allow serialization using Marshal' do
395
+ @emap_term.focus_graph!
396
+
397
+ OLS.stubs(:request).returns(nil)
398
+
399
+ # check the stubbing is okay...
400
+ foo = OLS.find_by_id('EMAP:3003')
401
+ foo.focus_graph!
402
+ assert_equal 1, foo.size
403
+
404
+ # now get on with testing marshal...
405
+ data = Marshal.dump(@emap_term)
406
+ copy = Marshal.load(data)
407
+
408
+ assert_equal @emap_term.term_id, copy.term_id
409
+ assert_equal @emap_term.term_name, copy.term_name
410
+ assert_equal @emap_term.size, copy.size
411
+ assert_equal @emap_term.root.term_id, copy.root.term_id
412
+ assert_equal @emap_term.all_parent_ids, copy.all_parent_ids
413
+ assert_equal @emap_term.all_parent_names, copy.all_parent_names
414
+
415
+ OLS.unstub(:request)
416
+ end
417
+
418
+ should 'allow serialization using YAML' do
419
+ @emap_term.focus_graph!
420
+
421
+ OLS.stubs(:request).returns(nil)
422
+
423
+ require 'yaml'
424
+
425
+ # check the stubbing is okay...
426
+ foo = OLS.find_by_id('EMAP:3003')
427
+ foo.focus_graph!
428
+ assert_equal 1, foo.size
429
+
430
+ # now get on with testing yaml...
431
+ data = @emap_term.to_yaml
432
+ copy = YAML.load(data)
433
+
434
+ assert_equal @emap_term.term_id, copy.term_id
435
+ assert_equal @emap_term.term_name, copy.term_name
436
+ assert_equal @emap_term.size, copy.size
437
+ assert_equal @emap_term.root.term_id, copy.root.term_id
438
+ assert_equal @emap_term.all_parent_ids, copy.all_parent_ids
439
+ assert_equal @emap_term.all_parent_names, copy.all_parent_names
440
+
441
+ OLS.unstub(:request)
442
+ end
443
+
444
+ should 'allow users to write image files showing the graph structure' do
445
+ @mp_term.focus_graph!
446
+ assert_silent do
447
+ @mp_term.write_children_to_graphic_file('children')
448
+ @mp_term.write_parentage_to_graphic_file('parentage')
449
+ end
450
+ system("rm children.dot children.png parentage.dot parentage.png")
451
+ end
452
+
453
+ should 'allow users to print a graph representation of the graph to STDOUT' do
454
+ @emap_term.focus_graph!
455
+ emap_graph = <<-EMAP
456
+ * EMAP:0
457
+ |---+ EMAP:2636
458
+ |---+ EMAP:2822
459
+ |---+ EMAP:2987
460
+ |---+ EMAP:3018
461
+ |---+ EMAP:3022
462
+ |---+ EMAP:3023
463
+ |---+ EMAP:3024
464
+ |---> EMAP:3025
465
+ |---> EMAP:3026
466
+ |---+ EMAP:3027
467
+ |---> EMAP:3029
468
+ |---> EMAP:3028
469
+ |---+ EMAP:3030
470
+ |---> EMAP:3031
471
+ |---> EMAP:3032
472
+ |---> EMAP:3019
473
+ |---+ EMAP:3020
474
+ |---> EMAP:3021
475
+ EMAP
476
+
477
+ assert_output(emap_graph.lstrip,nil) do
478
+ @emap_term.root.print_graph
479
+ end
480
+ end
481
+ end
482
+ end
483
+ end
484
+