intermine 0.98.01
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/Gemfile +4 -0
- data/LICENCE +165 -0
- data/MANIFEST +0 -0
- data/README.rdoc +79 -0
- data/Rakefile +67 -0
- data/lib/intermine/lists.rb +716 -0
- data/lib/intermine/model.rb +867 -0
- data/lib/intermine/query.rb +1569 -0
- data/lib/intermine/results.rb +196 -0
- data/lib/intermine/service.rb +253 -0
- data/lib/intermine/version.rb +3 -0
- data/test/data/lists.json +29 -0
- data/test/data/model.json +3 -0
- data/test/data/resultobjs.json +3 -0
- data/test/data/resultrow.json +1 -0
- data/test/data/resultset.json +3 -0
- data/test/data/testmodel_model.xml +94 -0
- data/test/live_test.rb +35 -0
- data/test/test.rb +84 -0
- data/test/test_helper.rb +67 -0
- data/test/test_lists.rb +68 -0
- data/test/test_model.rb +417 -0
- data/test/test_query.rb +1202 -0
- data/test/test_result_row.rb +114 -0
- data/test/test_results.rb +22 -0
- data/test/test_service.rb +86 -0
- data/test/test_sugar.rb +219 -0
- data/test/unit_tests.rb +6 -0
- metadata +192 -0
@@ -0,0 +1,114 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/test_helper.rb"
|
2
|
+
require "intermine/results"
|
3
|
+
require 'rubygems'
|
4
|
+
require "json"
|
5
|
+
require "test/unit"
|
6
|
+
|
7
|
+
class TestResults < Test::Unit::TestCase
|
8
|
+
|
9
|
+
include Results
|
10
|
+
|
11
|
+
def initialize(name)
|
12
|
+
super
|
13
|
+
file = File.new(
|
14
|
+
File.dirname(__FILE__) + "/data/resultrow.json", "r")
|
15
|
+
@data = file.read
|
16
|
+
@json = JSON.parse(@data)
|
17
|
+
@view = ["Company.departments.name","Company.departments.manager.name"]
|
18
|
+
@bad_view = ["Company.departments.name","Company.departments.manager.name", "Comany.name"]
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_initialize
|
22
|
+
rr = ResultsRow.new(@data, @view)
|
23
|
+
assert_kind_of(ResultsRow, rr)
|
24
|
+
|
25
|
+
rr = ResultsRow.new(@json, @view)
|
26
|
+
assert_kind_of(ResultsRow, rr)
|
27
|
+
|
28
|
+
assert_raise ArgumentError do
|
29
|
+
ResultsRow.new
|
30
|
+
end
|
31
|
+
|
32
|
+
assert_raise ArgumentError do
|
33
|
+
ResultsRow.new(@data)
|
34
|
+
end
|
35
|
+
|
36
|
+
assert_raise ArgumentError do
|
37
|
+
ResultsRow.new(@data, @bad_view)
|
38
|
+
end
|
39
|
+
|
40
|
+
assert_raise ArgumentError do
|
41
|
+
ResultsRow.new(@json, @bad_view)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_array_access
|
46
|
+
|
47
|
+
rr = ResultsRow.new(@data, @view)
|
48
|
+
|
49
|
+
assert_equal(rr[0], "DepartmentA1")
|
50
|
+
assert_equal(rr[1], "EmployeeA1")
|
51
|
+
|
52
|
+
rr = ResultsRow.new(@json, @view)
|
53
|
+
|
54
|
+
assert_equal(rr[0], "DepartmentA1")
|
55
|
+
assert_equal(rr[1], "EmployeeA1")
|
56
|
+
|
57
|
+
rr = ResultsRow.new(@json, @view)
|
58
|
+
|
59
|
+
assert_raise IndexError do
|
60
|
+
rr[3]
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_hash_access
|
66
|
+
|
67
|
+
rr = ResultsRow.new(@data, @view)
|
68
|
+
|
69
|
+
assert_equal(rr["Company.departments.name"], "DepartmentA1")
|
70
|
+
assert_equal(rr["Company.departments.manager.name"], "EmployeeA1")
|
71
|
+
|
72
|
+
rr = ResultsRow.new(@json, @view)
|
73
|
+
|
74
|
+
assert_equal(rr["Company.departments.name"], "DepartmentA1")
|
75
|
+
assert_equal(rr["Company.departments.manager.name"], "EmployeeA1")
|
76
|
+
|
77
|
+
rr = ResultsRow.new(@json, @view)
|
78
|
+
|
79
|
+
assert_raise IndexError do
|
80
|
+
rr["foo"]
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_to_a
|
86
|
+
|
87
|
+
expected = %w{DepartmentA1 EmployeeA1}
|
88
|
+
|
89
|
+
rr = ResultsRow.new(@data, @view)
|
90
|
+
|
91
|
+
assert_equal(expected, rr.to_a)
|
92
|
+
|
93
|
+
rr = ResultsRow.new(@json, @view)
|
94
|
+
|
95
|
+
assert_equal(expected, rr.to_a)
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_to_h
|
99
|
+
|
100
|
+
rr = ResultsRow.new(@data, @view)
|
101
|
+
|
102
|
+
expected = {
|
103
|
+
"Company.departments.name" => "DepartmentA1",
|
104
|
+
"Company.departments.manager.name" => "EmployeeA1"
|
105
|
+
}
|
106
|
+
assert_equal(expected, rr.to_h)
|
107
|
+
|
108
|
+
rr = ResultsRow.new(@json, @view)
|
109
|
+
|
110
|
+
assert_equal(expected, rr.to_h)
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
$LOAD_PATH << File.expand_path( File.dirname(__FILE__) + '/../lib' )
|
2
|
+
require "intermine/model"
|
3
|
+
require "intermine/query"
|
4
|
+
require "intermine/results"
|
5
|
+
include PathQuery
|
6
|
+
|
7
|
+
d = File.new(File.dirname(__FILE__) + "/data/model.json").read
|
8
|
+
m = Model.new(d)
|
9
|
+
q = Query.new(m, "Employee")
|
10
|
+
q.add_views("name", "age")
|
11
|
+
q.add_constraint({:path => "age", :op => ">", :value => 40})
|
12
|
+
q.add_sort_order("age")
|
13
|
+
params = {"query" => q.to_xml, "format" => "jsonrows"}
|
14
|
+
uri = "http://squirrel.flymine.org/intermine-test/service/query/results"
|
15
|
+
rr = Results::ResultsReader.new(uri, params, q.views)
|
16
|
+
sum, total = 0, 0
|
17
|
+
rr.each_row {|emp|
|
18
|
+
puts emp
|
19
|
+
sum += emp["age"]
|
20
|
+
total += 1
|
21
|
+
}
|
22
|
+
puts "Average age: #{sum/total} years"
|
@@ -0,0 +1,86 @@
|
|
1
|
+
$LOAD_PATH << File.expand_path( File.dirname(__FILE__) + '/../lib' )
|
2
|
+
require "intermine/service"
|
3
|
+
|
4
|
+
service = Service.new("http://squirrel.flymine.org/intermine-test/service")
|
5
|
+
|
6
|
+
p service.version
|
7
|
+
p service.model.name
|
8
|
+
|
9
|
+
sum, total = 0, 0
|
10
|
+
|
11
|
+
service.model.table("Employee").
|
12
|
+
select("name", "age").
|
13
|
+
where(:age => {">" => 60}).
|
14
|
+
order_by("age", "desc").each_row do |emp|
|
15
|
+
puts emp
|
16
|
+
sum += emp["age"]
|
17
|
+
total += 1
|
18
|
+
end
|
19
|
+
|
20
|
+
puts "Average => #{sum/total} - #{total} employees"
|
21
|
+
puts
|
22
|
+
|
23
|
+
tok_service = Service.new("http://squirrel.flymine.org/intermine-test/service", "a1v3V1X0f3hdmaybq0l6b7Z4eVG")
|
24
|
+
|
25
|
+
q = tok_service.new_query("Employee")
|
26
|
+
q.add_views("name", "age")
|
27
|
+
q.add_constraint(:path => "Employee", :op => "IN", :value => "My-Favourite-Employees")
|
28
|
+
|
29
|
+
sum = 0
|
30
|
+
q.each_row do |emp|
|
31
|
+
puts emp
|
32
|
+
sum += emp["age"]
|
33
|
+
end
|
34
|
+
|
35
|
+
total = q.count
|
36
|
+
puts "Average => #{sum/total} - #{total} employees"
|
37
|
+
puts
|
38
|
+
|
39
|
+
q = tok_service.new_query("Department").add_views("name")
|
40
|
+
|
41
|
+
q.add_constraint(:path => "employees", :op => "IN", :value => "My-Favourite-Employees")
|
42
|
+
|
43
|
+
q.each_row do |emp|
|
44
|
+
puts emp
|
45
|
+
end
|
46
|
+
|
47
|
+
sum, total,current_dep = 0, 0, nil
|
48
|
+
service.model.table("Employee").
|
49
|
+
select(:name, :age, "department.name").
|
50
|
+
where(:age => {"<" => 27}).
|
51
|
+
where("department.name" => "S*").
|
52
|
+
order_by("department.name").
|
53
|
+
order_by(:age, :desc).
|
54
|
+
set_logic("A or B").each_row do |emp|
|
55
|
+
if (current_dep.nil? or current_dep != emp["department.name"])
|
56
|
+
current_dep = emp["department.name"]
|
57
|
+
puts "\n#{current_dep}\n#{"-" * current_dep.length}"
|
58
|
+
end
|
59
|
+
puts "#{emp["name"]} (#{emp["age"]})"
|
60
|
+
sum += emp["age"]
|
61
|
+
total += 1
|
62
|
+
end
|
63
|
+
|
64
|
+
puts
|
65
|
+
puts "Average => #{sum/total} - #{total} employees"
|
66
|
+
|
67
|
+
service.model.table("Employee").
|
68
|
+
select("*", "department.*").
|
69
|
+
where(:age => {"<" => 30}).
|
70
|
+
each_row do |emp|
|
71
|
+
puts emp
|
72
|
+
end
|
73
|
+
|
74
|
+
Service.new("http://www.flymine.org/query/service").
|
75
|
+
model.
|
76
|
+
table(:Gene).
|
77
|
+
select(:symbol, "alleles.*").
|
78
|
+
where(:symbol => %w{zen h H bib}).
|
79
|
+
outerjoin(:alleles).
|
80
|
+
each_result do |gene|
|
81
|
+
#puts gene
|
82
|
+
|
83
|
+
puts "#{"-" * 30}\n#{gene.symbol}: #{gene.alleles.size} Alleles"
|
84
|
+
puts "#{gene.alleles.map {|a| a.symbol}.join(", ")}"
|
85
|
+
end
|
86
|
+
|
data/test/test_sugar.rb
ADDED
@@ -0,0 +1,219 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/test_helper.rb"
|
2
|
+
require "intermine/query"
|
3
|
+
require "intermine/model"
|
4
|
+
require "intermine/lists"
|
5
|
+
require "intermine/service"
|
6
|
+
require "test/unit"
|
7
|
+
|
8
|
+
class Service
|
9
|
+
def fetch(x)
|
10
|
+
return 100
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class TestQuerySugar < Test::Unit::TestCase
|
15
|
+
|
16
|
+
def initialize(name)
|
17
|
+
super
|
18
|
+
file = File.new(
|
19
|
+
File.dirname(__FILE__) + "/data/model.json", "r")
|
20
|
+
data = file.read
|
21
|
+
@model = InterMine::Metadata::Model.new(data)
|
22
|
+
@service = InterMine::Service.new("foo", "bar", @model)
|
23
|
+
@model.send(:set_service, @service)
|
24
|
+
@list = InterMine::Lists::List.new({"name" => "test-list"})
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_select_statement
|
28
|
+
q = @model.table("Employee").select("Employee.name")
|
29
|
+
assert_kind_of(PathQuery::Query, q)
|
30
|
+
assert_equal(q.views, ["Employee.name"])
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_view_expansion
|
34
|
+
q = @model.table("Employee").select("*", "department.*")
|
35
|
+
expected = ["Employee.name",
|
36
|
+
"Employee.end",
|
37
|
+
"Employee.id",
|
38
|
+
"Employee.fullTime",
|
39
|
+
"Employee.age",
|
40
|
+
"Employee.department.name",
|
41
|
+
"Employee.department.id"]
|
42
|
+
|
43
|
+
assert_equal(expected, q.views.map {|x| x.to_s})
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_sugary_null_cons
|
47
|
+
q = @model.table("Employee").
|
48
|
+
select("*").
|
49
|
+
where(:age => nil).
|
50
|
+
where(:name => {"=" => nil}).
|
51
|
+
where(:fullTime => {"!=" => nil})
|
52
|
+
|
53
|
+
expected = "<query model='testmodel' sortOrder='Employee.name ASC' view='Employee.name Employee.end Employee.id Employee.fullTime Employee.age'>" +
|
54
|
+
"<constraint op='IS NULL' code='A' path='Employee.age'/>" +
|
55
|
+
"<constraint op='IS NULL' code='B' path='Employee.name'/>" +
|
56
|
+
"<constraint op='IS NOT NULL' code='C' path='Employee.fullTime'/>" +
|
57
|
+
"</query>"
|
58
|
+
|
59
|
+
compare_xml(expected, q.to_xml)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_sugary_binaries
|
63
|
+
|
64
|
+
q = @model.table("Employee").
|
65
|
+
where(:name => "foo").
|
66
|
+
where(:age => 10).
|
67
|
+
where(:end => {"<" => 200}).
|
68
|
+
where("department.name" => {:contains => "foo"}).
|
69
|
+
where(:name => {"!=" => "bar"})
|
70
|
+
|
71
|
+
expected = "<query model='testmodel' sortOrder='Employee.name ASC' view='Employee.name Employee.end Employee.id Employee.fullTime Employee.age'>" +
|
72
|
+
"<constraint op='=' code='A' value='foo' path='Employee.name'/>" +
|
73
|
+
"<constraint op='=' code='B' value='10' path='Employee.age'/>" +
|
74
|
+
"<constraint op='<' code='C' value='200' path='Employee.end'/>" +
|
75
|
+
"<constraint op='CONTAINS' code='D' value='foo' path='Employee.department.name'/>" +
|
76
|
+
"<constraint op='!=' code='E' value='bar' path='Employee.name'/>" +
|
77
|
+
"</query>"
|
78
|
+
|
79
|
+
compare_xml(expected, q.to_xml)
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_sugary_binary_aliases
|
83
|
+
|
84
|
+
q = @model.table("Employee").
|
85
|
+
where(:age => {:lt => 100}).
|
86
|
+
where(:age => {:gt => 200}).
|
87
|
+
where(:age => {:le => 300}).
|
88
|
+
where(:age => {:ge => 400}).
|
89
|
+
where("department.name" => {:eq => "foo"}).
|
90
|
+
where(:name => {:ne => "bar"}).
|
91
|
+
where(:name => {:== => "zop"})
|
92
|
+
|
93
|
+
expected = "<query model='testmodel' sortOrder='Employee.name ASC' view='Employee.name Employee.end Employee.id Employee.fullTime Employee.age'>" +
|
94
|
+
"<constraint op='<' code='A' value='100' path='Employee.age'/>" +
|
95
|
+
"<constraint op='>' code='B' value='200' path='Employee.age'/>" +
|
96
|
+
"<constraint op='<=' code='C' value='300' path='Employee.age'/>" +
|
97
|
+
"<constraint op='>=' code='D' value='400' path='Employee.age'/>" +
|
98
|
+
"<constraint op='=' code='E' value='foo' path='Employee.department.name'/>" +
|
99
|
+
"<constraint op='!=' code='F' value='bar' path='Employee.name'/>" +
|
100
|
+
"<constraint op='=' code='G' value='zop' path='Employee.name'/>" +
|
101
|
+
"</query>"
|
102
|
+
|
103
|
+
compare_xml(expected, q.to_xml)
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
def test_sugary_lookups
|
108
|
+
|
109
|
+
q = @model.table("Employee").
|
110
|
+
where(:department => {:lookup => "foo"}).
|
111
|
+
where("department.company" => {:lookup => "foo", :with => "extra"})
|
112
|
+
|
113
|
+
expected = "<query model='testmodel' sortOrder='Employee.name ASC' view='Employee.name Employee.end Employee.id Employee.fullTime Employee.age'>" +
|
114
|
+
"<constraint op='LOOKUP' code='A' value='foo' path='Employee.department'/>" +
|
115
|
+
"<constraint extraValue='extra' op='LOOKUP' code='B' value='foo' path='Employee.department.company'/>" +
|
116
|
+
"</query>"
|
117
|
+
|
118
|
+
compare_xml(expected, q.to_xml)
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_sugary_lists
|
122
|
+
|
123
|
+
q = @model.table("Employee").
|
124
|
+
where(:Employee => @list).
|
125
|
+
where("Employee.department.manager" => {"=" => @list}).
|
126
|
+
where("Employee.department.manager" => {"!=" => @list}).
|
127
|
+
where("Employee.department" => {:in => "a list"}).
|
128
|
+
where("Employee.department.company" => {:not_in => "a list"})
|
129
|
+
|
130
|
+
expected = "<query model='testmodel' sortOrder='Employee.name ASC' view='Employee.name Employee.end Employee.id Employee.fullTime Employee.age'>" +
|
131
|
+
"<constraint op='IN' code='A' value='test-list' path='Employee'/>" +
|
132
|
+
"<constraint op='IN' code='B' value='test-list' path='Employee.department.manager'/>" +
|
133
|
+
"<constraint op='NOT IN' code='C' value='test-list' path='Employee.department.manager'/>" +
|
134
|
+
"<constraint op='IN' code='D' value='a list' path='Employee.department'/>" +
|
135
|
+
"<constraint op='NOT IN' code='E' value='a list' path='Employee.department.company'/>" +
|
136
|
+
"</query>"
|
137
|
+
|
138
|
+
compare_xml(expected, q.to_xml)
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_sugary_multis
|
142
|
+
|
143
|
+
q = @model.table("Employee").
|
144
|
+
where(:age => 30 .. 35).
|
145
|
+
where("department.manager.name" => %w{zip zop zap}).
|
146
|
+
where(:age => {'=' => 35 .. 36}).
|
147
|
+
where(:end => {"!=" => 37 .. 39}).
|
148
|
+
where(:age => {"=" => [1, 2, 3]}).
|
149
|
+
where(:end => {"!=" => [3, 4, 5]}).
|
150
|
+
where("department.manager.age" => {:none_of => 40 .. 45}).
|
151
|
+
where("department.manager.end" => {:one_of => 50 .. 55}).
|
152
|
+
where("department.manager.age" => {:none_of => [46, 47]}).
|
153
|
+
where("department.manager.end" => {:one_of => [56, 57]})
|
154
|
+
|
155
|
+
expected = "<query model='testmodel' sortOrder='Employee.name ASC' view='Employee.name Employee.end Employee.id Employee.fullTime Employee.age'>" +
|
156
|
+
"<constraint op='ONE OF' code='A' path='Employee.age'>" +
|
157
|
+
"<value>30</value><value>31</value><value>32</value><value>33</value><value>34</value><value>35</value>" +
|
158
|
+
"</constraint>" +
|
159
|
+
"<constraint op='ONE OF' code='B' path='Employee.department.manager.name'>" +
|
160
|
+
"<value>zip</value><value>zop</value><value>zap</value>" +
|
161
|
+
"</constraint>" +
|
162
|
+
"<constraint op='ONE OF' code='C' path='Employee.age'>" +
|
163
|
+
"<value>35</value><value>36</value>" +
|
164
|
+
"</constraint>" +
|
165
|
+
"<constraint op='NONE OF' code='D' path='Employee.end'>" +
|
166
|
+
"<value>37</value><value>38</value><value>39</value>" +
|
167
|
+
"</constraint>" +
|
168
|
+
"<constraint op='ONE OF' code='E' path='Employee.age'>" +
|
169
|
+
"<value>1</value><value>2</value><value>3</value>" +
|
170
|
+
"</constraint>" +
|
171
|
+
"<constraint op='NONE OF' code='F' path='Employee.end'>" +
|
172
|
+
"<value>3</value><value>4</value><value>5</value>" +
|
173
|
+
"</constraint>" +
|
174
|
+
"<constraint op='NONE OF' code='G' path='Employee.department.manager.age'>" +
|
175
|
+
"<value>40</value><value>41</value><value>42</value><value>43</value><value>44</value><value>45</value>" +
|
176
|
+
"</constraint>" +
|
177
|
+
"<constraint op='ONE OF' code='H' path='Employee.department.manager.end'>" +
|
178
|
+
"<value>50</value><value>51</value><value>52</value><value>53</value><value>54</value><value>55</value>" +
|
179
|
+
"</constraint>" +
|
180
|
+
"<constraint op='NONE OF' code='I' path='Employee.department.manager.age'>" +
|
181
|
+
"<value>46</value><value>47</value>" +
|
182
|
+
"</constraint>" +
|
183
|
+
"<constraint op='ONE OF' code='J' path='Employee.department.manager.end'>" +
|
184
|
+
"<value>56</value><value>57</value>" +
|
185
|
+
"</constraint>" +
|
186
|
+
"</query>"
|
187
|
+
|
188
|
+
compare_xml(expected, q.to_xml)
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_sugary_loops
|
192
|
+
|
193
|
+
q = @model.table("Employee").
|
194
|
+
where("department.company.CEO" => {:is => "department.manager"}).
|
195
|
+
where("department.company.CEO" => {:is_not => "department.employees"})
|
196
|
+
|
197
|
+
expected = "<query model='testmodel' sortOrder='Employee.name ASC' view='Employee.name Employee.end Employee.id Employee.fullTime Employee.age'>" +
|
198
|
+
"<constraint op='=' loopPath='Employee.department.manager' code='A' path='Employee.department.company.CEO'/>" +
|
199
|
+
"<constraint op='!=' loopPath='Employee.department.employees' code='B' path='Employee.department.company.CEO'/>" +
|
200
|
+
"</query>"
|
201
|
+
|
202
|
+
compare_xml(expected, q.to_xml)
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_sugary_subclasses
|
206
|
+
manager = @model.table("Manager")
|
207
|
+
|
208
|
+
q = @model.table("Employee").
|
209
|
+
where("department.employees" => manager).
|
210
|
+
where("department.employees" => {:sub_class => "CEO"})
|
211
|
+
|
212
|
+
expected = "<query model='testmodel' sortOrder='Employee.name ASC' view='Employee.name Employee.end Employee.id Employee.fullTime Employee.age'>" +
|
213
|
+
"<constraint type='Manager' path='Employee.department.employees'/>" +
|
214
|
+
"<constraint type='CEO' path='Employee.department.employees'/>" +
|
215
|
+
"</query>"
|
216
|
+
|
217
|
+
compare_xml(expected, q.to_xml)
|
218
|
+
end
|
219
|
+
end
|