intermine 0.99.03 → 1.00.00

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.
data/Rakefile CHANGED
@@ -1,14 +1,14 @@
1
1
  require 'rubygems'
2
2
  require 'rubygems/specification' unless defined?(Gem::Specification)
3
+ require 'rubygems/package_task'
3
4
  require 'rake/testtask'
4
- require 'rake/gempackagetask'
5
5
 
6
- gem 'rdoc', '=2.1.0'
7
- require 'rdoc/rdoc'
8
- require 'rake/rdoctask'
9
-
10
- gem 'darkfish-rdoc'
11
- require 'darkfish-rdoc'
6
+ #gem 'rdoc'# , '=2.1.0'
7
+ #require 'rdoc/rdoc'
8
+ #require 'rake/rdoctask'
9
+ #
10
+ #gem 'darkfish-rdoc'
11
+ #require 'darkfish-rdoc'
12
12
 
13
13
  def gemspec
14
14
  @gemspec ||= begin
@@ -38,30 +38,44 @@ task :release => :package do
38
38
  sh "gem push pkg/#{gemspec.name}-#{gemspec.version}.gem"
39
39
  end
40
40
 
41
- Rake::GemPackageTask.new(gemspec) do |pkg|
41
+ Gem::PackageTask.new(gemspec) do |pkg|
42
42
  pkg.need_zip = true
43
43
  pkg.need_tar = true
44
-
45
44
  end
46
45
 
47
- Rake::TestTask.new do |t|
48
- t.libs << "test"
49
- t.test_files = FileList['test/unit_tests.rb']
50
- t.verbose = true
51
- end
52
46
 
53
- Rake::TestTask.new(:live_tests) do |t|
54
- t.libs << "test"
55
- t.test_files = FileList['test/live_test.rb'] << FileList['test/live_summary_test.rb'] << FileList['test/live_results.rb']
56
- t.verbose = true
57
- end
58
47
 
59
- Rake::RDocTask.new do |t|
60
- t.title = 'InterMine Webservice Client Documentation'
61
- t.rdoc_files.include 'README.rdoc'
62
- t.rdoc_files.include 'lib/**/*rb'
63
- t.main = 'README.rdoc'
64
- t.options += ['-SHN', '-f', 'darkfish']
48
+ namespace :test do
49
+
50
+ desc "Run the unit-tests"
51
+ Rake::TestTask.new(:unit) do |t|
52
+ t.libs << "test"
53
+ t.test_files = FileList['test/unit_tests.rb']
54
+ t.verbose = true
55
+ puts "Running UNIT TESTS"
56
+ end
57
+
58
+ desc "Run the live integration tests"
59
+ Rake::TestTask.new(:live) do |t|
60
+ t.libs << "test"
61
+ t.test_files = FileList['test/live_test.rb'] << FileList['test/live_summary_test.rb'] << FileList['test/live_results.rb']
62
+ t.verbose = false
63
+ puts "Running LIVE INTEGRATION TESTS"
64
+ end
65
+
66
+ desc "Run all tests"
67
+ task :all => [:unit, :live]
65
68
  end
66
69
 
70
+ desc "Run the default test-suite"
71
+ task :test => ["test:all"]
72
+
73
+ #Rake::RDocTask.new do |t|
74
+ # t.title = 'InterMine Webservice Client Documentation'
75
+ # t.rdoc_files.include 'README.rdoc'
76
+ # t.rdoc_files.include 'lib/**/*rb'
77
+ # t.main = 'README.rdoc'
78
+ # t.options += ['-SHN', '-f', 'darkfish']
79
+ #end
80
+
67
81
 
@@ -312,6 +312,54 @@ module InterMine::Lists
312
312
  @tags = @manager.tags_for(self)
313
313
  end
314
314
 
315
+ ENRICHMENT_DEFAULTS = {:correction => "Holm-Bonferroni", :maxp => 0.05}
316
+
317
+ # Retrieve the results of an enrichment calculation
318
+ #
319
+ # Get the results of an enrichment calculate_enrichment with the default parameter values:
320
+ #
321
+ # calculate_enrichment(widget)
322
+ #
323
+ # Pass optional parameters to the enrichment service:
324
+ #
325
+ # calculate_enrichment(widget, :correction => "Benjamini-Hochberg", :maxp => 0.1)
326
+ #
327
+ # The optional parameters are: :correction, :maxp, :filter
328
+ #
329
+ # Each result returned by the enrichment service is a hash with the following
330
+ # keys: "p-value", "identifier", "matches", "description". The Hash returned also allows
331
+ # key access with symbols.
332
+ #
333
+ def calculate_enrichment(widget, opts = {})
334
+ s = @manager.service
335
+ params = s.params.merge(ENRICHMENT_DEFAULTS).merge(opts).merge(:widget => widget, :list => @name)
336
+ uri = URI.parse(s.root + Service::LIST_ENRICHMENT_PATH)
337
+ res = Net::HTTP.post_form(uri, params)
338
+ return case res
339
+ when Net::HTTPSuccess
340
+ JSON.parse(res.body)["results"].map {|row| SymbolAcceptingHash[row] }
341
+ else
342
+ begin
343
+ container = JSON.parse(res.body)
344
+ raise ServiceError, container["error"]
345
+ rescue
346
+ res.error!
347
+ end
348
+ end
349
+ end
350
+
351
+ class SymbolAcceptingHash < Hash
352
+
353
+ def [](key)
354
+ return case key
355
+ when Symbol
356
+ return super(key.to_s.gsub(/[_]/, '-'))
357
+ else
358
+ return super(key)
359
+ end
360
+ end
361
+ end
362
+
315
363
  private
316
364
 
317
365
  # Used to interpret arguments to add and remove
@@ -675,10 +723,13 @@ module InterMine::Lists
675
723
  def make_list_names(objs)
676
724
  current_names = list_names
677
725
  return objs.map do |x|
678
- case
679
- when x.is_a?(List) then x.name
680
- when x.respond_to?(:list_upload_uri) then create_list(x).name
681
- when current_names.include?(x.to_s) then x.to_s
726
+ case x
727
+ when List
728
+ x.name
729
+ when x.respond_to?(:list_upload_uri)
730
+ create_list(x).name
731
+ when current_names.include?(x.to_s)
732
+ x.to_s
682
733
  else
683
734
  raise ArgumentError, "#{x} is not a list you can access"
684
735
  end
@@ -708,17 +759,15 @@ module InterMine::Lists
708
759
  else
709
760
  begin
710
761
  container = JSON.parse(response.body)
711
- err = container["error"]
762
+ raise ServiceError, container["error"]
712
763
  rescue
713
764
  response.error!
714
765
  end
715
- raise ServiceError, container["error"]
716
766
  end
717
767
  end
718
768
 
719
769
  # Routine for creating a list from a PathQuery::Query
720
770
  def create_list_from_query(query, tags=[], name=nil, description=nil)
721
- query = get_listable_query(query)
722
771
  uri = query.list_upload_uri
723
772
  list_params = {
724
773
  "listName" => name,
@@ -730,19 +779,6 @@ module InterMine::Lists
730
779
  return Net::HTTP.post_form(URI.parse(uri), params)
731
780
  end
732
781
 
733
- def get_listable_query(query)
734
- clone = query.clone()
735
- views = clone.views
736
- selected_classes = views.map {|x| x.prefix}.uniq {|p| p.to_s}
737
- if selected_classes.size == 1
738
- return clone.select(selected_classes.first.append("id"))
739
- elsif selected_classes.size == 0
740
- return clone.select("#{clone.root.name}.id")
741
- end
742
- # Bound to fail, but let the service provide the message.
743
- return clone
744
- end
745
-
746
782
  # Routine for creating a List in a webservice from a list of Ids.
747
783
  def create_list_from_ids(ids, type, tags=[], name=nil, description=nil)
748
784
  if @service.model.get_cd(type).nil?
@@ -402,46 +402,6 @@ module Metadata
402
402
  return q
403
403
  end
404
404
 
405
- # call-seq:
406
- # find(*attributes) => Enumerable[InterMineObject]
407
- #
408
- # Get the items in the database matching the identifiers.
409
- #
410
- # zen = model.table("Gene").find("zen")
411
- # puts zen.length, zen.organism.name
412
- #
413
- # find may retrun multiple results:
414
- #
415
- # genes = model.table("Gene").find("zen", "eve", "r", "h")
416
- #
417
- # The search mechanism used is a "lookup" constraint, so extra-values
418
- # may be provided to distinguish search terms by passing key-value pairs:
419
- #
420
- # starting_with_c = model.table("Gene").find("c*" => "D. melanogaster")
421
- #
422
- def find(*attrs)
423
- q = new_query
424
- q.select("*")
425
- attrs.each do |attr|
426
- if attr.is_a? Hash
427
- attr.each do |term, extra|
428
- q.or(@root, "LOOKUP", term, extra)
429
- end
430
- else
431
- q.or(@root, "LOOKUP", attr)
432
- end
433
- end
434
-
435
- c = q.count()
436
- if c < 1
437
- raise ItemNotFoundError
438
- elsif c == 1
439
- return q.results.first
440
- else
441
- return q.results
442
- end
443
- end
444
-
445
405
  # call-seq:
446
406
  # where(*constraints) => PathQuery::Query
447
407
  #
@@ -487,8 +447,13 @@ module Metadata
487
447
  # attributes (ie. columns that can hold values, rather than references to
488
448
  # other tables.)
489
449
  #
450
+ # The array returned will be sorted in alphabetical order by field-name.
451
+ #
490
452
  def attributes
491
- return @fields.select {|k, v| v.is_a?(AttributeDescriptor)}.map {|pair| pair[1]}
453
+ return @fields.
454
+ select {|_, v| v.is_a?(AttributeDescriptor)}.
455
+ sort {|(k0, _), (k1, _)| k0 <=> k1}.
456
+ map {|(_, v)| v}
492
457
  end
493
458
 
494
459
  # Returns a human readable string
@@ -580,11 +545,8 @@ module Metadata
580
545
  klass.class_eval do
581
546
  define_method(fd.name) do
582
547
  if instance_variable_get("@" + fd.name).nil?
583
- q = __cd__.select("id", fd.name + ".*").where(:id => objectId).outerjoin(fd.name)
584
- instance_var = q.results.first.instance_variable_get('@' + fd.name)
585
- if fd.is_a?(CollectionDescriptor) and instance_var.nil?
586
- instance_var = []
587
- end
548
+ q = __cd__.select(fd.name + ".*").where(:id => objectId)
549
+ instance_var = q.results.first[fd.name]
588
550
  instance_variable_set("@" + fd.name, instance_var)
589
551
  end
590
552
  return instance_variable_get("@" + fd.name)
@@ -614,16 +576,14 @@ module Metadata
614
576
  type = fd.referencedType
615
577
  if fd.is_a?(CollectionDescriptor)
616
578
  instance_var = []
617
- if not val.nil?
618
- val.each do |item|
619
- if item.is_a?(Hash)
620
- item = type.model.make_new(type.name, item)
621
- end
622
- if !item.is_a?(type)
623
- raise ArgumentError, "Arguments to #{fd.name} in #{@name} must be #{type.name}s"
624
- end
625
- instance_var << item
579
+ val.each do |item|
580
+ if item.is_a?(Hash)
581
+ item = type.model.make_new(type.name, item)
626
582
  end
583
+ if !item.is_a?(type)
584
+ raise ArgumentError, "Arguments to #{fd.name} in #{@name} must be #{type.name}s"
585
+ end
586
+ instance_var << item
627
587
  end
628
588
  instance_variable_set("@" + fd.name, instance_var)
629
589
  else
@@ -794,55 +754,11 @@ module Metadata
794
754
  end
795
755
  end
796
756
 
797
- # call-seq:
798
- # end => ClassDescriptor | ReferenceDescriptor | AttributeDescriptor
799
- #
800
- # Return the last element of this path
801
- #
802
- def end
803
- return @elements.last
804
- end
805
-
806
- # call-seq:
807
- # prefix => Path
808
- #
809
- # Return the Path one above this.
810
- def prefix
811
- if @elements.size == 1
812
- raise PathException, "Root paths do not have a prefix"
813
- end
814
- new_str = @elements[0, @elements.size - 1].map {|x| x.name}.join(".")
815
- return Path.new(new_str, @model, @subclasses)
816
- end
817
-
818
- # call-seq:
819
- # append(part, ...) => Path
820
- #
821
- # Return a new path by adding elements to this path.
822
- #
823
- def append(*parts)
824
- new_str = self.to_s + "." + parts.join(".")
825
- return Path.new(new_str, @model, @subclasses)
826
- end
827
-
828
757
  # Two paths can be said to be equal when they stringify to the same representation.
829
758
  def ==(other)
830
759
  return self.to_s == other.to_s
831
760
  end
832
761
 
833
- # Two paths are identical when they have the same everything.
834
- def eql?(other)
835
- begin
836
- return (self == other) && @model.eql?(other.model) && @subclasses.eql?(other.subclasses)
837
- rescue
838
- return false
839
- end
840
- end
841
-
842
- def hash
843
- return 17 * @model.hash * 11 * @subclasses.hash * 3 * to_s.hash
844
- end
845
-
846
762
  # Get the number of elements in the path
847
763
  def length
848
764
  return @elements.length
@@ -969,9 +885,6 @@ module Metadata
969
885
  end
970
886
  end
971
887
  end
972
-
973
- class ItemNotFoundError < RuntimeError
974
- end
975
888
  end
976
889
  end
977
890
 
@@ -616,10 +616,7 @@ module InterMine::PathQuery
616
616
  if y.end_with?("*")
617
617
  prefix = y.chomp(".*")
618
618
  path = make_path(prefix)
619
- attrs = path.end_cd.attributes.map {|x|
620
- prefix + "." + x.name
621
- }
622
- add_views(attrs)
619
+ add_views(path.end_cd.attributes.map {|x| prefix + "." + x.name})
623
620
  else
624
621
  path = make_path(y)
625
622
  path = make_path(y.to_s + ".id") unless path.is_attribute?
@@ -723,11 +720,8 @@ module InterMine::PathQuery
723
720
  #
724
721
  def add_sort_order(path, direction="ASC")
725
722
  p = self.path(path)
726
- selected = @views.map {|v| v.prefix}
727
- selected.push(@constraints.map {|c| c.path.is_attribute? ? c.path.prefix : c.path })
728
- selected.uniq!
729
- if !selected.include? p.prefix
730
- raise ArgumentError, "Sort order (#{p}) not on a selected class (#{selected.map {|v| v.to_s}.inspect} in #{self.name || 'unnamed query'})"
723
+ if !@views.include? p
724
+ raise ArgumentError, "Sort order (#{p}) not in view (#{@views.map {|v| v.to_s}.inspect} in #{self.name || 'unnamed query'})"
731
725
  end
732
726
  @sort_order << SortOrder.new(p, direction)
733
727
  return self
@@ -765,32 +759,6 @@ module InterMine::PathQuery
765
759
  @constraints << con
766
760
  return con
767
761
  end
768
-
769
- def or(*parameters)
770
- logic = @logic
771
- new_con = add_constraint(*parameters)
772
-
773
- if logic
774
- set_logic(LogicGroup.new(logic, "OR", new_con))
775
- elsif @constraints.size > 1
776
- set_logic(@constraints.map {|c| c.code }.join(" or "))
777
- end
778
-
779
- return self
780
- end
781
-
782
- def and(*parameters)
783
- logic = @logic
784
- new_con = add_constraint(*parameters)
785
-
786
- if logic
787
- set_logic(LogicGroup.new(logic, "AND", new_con))
788
- elsif @constraints.size > 1
789
- set_logic(@constraints.map {|c| c.code }.join(" and "))
790
- end
791
-
792
- return self
793
- end
794
762
 
795
763
  # Returns a Path object constructed from the given path-string,
796
764
  # taking the current state of the query into account (its data-model
@@ -855,7 +823,7 @@ module InterMine::PathQuery
855
823
  end
856
824
  parameters[:values] = subv.to_a
857
825
  elsif subv.is_a?(Lists::List)
858
- if subk == "=" or subk == "<" or subk == "<="
826
+ if subk == "="
859
827
  parameters[:op] = "IN"
860
828
  elsif subk == "!="
861
829
  parameters[:op] = "NOT IN"
@@ -863,19 +831,6 @@ module InterMine::PathQuery
863
831
  parameters[:op] = normalised_k
864
832
  end
865
833
  parameters[:value] = subv.name
866
- elsif subv.is_a? Query
867
- if subk == "=" or subk == "<" or subk == "<="
868
- parameters[:op] = "IN"
869
- elsif subk == "!="
870
- parameters[:op] = "NOT IN"
871
- else
872
- parameters[:op] = normalised_k
873
- end
874
- s = subv.service
875
- l = s.create_list(subv)
876
-
877
- parameters[:value] = l.name
878
-
879
834
  else
880
835
  parameters[:op] = normalised_k
881
836
  parameters[:value] = subv
@@ -988,7 +943,7 @@ module InterMine::PathQuery
988
943
  @classes = [
989
944
  SingleValueConstraint,
990
945
  SubClassConstraint,
991
- LookupConstraint, MultiValueConstraint,
946
+ LookupConstraint, MultiValueConstraint, RangeConstraint,
992
947
  UnaryConstraint, LoopConstraint, ListConstraint]
993
948
 
994
949
  @query = query
@@ -1014,14 +969,9 @@ module InterMine::PathQuery
1014
969
 
1015
970
  attr_keys = parameters.keys
1016
971
  suitable_classes = @classes.select { |cls|
1017
- is_suitable = true
1018
- attr_keys.each { |key|
1019
- is_suitable = is_suitable && (cls.method_defined?(key))
1020
- if key.to_s == "op"
1021
- is_suitable = is_suitable && cls.valid_ops.include?(parameters[key])
1022
- end
1023
- }
1024
- is_suitable
972
+ attr_keys.reduce(true) do |suitable, k|
973
+ suitable && cls.method_defined?(k) && (k.to_s != "op" or cls.valid_ops.include?(parameters[k]))
974
+ end
1025
975
  }
1026
976
  if suitable_classes.size > 1
1027
977
  raise ArgumentError, "More than one class found for #{parameters.inspect}"
@@ -1402,10 +1352,31 @@ module InterMine::PathQuery
1402
1352
  end
1403
1353
  end
1404
1354
 
1355
+ class RangeConstraint < MultiValueConstraint
1356
+
1357
+ VALID_OPS = [
1358
+ "WITHIN", "OUTSIDE",
1359
+ "CONTAINS", "DOES NOT CONTAIN",
1360
+ "OVERLAPS", "DOES NOT OVERLAP"
1361
+ ]
1362
+
1363
+ def self.valid_ops
1364
+ return VALID_OPS
1365
+ end
1366
+
1367
+ def validate
1368
+ # no-op
1369
+ end
1370
+ end
1371
+
1405
1372
  class TemplateMultiValueConstraint < MultiValueConstraint
1406
1373
  include TemplateConstraint
1407
1374
  end
1408
1375
 
1376
+ class TemplateRangeConstraint < RangeConstraint
1377
+ include TemplateConstraint
1378
+ end
1379
+
1409
1380
  class SortOrder
1410
1381
  include PathFeature
1411
1382
  attr_accessor :direction
@@ -85,12 +85,12 @@ module InterMine::Results
85
85
  def [](arg, length=nil)
86
86
  unless length.nil?
87
87
  raise ArgumentError, "when providing a length, the first argument must be an Integer" unless arg.is_a? Integer
88
- return @results[arg, length].map {|x| value_of(x)}
88
+ return @results[arg, length].map {|x| x["value"]}
89
89
  end
90
90
 
91
91
  case arg
92
92
  when Range
93
- return @results[arg].map {|x| value_of(x)}
93
+ return @results[arg].map {|x| x["value"]}
94
94
  when Integer
95
95
  idx = arg
96
96
  else
@@ -101,19 +101,19 @@ module InterMine::Results
101
101
 
102
102
  cell = @results[idx]
103
103
 
104
- raise IndexError, "Argument out of range" if @columns[idx].nil?
104
+ raise IndexError, "Argument out of range" if cell.nil?
105
105
 
106
- return value_of(cell)
106
+ return cell["value"]
107
107
  end
108
108
 
109
109
  # Returns the first value in this row
110
110
  def first
111
- return value_of(@results[0])
111
+ return @results[0]["value"]
112
112
  end
113
113
 
114
114
  # Returns the last value in this row
115
115
  def last
116
- return value_of(@results.last)
116
+ return @results.last["value"]
117
117
  end
118
118
 
119
119
  # Iterate over the values in this row in the
@@ -134,11 +134,9 @@ module InterMine::Results
134
134
  def each(&block)
135
135
  if block
136
136
  if block.arity == 1
137
- @results.each {|x| block.call(value_of(x))}
137
+ @results.each {|x| block.call(x["value"])}
138
138
  else block.arity == 2
139
- (0 ... @results.size).to_a.each {|i|
140
- block.call(@columns[i], value_of(@results[i]))
141
- }
139
+ (0 ... @results.size).to_a.each {|i| block.call(@columns[i], @results[i]["value"])}
142
140
  end
143
141
  end
144
142
  return self
@@ -156,7 +154,7 @@ module InterMine::Results
156
154
 
157
155
  # Return an Array version of the row.
158
156
  def to_a
159
- return @results.map {|x| value_of(x)}
157
+ return @results.map {|x| x["value"]}
160
158
  end
161
159
 
162
160
  # Return a Hash version of the row. All keys in this
@@ -187,15 +185,11 @@ module InterMine::Results
187
185
  # CSV or TSV file. The optional separator argument will be used to delimit
188
186
  # columns
189
187
  def to_csv(sep="\t")
190
- return @results.map {|x| value_of(x).inspect}.join(sep)
188
+ return @results.map {|x| x["value"].inspect}.join(sep)
191
189
  end
192
190
 
193
191
  private
194
192
 
195
- def value_of(cell)
196
- return cell["value"]
197
- end
198
-
199
193
  # Return the index for a string or symbol key.
200
194
  def index_for(key)
201
195
  if @indexes.nil?
@@ -215,13 +209,6 @@ module InterMine::Results
215
209
  end
216
210
  end
217
211
 
218
- class NewResultRow < ResultsRow
219
-
220
- def value_of(cell)
221
- return cell
222
- end
223
- end
224
-
225
212
  # The class responsible for retrieving results and processing them
226
213
  #
227
214
  # query.each_row do |row|
@@ -263,13 +250,11 @@ module InterMine::Results
263
250
 
264
251
  # Iterate over the result set one ResultsRow at a time
265
252
  def each_row
266
- cls = @query.service.version >= 8 ? NewResultRow : ResultsRow
267
- format = @query.service.version >= 8 ? "json" : "jsonrows"
268
253
  processor = lambda {|line|
269
254
  x = line.chomp.chomp(",")
270
- x.empty? ? nil : cls.new(x, @query.views)
255
+ x.empty? ? nil : ResultsRow.new(x, @query.views)
271
256
  }
272
- read_result_set(params(format), processor) {|x|
257
+ read_result_set(params("jsonrows"), processor) {|x|
273
258
  yield x
274
259
  }
275
260
  end
@@ -109,6 +109,7 @@ module InterMine
109
109
  LIST_INTERSECTION_PATH = "/lists/intersect/json"
110
110
  LIST_SUBTRACTION_PATH = "/lists/subtract/json"
111
111
  LIST_TAG_PATH = "/list/tags/json"
112
+ LIST_ENRICHMENT_PATH = "/list/enrichment"
112
113
 
113
114
  # The webservice version. An integer that
114
115
  # supplies information about what features are supported.
@@ -3,6 +3,9 @@ module Intermine
3
3
  # Webservice Client Version number
4
4
  #
5
5
  # Changes:
6
+ # 1.00.00 - Up to make use of new features of the InterMine 1.0 API
7
+ # * Enrichment queries
8
+ # * Range constraints
6
9
  # 0.98.11 - * InterMineObjects now lazily fetch their references
7
10
  # if nil. Note that while extremely convenient,
8
11
  # explicit prefetching will be much more efficient
@@ -12,10 +15,5 @@ module Intermine
12
15
  # 0.98.10 - Added status property to lists
13
16
  # 0.98.09 - Major changes to results - now with thorough-going Enumerable support
14
17
  # 0.98.08 - Added column summary support
15
- # 0.99.00 - Added coercion from query to lists in "IN/NOT IN" constraints
16
- # - Added support for "json" format (performance) improvement
17
- # 0.99.01 - Added support for sort-orders on selected classes which are not in the view
18
- # 0.99.02 - Fixed bug with null values in new result rows (resulting commonly from outer joins)
19
- # 0.99.03 - Fixed handling of null references and empty collections in lazy reference fetching.
20
- VERSION = "0.99.03"
18
+ VERSION = "1.00.00"
21
19
  end
@@ -0,0 +1,164 @@
1
+ require File.dirname(__FILE__) + "/test_helper.rb"
2
+
3
+ require "test/unit"
4
+ require "intermine/service"
5
+ require "intermine/results"
6
+
7
+ class LiveResultsTest < Test::Unit::TestCase
8
+
9
+ def setup
10
+ @service = Service.new("http://localhost/intermine-test")
11
+ @max = 50
12
+ @q = @service.query("Employee").select("*", "department.*").where(:age => {:lt => @max})
13
+ @empty = @service.query("Employee").where(:name => "some-non-existant-value")
14
+ @exp_count = 82
15
+ @expected_last = "Didier Legu\303\251lec"
16
+ @expected_last_summary = "Vincent"
17
+ @expected_last_obj = "Both Quotes '\""
18
+ @expected_target = 37.02439
19
+ @expected_two_vowels = 31
20
+ @exp_trideps = 5
21
+ @exp_s_deps = 29
22
+ @exp_row_size = 7
23
+ @rows_args = []
24
+ @results_args = []
25
+ @summary_args = []
26
+ @count_args = []
27
+ @dep_size = 3
28
+ end
29
+
30
+ def testRowIteration
31
+ count = 0
32
+ @q.rows(*@rows_args).each do |row|
33
+ assert_equal(@exp_row_size, row.size)
34
+ assert(row["age"].is_a? Fixnum)
35
+ assert(row["age"] < @max)
36
+ assert(row["name"].is_a? String)
37
+ count += 1
38
+ end
39
+ assert_equal(@exp_count, count)
40
+ end
41
+
42
+ def testEmptyRows
43
+ count = 0
44
+ @empty.rows.each do
45
+ count += 1
46
+ end
47
+ assert_equal(0, count)
48
+ end
49
+
50
+ def testRowMapping
51
+ names = @q.rows(*@rows_args).map {|r| r["name"]}
52
+ assert_equal(@exp_count, names.length)
53
+ assert_equal(@expected_last, names.last)
54
+ end
55
+
56
+ def testRowFolding
57
+ average = @q.rows(*@rows_args).reduce(0.0) {|m, i| m + i["age"]} / @q.count(*@count_args)
58
+ target = @expected_target
59
+ assert(average > target * 0.999999)
60
+ assert(average < target * 1.000001)
61
+ end
62
+
63
+ def testRowFiltering
64
+ two_vowels = @q.rows(*@rows_args).select {|r| r["name"].match(/[aeiou]{2}/) }
65
+ assert_equal(@expected_two_vowels, two_vowels.length)
66
+ end
67
+
68
+ def testObjectIteration
69
+ count = 0
70
+ @q.results(*@results_args).each do |emp|
71
+ assert(emp.is_a? @q.model.table("Employee"))
72
+ assert(emp.age.is_a? Fixnum)
73
+ assert(emp.age < @max)
74
+ assert(emp.name.is_a? String)
75
+ count += 1
76
+ end
77
+ assert_equal(@exp_count, count)
78
+ end
79
+
80
+ def testEmptyObjects
81
+ count = 0
82
+ @empty.results.each do
83
+ count += 1
84
+ end
85
+ assert_equal(0, count)
86
+ end
87
+
88
+ def testObjectMapping
89
+ names = @q.results(*@results_args).map {|r| r.name}
90
+ assert_equal(@exp_count, names.length)
91
+ assert_equal(@expected_last_obj, names.last)
92
+ end
93
+
94
+ def testObjectFolding
95
+ average = @q.results(*@results_args).reduce(0.0) {|m, i| m + i.age} / @q.count(*@count_args)
96
+ target = @expected_target
97
+ assert(average > target * 0.999999, "Checking lower bound on #{average}")
98
+ assert(average < target * 1.000001, "Checking upper bound on #{average}")
99
+ end
100
+
101
+ def testObjectFiltering
102
+ emps_in_s_deps = @q.results(*@results_args).select {|o| o.department.name.start_with? "S"}
103
+ assert_equal(@exp_s_deps, emps_in_s_deps.length)
104
+ end
105
+
106
+ def testSummaryIteration
107
+ count = 0
108
+ @q.summaries("name", *@summary_args).each do |summary|
109
+ assert_equal(1, summary["count"])
110
+ count += 1
111
+ end
112
+ assert_equal(@exp_count, count)
113
+ end
114
+
115
+ def testEmptySummaries
116
+ count = 0
117
+ @empty.summaries("name").each do
118
+ count += 1
119
+ end
120
+ assert_equal(0, count)
121
+ end
122
+
123
+ def testSummaryMapping
124
+ names = @q.summaries("name", *@summary_args).map {|s| s["item"]}
125
+ assert_equal(@exp_count, names.length)
126
+ assert_equal(@expected_last_summary, names.last)
127
+ end
128
+
129
+ def testSummaryFolding
130
+ sum = @q.summaries("name", *@summary_args).reduce(0) {|m, i| m + i["count"]}
131
+ assert_equal(@q.count(*@count_args), sum)
132
+ end
133
+
134
+ def testSummaryFiltering
135
+ trideps = @q.summaries("department.name", *@summary_args).select {|s| s["count"] == @dep_size}
136
+ assert_equal(@exp_trideps, trideps.length)
137
+ end
138
+ end
139
+
140
+ class LiveTemplateResultsTest < LiveResultsTest
141
+
142
+ def setup
143
+ @service = Service.new("http://localhost/intermine-test")
144
+ @q = @service.template("employeesOverACertainAgeFromDepartmentA")
145
+ @empty = @q
146
+ @exp_count = 18
147
+ @expected_last = "Tim Canterbury"
148
+ @expected_last_summary = "Tim Canterbury"
149
+ @expected_last_obj = "Fatou"
150
+ @expected_target = 47.277778
151
+ @expected_two_vowels = 4
152
+ @dep_size = 18
153
+ @exp_trideps = 1
154
+ @exp_s_deps = 18
155
+ @max = 69
156
+ @rows_args = [{"B" => "Sales"}]
157
+ @results_args = [{"B" => "Sales"}]
158
+ @summary_args = [{"B" => "Sales"}]
159
+ @count_args = [{"B" => "Sales"}]
160
+ @exp_row_size = 3
161
+
162
+ end
163
+ end
164
+
@@ -0,0 +1,59 @@
1
+ require File.dirname(__FILE__) + "/test_helper.rb"
2
+
3
+ require "test/unit"
4
+ require "intermine/service"
5
+
6
+ class LiveSummaryTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ @service = Service.new("http://localhost/intermine-test")
10
+ @query = @service.query("Employee").where(:age => {:lt => 50})
11
+ end
12
+
13
+ def testIteration
14
+ @query.summaries("age").each {|summary|
15
+ assert_equal("37.0243902439024390", summary["average"])
16
+ assert(summary["max"] < 50)
17
+ }
18
+
19
+ count = 0
20
+ @query.summaries("name").each {|summary|
21
+ assert_equal(1, summary["count"])
22
+ count += 1
23
+ }
24
+ assert_equal(count, @query.count)
25
+
26
+ end
27
+
28
+ def testNumericSummary
29
+ summary = @query.summarise("age")
30
+ assert(summary["max"] < 50)
31
+ # Work around float comparison errors, grrr
32
+ assert(summary["average"] > 37.024)
33
+ assert(summary["average"] < 37.025)
34
+ end
35
+
36
+ def testNonNumericSummary
37
+ summary = @query.summarise("name")
38
+ assert_equal(1, summary["Tim Canterbury"])
39
+ end
40
+
41
+ def testTop
42
+ summary = @query.summaries("department.name")
43
+ top = summary.first
44
+ assert_equal("Warehouse", top["item"])
45
+ assert_equal(12, top["count"])
46
+ end
47
+
48
+ def testTemplateSummary
49
+ template = @service.template("CEO_Rivals")
50
+ template_params = {"A" => {"!=" => "Charles Miner"}}
51
+
52
+ summary = template.summarise("salary", template_params)
53
+ assert_equal(529119.4, summary["average"])
54
+
55
+ summary = template.summarise("company.name", template_params)
56
+ assert_equal(1, summary["Gogirep"])
57
+ end
58
+
59
+ end
data/test/live_test.rb CHANGED
@@ -6,7 +6,7 @@ require "intermine/service"
6
6
  class LiveDemoTest < Test::Unit::TestCase
7
7
 
8
8
  def setup
9
- @service = Service.new("localhost/intermine-test", "test-user-token")
9
+ @service = Service.new("http://localhost/intermine-test", "test-user-token")
10
10
  @temp_lists = []
11
11
  end
12
12
 
@@ -48,10 +48,10 @@ class LiveDemoTest < Test::Unit::TestCase
48
48
  def testListEnumerability
49
49
  list = @service.list("My-Favourite-Employees")
50
50
  names = list.map {|emp| emp.name }
51
- exp = ["David Brent", "Neil Godwin", "Bernd Stromberg", "Timo Becker"]
51
+ exp = [ "David Brent", "Neil Godwin", "Bernd Stromberg", "Timo Becker"]
52
52
  assert_equal(exp, names)
53
53
 
54
- old = list.select {|emp| emp.age > 42}
54
+ old = list.select {|emp| emp.age > 43}
55
55
  assert_equal(1, old.size)
56
56
  assert_equal("Neil Godwin", old.first.name)
57
57
 
@@ -63,23 +63,23 @@ class LiveDemoTest < Test::Unit::TestCase
63
63
  list = @service.list("My-Favourite-Employees")
64
64
 
65
65
  deps = list.map {|emp| emp.department.name }
66
- exp = ["Sales", "Human Resources",
67
- "Schadensregulierung M-Z", "Schadensregulierung"]
66
+ exp = ["Sales", "Human Resources", "Schadensregulierung M-Z", "Schadensregulierung"]
68
67
  assert_equal(exp, deps)
69
68
 
70
69
  comps = list.map {|emp| emp.department.company.name }
71
- exp = [ "Wernham-Hogg","Wernham-Hogg",
72
- "Capitol Versicherung AG", "Capitol Versicherung AG"]
70
+ exp = ["Wernham-Hogg", "Wernham-Hogg", "Capitol Versicherung AG", "Capitol Versicherung AG"]
73
71
  assert_equal(exp, comps)
74
72
  end
75
73
 
76
74
  def testLazyCollectionFetching
77
75
  list = @service.list("My-Favourite-Employees")
78
76
  emps = list.map {|manager| manager.department.employees.map {|employee| employee.age} }
79
- exp = [[41, 36, 55, 34, 61, 61],
80
- [44, 49, 62],
81
- [37, 45, 30, 64, 46, 58],
82
- [37, 49, 39, 57, 36, 59]]
77
+ exp = [
78
+ [34, 36, 41, 55, 61, 61],
79
+ [44, 49, 62],
80
+ [30, 37, 45, 46, 58, 64],
81
+ [36, 37, 39, 49, 57, 59]
82
+ ]
83
83
  assert_equal(exp, emps)
84
84
 
85
85
  sum = list.reduce(0) {|m, manager| m + manager.department.employees.reduce(0) {|n, emp| n + emp.age}}
@@ -130,15 +130,10 @@ class LiveDemoTest < Test::Unit::TestCase
130
130
  assert_equal(tags.sort, new_list.tags.sort)
131
131
  end
132
132
 
133
- def testCoercingQueriesToLists
134
- q1 = @service.query("Bank")
135
- q2 = @service.query("Bank").where("corporateCustomers.id" => {'!=' => nil})
136
-
137
- assert_equal(2, @service.query("Bank").where("Bank" => {:not_in => q2}).count)
138
-
139
- l = @service.subtract([q1], [q2])
140
- @temp_lists << l
141
- assert_equal(2, l.size)
133
+ def testEnrichment
134
+ l = @service.list("My-Favourite-Employees")
135
+ contractors = l.calculate_enrichment :contractor_enrichment, :maxp => 1.0
136
+ assert_equal("Vikram", contractors.first[:identifier])
142
137
  end
143
138
 
144
139
  end
data/test/test_query.rb CHANGED
@@ -640,6 +640,20 @@ class TestQuery < Test::Unit::TestCase
640
640
  assert_equal(conA.values, %w{Sales Marketing Janitorial})
641
641
  end
642
642
 
643
+ def test_range_constraints
644
+ query = InterMine::PathQuery::Query.new(@model, "Employee")
645
+ query.add_constraint({
646
+ :path => "age",
647
+ :op => "WITHIN",
648
+ :values => %w{1..10 30..35}
649
+ })
650
+
651
+ conA = query.constraints.first
652
+ assert_equal(conA.path.to_s, "Employee.age")
653
+ assert_equal(conA.op, "WITHIN")
654
+ assert_equal(conA.values, ["1..10", "30..35"])
655
+ end
656
+
643
657
  def test_bad_multi_constraint
644
658
  query = InterMine::PathQuery::Query.new(@model, "Employee")
645
659
  assert_raise ArgumentError do
@@ -848,12 +862,6 @@ class TestQuery < Test::Unit::TestCase
848
862
 
849
863
  assert_equal(query.sort_order.last.path, "Employee.name")
850
864
  assert_equal(query.sort_order.last.direction, "DESC")
851
-
852
- query.add_sort_order("fullTime")
853
-
854
- assert_equal(query.sort_order.last.path, "Employee.fullTime")
855
- assert_equal(query.sort_order.last.direction, "ASC")
856
-
857
865
  end
858
866
 
859
867
  def test_subclassed_sort_order
@@ -981,6 +989,11 @@ class TestQuery < Test::Unit::TestCase
981
989
  :value => "zop",
982
990
  :extra_value => "zip"
983
991
  })
992
+ query.add_constraint({
993
+ :path => "age",
994
+ :op => "WITHIN",
995
+ :values => %w{1..10 30..35}
996
+ })
984
997
  query.add_constraint({
985
998
  :path => "Employee",
986
999
  :sub_class => "Manager"
@@ -998,6 +1011,9 @@ class TestQuery < Test::Unit::TestCase
998
1011
  "<constraint loopPath='Employee.department.manager' op='=' code='E' path='Employee'/>" +
999
1012
  "<constraint op='LOOKUP' code='F' value='quux' path='Employee'/>" +
1000
1013
  "<constraint extraValue='zip' op='LOOKUP' code='G' value='zop' path='Employee'/>" +
1014
+ "<constraint op='WITHIN' code='H' path='Employee.age'>" +
1015
+ "<value>1..10</value><value>30..35</value>" +
1016
+ "</constraint>" +
1001
1017
  "</query>"
1002
1018
 
1003
1019
  compare_xml(expected, query.to_xml.to_s)
@@ -12,14 +12,9 @@ class TestResults < Test::Unit::TestCase
12
12
  super
13
13
  file = File.new(
14
14
  File.dirname(__FILE__) + "/data/resultrow.json", "r")
15
- file2 = File.new(
16
- File.dirname(__FILE__) + "/data/resultrow_new.json", "r")
17
15
  @data = file.read
18
- @data2 = file2.read
19
16
  @json = JSON.parse(@data)
20
- @json2 = JSON.parse(@data2)
21
17
  @view = ["Company.departments.name","Company.departments.manager.name", "Company.departments.manager.age"]
22
- @view2 = ["Company.departments.name","Company.departments.manager.name", "Company.departments.manager.age", "Company.address.address"]
23
18
  @bad_view = ["Company.departments.name","Company.departments.manager.name"]
24
19
  end
25
20
 
@@ -47,31 +42,6 @@ class TestResults < Test::Unit::TestCase
47
42
  end
48
43
  end
49
44
 
50
- def test_array_access2
51
-
52
- rr = NewResultRow.new(@data2, @view2)
53
-
54
- assert_equal(rr[0], "DepartmentA1")
55
- assert_equal(rr[1], "EmployeeA1")
56
-
57
- rr = NewResultRow.new(@json2, @view2)
58
-
59
- assert_equal(rr[0], "DepartmentA1")
60
- assert_equal(rr[1], "EmployeeA1")
61
-
62
- assert_equal(rr[1..2], ["EmployeeA1", 33])
63
- assert_equal(rr[0, 2], ["DepartmentA1", "EmployeeA1"])
64
-
65
- assert_equal(rr.first, "DepartmentA1")
66
- assert_equal(rr[3], nil)
67
- assert_equal(rr.last, nil)
68
-
69
- assert_raise IndexError do
70
- rr[4]
71
- end
72
-
73
- end
74
-
75
45
  def test_array_access
76
46
 
77
47
  rr = ResultsRow.new(@data, @view)
data/test/test_sugar.rb CHANGED
@@ -32,13 +32,14 @@ class TestQuerySugar < Test::Unit::TestCase
32
32
 
33
33
  def test_view_expansion
34
34
  q = @model.table("Employee").select("*", "department.*")
35
- expected = ["Employee.name",
35
+ expected = [
36
+ "Employee.age",
36
37
  "Employee.end",
37
- "Employee.id",
38
38
  "Employee.fullTime",
39
- "Employee.age",
40
- "Employee.department.name",
41
- "Employee.department.id"]
39
+ "Employee.id",
40
+ "Employee.name",
41
+ "Employee.department.id",
42
+ "Employee.department.name"]
42
43
 
43
44
  assert_equal(expected, q.views.map {|x| x.to_s})
44
45
  end
@@ -50,7 +51,7 @@ class TestQuerySugar < Test::Unit::TestCase
50
51
  where(:name => {"=" => nil}).
51
52
  where(:fullTime => {"!=" => nil})
52
53
 
53
- expected = "<query model='testmodel' sortOrder='Employee.name ASC' view='Employee.name Employee.end Employee.id Employee.fullTime Employee.age'>" +
54
+ expected = "<query model='testmodel' sortOrder='Employee.age ASC' view='Employee.age Employee.end Employee.fullTime Employee.id Employee.name'>" +
54
55
  "<constraint op='IS NULL' code='A' path='Employee.age'/>" +
55
56
  "<constraint op='IS NULL' code='B' path='Employee.name'/>" +
56
57
  "<constraint op='IS NOT NULL' code='C' path='Employee.fullTime'/>" +
@@ -68,7 +69,7 @@ class TestQuerySugar < Test::Unit::TestCase
68
69
  where("department.name" => {:contains => "foo"}).
69
70
  where(:name => {"!=" => "bar"})
70
71
 
71
- expected = "<query model='testmodel' sortOrder='Employee.name ASC' view='Employee.name Employee.end Employee.id Employee.fullTime Employee.age'>" +
72
+ expected = "<query model='testmodel' sortOrder='Employee.age ASC' view='Employee.age Employee.end Employee.fullTime Employee.id Employee.name'>" +
72
73
  "<constraint op='=' code='A' value='foo' path='Employee.name'/>" +
73
74
  "<constraint op='=' code='B' value='10' path='Employee.age'/>" +
74
75
  "<constraint op='&lt;' code='C' value='200' path='Employee.end'/>" +
@@ -90,7 +91,7 @@ class TestQuerySugar < Test::Unit::TestCase
90
91
  where(:name => {:ne => "bar"}).
91
92
  where(:name => {:== => "zop"})
92
93
 
93
- expected = "<query model='testmodel' sortOrder='Employee.name ASC' view='Employee.name Employee.end Employee.id Employee.fullTime Employee.age'>" +
94
+ expected = "<query model='testmodel' sortOrder='Employee.age ASC' view='Employee.age Employee.end Employee.fullTime Employee.id Employee.name'>" +
94
95
  "<constraint op='&lt;' code='A' value='100' path='Employee.age'/>" +
95
96
  "<constraint op='&gt;' code='B' value='200' path='Employee.age'/>" +
96
97
  "<constraint op='&lt;=' code='C' value='300' path='Employee.age'/>" +
@@ -110,7 +111,7 @@ class TestQuerySugar < Test::Unit::TestCase
110
111
  where(:department => {:lookup => "foo"}).
111
112
  where("department.company" => {:lookup => "foo", :with => "extra"})
112
113
 
113
- expected = "<query model='testmodel' sortOrder='Employee.name ASC' view='Employee.name Employee.end Employee.id Employee.fullTime Employee.age'>" +
114
+ expected = "<query model='testmodel' sortOrder='Employee.age ASC' view='Employee.age Employee.end Employee.fullTime Employee.id Employee.name'>" +
114
115
  "<constraint op='LOOKUP' code='A' value='foo' path='Employee.department'/>" +
115
116
  "<constraint extraValue='extra' op='LOOKUP' code='B' value='foo' path='Employee.department.company'/>" +
116
117
  "</query>"
@@ -127,7 +128,7 @@ class TestQuerySugar < Test::Unit::TestCase
127
128
  where("Employee.department" => {:in => "a list"}).
128
129
  where("Employee.department.company" => {:not_in => "a list"})
129
130
 
130
- expected = "<query model='testmodel' sortOrder='Employee.name ASC' view='Employee.name Employee.end Employee.id Employee.fullTime Employee.age'>" +
131
+ expected = "<query model='testmodel' sortOrder='Employee.age ASC' view='Employee.age Employee.end Employee.fullTime Employee.id Employee.name'>" +
131
132
  "<constraint op='IN' code='A' value='test-list' path='Employee'/>" +
132
133
  "<constraint op='IN' code='B' value='test-list' path='Employee.department.manager'/>" +
133
134
  "<constraint op='NOT IN' code='C' value='test-list' path='Employee.department.manager'/>" +
@@ -152,7 +153,7 @@ class TestQuerySugar < Test::Unit::TestCase
152
153
  where("department.manager.age" => {:none_of => [46, 47]}).
153
154
  where("department.manager.end" => {:one_of => [56, 57]})
154
155
 
155
- expected = "<query model='testmodel' sortOrder='Employee.name ASC' view='Employee.name Employee.end Employee.id Employee.fullTime Employee.age'>" +
156
+ expected = "<query model='testmodel' sortOrder='Employee.age ASC' view='Employee.age Employee.end Employee.fullTime Employee.id Employee.name'>" +
156
157
  "<constraint op='ONE OF' code='A' path='Employee.age'>" +
157
158
  "<value>30</value><value>31</value><value>32</value><value>33</value><value>34</value><value>35</value>" +
158
159
  "</constraint>" +
@@ -194,7 +195,7 @@ class TestQuerySugar < Test::Unit::TestCase
194
195
  where("department.company.CEO" => {:is => "department.manager"}).
195
196
  where("department.company.CEO" => {:is_not => "department.employees"})
196
197
 
197
- expected = "<query model='testmodel' sortOrder='Employee.name ASC' view='Employee.name Employee.end Employee.id Employee.fullTime Employee.age'>" +
198
+ expected = "<query model='testmodel' sortOrder='Employee.age ASC' view='Employee.age Employee.end Employee.fullTime Employee.id Employee.name'>" +
198
199
  "<constraint op='=' loopPath='Employee.department.manager' code='A' path='Employee.department.company.CEO'/>" +
199
200
  "<constraint op='!=' loopPath='Employee.department.employees' code='B' path='Employee.department.company.CEO'/>" +
200
201
  "</query>"
@@ -209,7 +210,7 @@ class TestQuerySugar < Test::Unit::TestCase
209
210
  where("department.employees" => manager).
210
211
  where("department.employees" => {:sub_class => "CEO"})
211
212
 
212
- expected = "<query model='testmodel' sortOrder='Employee.name ASC' view='Employee.name Employee.end Employee.id Employee.fullTime Employee.age'>" +
213
+ expected = "<query model='testmodel' sortOrder='Employee.age ASC' view='Employee.age Employee.end Employee.fullTime Employee.id Employee.name'>" +
213
214
  "<constraint type='Manager' path='Employee.department.employees'/>" +
214
215
  "<constraint type='CEO' path='Employee.department.employees'/>" +
215
216
  "</query>"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: intermine
3
3
  version: !ruby/object:Gem::Version
4
- hash: 405
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
+ - 1
7
8
  - 0
8
- - 99
9
- - 3
10
- version: 0.99.03
9
+ - 0
10
+ version: 1.00.00
11
11
  platform: ruby
12
12
  authors:
13
13
  - Alex Kalderimis
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-01-18 00:00:00 Z
18
+ date: 2012-10-08 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: json
@@ -133,6 +133,8 @@ files:
133
133
  - test/data/resultrow.json
134
134
  - test/data/resultset.json
135
135
  - test/data/testmodel_model.xml
136
+ - test/live_results.rb
137
+ - test/live_summary_test.rb
136
138
  - test/live_test.rb
137
139
  - test/test.rb
138
140
  - test/test_helper.rb
@@ -148,7 +150,6 @@ files:
148
150
  - LICENCE
149
151
  - Rakefile
150
152
  - README.rdoc
151
- - TODO
152
153
  - Gemfile
153
154
  - contact_header.rdoc
154
155
  homepage: http://www.intermine.org
@@ -184,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
184
185
  requirements: []
185
186
 
186
187
  rubyforge_project: intermine
187
- rubygems_version: 1.7.2
188
+ rubygems_version: 1.8.15
188
189
  signing_key:
189
190
  specification_version: 3
190
191
  summary: Webservice Client Library for InterMine Data-Warehouses
data/TODO DELETED
@@ -1,3 +0,0 @@
1
- json formats (and benchmarks)
2
- test for CD.find
3
-