ols 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+