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
data/test/test_query.rb
ADDED
@@ -0,0 +1,1202 @@
|
|
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
|
+
|
7
|
+
require "test/unit"
|
8
|
+
|
9
|
+
|
10
|
+
class TestQuery < Test::Unit::TestCase
|
11
|
+
|
12
|
+
def initialize(name)
|
13
|
+
super
|
14
|
+
file = File.new(
|
15
|
+
File.dirname(__FILE__) + "/data/model.json", "r")
|
16
|
+
data = file.read
|
17
|
+
@model = InterMine::Metadata::Model.new(data)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_instantiation
|
21
|
+
query = InterMine::PathQuery::Query.new(@model)
|
22
|
+
assert(query.is_a?(PathQuery::Query))
|
23
|
+
|
24
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
25
|
+
assert_equal(query.root, @model.get_cd("Employee"))
|
26
|
+
|
27
|
+
query = InterMine::PathQuery::Query.new(@model, "Department.name")
|
28
|
+
assert_equal(query.root, @model.get_cd("Department"))
|
29
|
+
|
30
|
+
assert_raise InterMine::Metadata::PathException do
|
31
|
+
InterMine::PathQuery::Query.new(@model, "Foo")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_fully_qualified_views
|
36
|
+
views = [
|
37
|
+
"Employee.name",
|
38
|
+
"Employee.age",
|
39
|
+
"Employee.department.name"
|
40
|
+
]
|
41
|
+
expected = views.to_s
|
42
|
+
|
43
|
+
|
44
|
+
query = InterMine::PathQuery::Query.new(@model)
|
45
|
+
query.add_views("Employee.name", "Employee.age",
|
46
|
+
"Employee.department.name")
|
47
|
+
assert_equal(query.views.to_s, expected)
|
48
|
+
|
49
|
+
|
50
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
51
|
+
query.add_views("Employee.name", "Employee.age",
|
52
|
+
"Employee.department.name")
|
53
|
+
assert_equal(query.views.to_s, expected)
|
54
|
+
|
55
|
+
query = InterMine::PathQuery::Query.new(@model)
|
56
|
+
query.add_views(views)
|
57
|
+
assert_equal(query.views.to_s, expected)
|
58
|
+
|
59
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
60
|
+
query.add_views(views)
|
61
|
+
assert_equal(query.views.to_s, expected)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_bad_viewpath
|
65
|
+
query = InterMine::PathQuery::Query.new(@model)
|
66
|
+
assert_raise InterMine::Metadata::PathException do
|
67
|
+
query.add_views("Employee.foo.id")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_inconsistent_view_roots
|
72
|
+
query = InterMine::PathQuery::Query.new(@model)
|
73
|
+
assert_raise InterMine::Metadata::PathException do
|
74
|
+
query.add_views("Employee.name")
|
75
|
+
query.add_views("Department.name")
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_unqualified_views
|
81
|
+
views = [
|
82
|
+
"Employee.name",
|
83
|
+
"Employee.age",
|
84
|
+
"Employee.department.name"
|
85
|
+
]
|
86
|
+
expected = views.to_s
|
87
|
+
|
88
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
89
|
+
query.add_views("name", "age", "department.name")
|
90
|
+
assert_equal(query.views.to_s, expected)
|
91
|
+
|
92
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
93
|
+
query.add_views(["name", "age", "department.name"])
|
94
|
+
assert_equal(query.views.to_s, expected)
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_bad_unqualified_path
|
98
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
99
|
+
assert_raise InterMine::Metadata::PathException do
|
100
|
+
query.add_views("foo.id")
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_inconsistent_views_with_rooted_query
|
105
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
106
|
+
assert_raise InterMine::Metadata::PathException do
|
107
|
+
query.add_views("Department.id")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_subclasses
|
112
|
+
query = InterMine::PathQuery::Query.new(@model)
|
113
|
+
query.add_constraint({
|
114
|
+
:path => "Department.employees",
|
115
|
+
:sub_class => "Manager"
|
116
|
+
})
|
117
|
+
query.add_constraint({
|
118
|
+
:path => "Department.company.departments.employees",
|
119
|
+
:sub_class => "Manager"
|
120
|
+
})
|
121
|
+
expected = {
|
122
|
+
"Department.employees" => "Manager",
|
123
|
+
"Department.company.departments.employees" => "Manager"
|
124
|
+
}
|
125
|
+
assert_equal(expected, query.subclasses)
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_problem_subclasses
|
129
|
+
query = InterMine::PathQuery::Query.new(@model)
|
130
|
+
assert_raise InterMine::Metadata::PathException do
|
131
|
+
query.add_constraint({
|
132
|
+
:path => "Department.employees",
|
133
|
+
:sub_class => "Foo"
|
134
|
+
})
|
135
|
+
end
|
136
|
+
|
137
|
+
query = InterMine::PathQuery::Query.new(@model)
|
138
|
+
assert_raise ArgumentError do
|
139
|
+
query.add_constraint({
|
140
|
+
:path => "Department.employees",
|
141
|
+
:sub_class => "Company"
|
142
|
+
})
|
143
|
+
end
|
144
|
+
|
145
|
+
query = InterMine::PathQuery::Query.new(@model)
|
146
|
+
assert_raise ArgumentError do
|
147
|
+
query.add_constraint({
|
148
|
+
:path => "Department.manager",
|
149
|
+
:sub_class => "Company.departments.employees"
|
150
|
+
})
|
151
|
+
end
|
152
|
+
|
153
|
+
query = InterMine::PathQuery::Query.new(@model)
|
154
|
+
assert_raise ArgumentError do
|
155
|
+
query.add_constraint({
|
156
|
+
:path => "Department.manager",
|
157
|
+
:sub_class => "Employee"
|
158
|
+
})
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_subclassed_views
|
163
|
+
query = InterMine::PathQuery::Query.new(@model)
|
164
|
+
query.add_constraint({
|
165
|
+
:path => "Department.employees",
|
166
|
+
:sub_class => "Manager"
|
167
|
+
})
|
168
|
+
query.add_views("Department.employees.seniority")
|
169
|
+
expected = ["Department.employees.seniority"].to_s
|
170
|
+
assert_equal(query.views.to_s, expected)
|
171
|
+
|
172
|
+
query = InterMine::PathQuery::Query.new(@model)
|
173
|
+
assert_raise InterMine::Metadata::PathException do
|
174
|
+
query.add_views("Department.employees.seniority")
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_joins
|
179
|
+
query = InterMine::PathQuery::Query.new(@model)
|
180
|
+
query.add_join("Department.employees", "OUTER")
|
181
|
+
join = query.joins.first
|
182
|
+
assert_equal(join.path.to_s, "Department.employees")
|
183
|
+
assert_equal(join.style, "OUTER")
|
184
|
+
assert_equal(query.root.name, "Department")
|
185
|
+
|
186
|
+
query = InterMine::PathQuery::Query.new(@model)
|
187
|
+
query.add_join("Department.employees")
|
188
|
+
join = query.joins.first
|
189
|
+
assert_equal(join.path.to_s, "Department.employees")
|
190
|
+
assert_equal(join.style, "OUTER")
|
191
|
+
|
192
|
+
query = InterMine::PathQuery::Query.new(@model, "Department")
|
193
|
+
query.add_join("employees")
|
194
|
+
join = query.joins.first
|
195
|
+
assert_equal(join.path.to_s, "Department.employees")
|
196
|
+
assert_equal(join.style, "OUTER")
|
197
|
+
|
198
|
+
query = InterMine::PathQuery::Query.new(@model)
|
199
|
+
query.add_join("Department.employees", "INNER")
|
200
|
+
join = query.joins.first
|
201
|
+
assert_equal(join.path.to_s, "Department.employees")
|
202
|
+
assert_equal(join.style, "INNER")
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_subclassed_joins
|
206
|
+
|
207
|
+
query = InterMine::PathQuery::Query.new(@model, "Department")
|
208
|
+
|
209
|
+
query.add_constraint({:path => "employees", :sub_class => "CEO"})
|
210
|
+
query.add_join("employees.secretarys")
|
211
|
+
|
212
|
+
assert_equal(query.joins.first.path.to_s, "Department.employees.secretarys")
|
213
|
+
assert_equal(query.joins.first.style, "OUTER")
|
214
|
+
|
215
|
+
query = InterMine::PathQuery::Query.new(@model, "Department")
|
216
|
+
assert_raise InterMine::Metadata::PathException do
|
217
|
+
query.add_join("employees.secretarys")
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_join_problems
|
222
|
+
|
223
|
+
query = InterMine::PathQuery::Query.new(@model)
|
224
|
+
assert_raise InterMine::Metadata::PathException do
|
225
|
+
query.add_join("Foo.employees")
|
226
|
+
end
|
227
|
+
|
228
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
229
|
+
assert_raise InterMine::Metadata::PathException do
|
230
|
+
query.add_join("Department.employees")
|
231
|
+
end
|
232
|
+
|
233
|
+
query = InterMine::PathQuery::Query.new(@model)
|
234
|
+
assert_raise ArgumentError do
|
235
|
+
query.add_join("Department.employees", "QUIRKY")
|
236
|
+
end
|
237
|
+
|
238
|
+
query = InterMine::PathQuery::Query.new(@model)
|
239
|
+
assert_raise InterMine::Metadata::PathException do
|
240
|
+
query.add_join("Department.employees")
|
241
|
+
query.add_join("Company.departments")
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_unary_constraints
|
246
|
+
query = InterMine::PathQuery::Query.new(@model)
|
247
|
+
query.add_constraint({
|
248
|
+
:path => "Employee.name",
|
249
|
+
:op => "IS NULL"
|
250
|
+
})
|
251
|
+
query.add_constraint({
|
252
|
+
:path => "Employee.department",
|
253
|
+
:op => "IS NOT NULL"
|
254
|
+
})
|
255
|
+
conA = query.constraints[0]
|
256
|
+
conB = query.constraints[1]
|
257
|
+
|
258
|
+
query = InterMine::PathQuery::Query.new(@model)
|
259
|
+
query.add_constraint(
|
260
|
+
:path => "Employee.name",
|
261
|
+
:op => "IS NULL"
|
262
|
+
)
|
263
|
+
query.add_constraint(
|
264
|
+
:path => "Employee.department",
|
265
|
+
:op => "IS NOT NULL"
|
266
|
+
)
|
267
|
+
conA = query.constraints[0]
|
268
|
+
conB = query.constraints[1]
|
269
|
+
|
270
|
+
assert_equal(conA.path.to_s, "Employee.name")
|
271
|
+
assert_equal(conB.path.to_s, "Employee.department")
|
272
|
+
|
273
|
+
assert_equal(conA.op, "IS NULL")
|
274
|
+
assert_equal(conB.op, "IS NOT NULL")
|
275
|
+
end
|
276
|
+
|
277
|
+
def test_unqualified_unary_constraint
|
278
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
279
|
+
query.add_constraint(
|
280
|
+
:path => "name",
|
281
|
+
:op => "IS NULL"
|
282
|
+
)
|
283
|
+
|
284
|
+
conA = query.constraints[0]
|
285
|
+
assert_equal(conA.path.to_s, "Employee.name")
|
286
|
+
assert_equal(conA.op, "IS NULL")
|
287
|
+
|
288
|
+
end
|
289
|
+
|
290
|
+
def test_bad_unary_constraint
|
291
|
+
query = InterMine::PathQuery::Query.new(@model)
|
292
|
+
assert_raise ArgumentError do
|
293
|
+
query.add_constraint(
|
294
|
+
:path => "name",
|
295
|
+
:op => "IS MAYBE NULL"
|
296
|
+
)
|
297
|
+
end
|
298
|
+
|
299
|
+
query = InterMine::PathQuery::Query.new(@model)
|
300
|
+
assert_raise InterMine::Metadata::PathException do
|
301
|
+
query.add_constraint({
|
302
|
+
:path => "Company.foo",
|
303
|
+
:op => "IS NULL"
|
304
|
+
})
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
def test_binary_constraints
|
309
|
+
query = InterMine::PathQuery::Query.new(@model)
|
310
|
+
query.add_constraint({
|
311
|
+
:path => "Employee.name",
|
312
|
+
:op => "=",
|
313
|
+
:value => "foo"
|
314
|
+
})
|
315
|
+
query.add_constraint({
|
316
|
+
:path => "Employee.department.name",
|
317
|
+
:op => "!=",
|
318
|
+
:value => "foo"
|
319
|
+
})
|
320
|
+
query.add_constraint({
|
321
|
+
:path => "Employee.age",
|
322
|
+
:op => ">",
|
323
|
+
:value => 1
|
324
|
+
})
|
325
|
+
query.add_constraint({
|
326
|
+
:path => "Employee.fullTime",
|
327
|
+
:op => "<",
|
328
|
+
:value => false
|
329
|
+
})
|
330
|
+
conA = query.constraints[0]
|
331
|
+
conB = query.constraints[1]
|
332
|
+
conC = query.constraints[2]
|
333
|
+
conD = query.constraints[3]
|
334
|
+
|
335
|
+
assert_equal(conA.path.to_s, "Employee.name")
|
336
|
+
assert_equal(conB.path.to_s, "Employee.department.name")
|
337
|
+
assert_equal(conC.path.to_s, "Employee.age")
|
338
|
+
assert_equal(conD.path.to_s, "Employee.fullTime")
|
339
|
+
|
340
|
+
assert_equal(conA.op, "=")
|
341
|
+
assert_equal(conB.op, "!=")
|
342
|
+
assert_equal(conC.op, ">")
|
343
|
+
assert_equal(conD.op, "<")
|
344
|
+
|
345
|
+
assert_equal(conA.value, "foo")
|
346
|
+
assert_equal(conB.value, "foo")
|
347
|
+
assert_equal(conC.value, 1)
|
348
|
+
assert_equal(conD.value, false)
|
349
|
+
end
|
350
|
+
|
351
|
+
def test_value_coercion
|
352
|
+
query = InterMine::PathQuery::Query.new(@model)
|
353
|
+
query.add_constraint({
|
354
|
+
:path => "Employee.age",
|
355
|
+
:op => ">",
|
356
|
+
:value => "1"
|
357
|
+
})
|
358
|
+
query.add_constraint({
|
359
|
+
:path => "Employee.fullTime",
|
360
|
+
:op => "<",
|
361
|
+
:value => "false"
|
362
|
+
})
|
363
|
+
conA = query.constraints[0]
|
364
|
+
conB = query.constraints[1]
|
365
|
+
|
366
|
+
assert_equal(conA.path.to_s, "Employee.age")
|
367
|
+
assert_equal(conB.path.to_s, "Employee.fullTime")
|
368
|
+
|
369
|
+
assert_equal(conA.op, ">")
|
370
|
+
assert_equal(conB.op, "<")
|
371
|
+
|
372
|
+
assert_equal(conA.value, 1)
|
373
|
+
assert_equal(conB.value, false)
|
374
|
+
end
|
375
|
+
|
376
|
+
def test_unqualified_binary_constraint
|
377
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
378
|
+
query.add_constraint({
|
379
|
+
:path => "name",
|
380
|
+
:op => ">=",
|
381
|
+
:value => "foo"
|
382
|
+
})
|
383
|
+
|
384
|
+
conA = query.constraints[0]
|
385
|
+
assert_equal(conA.path.to_s, "Employee.name")
|
386
|
+
assert_equal(conA.op, ">=")
|
387
|
+
assert_equal(conA.value, "foo")
|
388
|
+
|
389
|
+
end
|
390
|
+
|
391
|
+
def test_bad_binary_constraint
|
392
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
393
|
+
assert_raise ArgumentError do
|
394
|
+
query.add_constraint({
|
395
|
+
:path => "name",
|
396
|
+
:op => "===",
|
397
|
+
:value => "foo"
|
398
|
+
})
|
399
|
+
end
|
400
|
+
|
401
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
402
|
+
assert_raise ArgumentError do
|
403
|
+
query.add_constraint({
|
404
|
+
:path => "age",
|
405
|
+
:op => "<",
|
406
|
+
:value => "foo"
|
407
|
+
})
|
408
|
+
end
|
409
|
+
|
410
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
411
|
+
assert_raise ArgumentError do
|
412
|
+
query.add_constraint({
|
413
|
+
:path => "fullTime",
|
414
|
+
:op => "=",
|
415
|
+
:value => "foo"
|
416
|
+
})
|
417
|
+
end
|
418
|
+
|
419
|
+
query = InterMine::PathQuery::Query.new(@model)
|
420
|
+
assert_raise InterMine::Metadata::PathException do
|
421
|
+
query.add_constraint({
|
422
|
+
:path => "Company.foo",
|
423
|
+
:op => ">=",
|
424
|
+
:value => "foo"
|
425
|
+
})
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
def test_list_constraints
|
430
|
+
query = InterMine::PathQuery::Query.new(@model)
|
431
|
+
query.add_constraint({
|
432
|
+
:path => "Employee",
|
433
|
+
:op => "IN",
|
434
|
+
:value => "foo"
|
435
|
+
})
|
436
|
+
query.add_constraint({
|
437
|
+
:path => "Employee.department",
|
438
|
+
:op => "NOT IN",
|
439
|
+
:value => "foo"
|
440
|
+
})
|
441
|
+
conA = query.constraints[0]
|
442
|
+
conB = query.constraints[1]
|
443
|
+
|
444
|
+
assert_equal(conA.path.to_s, "Employee")
|
445
|
+
assert_equal(conB.path.to_s, "Employee.department")
|
446
|
+
|
447
|
+
assert_equal(conA.op, "IN")
|
448
|
+
assert_equal(conB.op, "NOT IN")
|
449
|
+
|
450
|
+
assert_equal(conA.value, "foo")
|
451
|
+
assert_equal(conB.value, "foo")
|
452
|
+
end
|
453
|
+
|
454
|
+
def test_unqualified_list_constraint
|
455
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
456
|
+
query.add_constraint({
|
457
|
+
:path => "department",
|
458
|
+
:op => "IN",
|
459
|
+
:value => "foo"
|
460
|
+
})
|
461
|
+
|
462
|
+
conA = query.constraints[0]
|
463
|
+
assert_equal(conA.path.to_s, "Employee.department")
|
464
|
+
assert_equal(conA.op, "IN")
|
465
|
+
assert_equal(conA.value, "foo")
|
466
|
+
end
|
467
|
+
|
468
|
+
def test_bad_list_constraint
|
469
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
470
|
+
assert_raise ArgumentError do
|
471
|
+
query.add_constraint({
|
472
|
+
:path => "department.name",
|
473
|
+
:op => "IN",
|
474
|
+
:value => "foo"
|
475
|
+
})
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
def test_lookup_constraints
|
480
|
+
query = InterMine::PathQuery::Query.new(@model)
|
481
|
+
query.add_constraint({
|
482
|
+
:path => "Employee",
|
483
|
+
:op => "LOOKUP",
|
484
|
+
:value => "foo"
|
485
|
+
})
|
486
|
+
query.add_constraint({
|
487
|
+
:path => "Employee.department",
|
488
|
+
:op => "LOOKUP",
|
489
|
+
:value => "foo",
|
490
|
+
:extra_value => "bar"
|
491
|
+
})
|
492
|
+
conA = query.constraints[0]
|
493
|
+
conB = query.constraints[1]
|
494
|
+
|
495
|
+
assert_equal(conA.path.to_s, "Employee")
|
496
|
+
assert_equal(conB.path.to_s, "Employee.department")
|
497
|
+
|
498
|
+
assert_equal(conA.op, "LOOKUP")
|
499
|
+
assert_equal(conB.op, "LOOKUP")
|
500
|
+
|
501
|
+
assert_equal(conA.value, "foo")
|
502
|
+
assert_equal(conB.value, "foo")
|
503
|
+
|
504
|
+
assert_equal(conA.extra_value, nil)
|
505
|
+
assert_equal(conB.extra_value, "bar")
|
506
|
+
end
|
507
|
+
|
508
|
+
def test_unqualified_lookup_constraint
|
509
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
510
|
+
query.add_constraint({
|
511
|
+
:path => "department",
|
512
|
+
:op => "LOOKUP",
|
513
|
+
:value => "foo"
|
514
|
+
})
|
515
|
+
|
516
|
+
conA = query.constraints[0]
|
517
|
+
assert_equal(conA.path.to_s, "Employee.department")
|
518
|
+
assert_equal(conA.op, "LOOKUP")
|
519
|
+
assert_equal(conA.value, "foo")
|
520
|
+
end
|
521
|
+
|
522
|
+
def test_bad_lookup_constraint
|
523
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
524
|
+
assert_raise ArgumentError do
|
525
|
+
query.add_constraint({
|
526
|
+
:path => "department.name",
|
527
|
+
:op => "LOOKUP",
|
528
|
+
:value => "foo"
|
529
|
+
})
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
533
|
+
def test_loop_constraints
|
534
|
+
query = InterMine::PathQuery::Query.new(@model)
|
535
|
+
query.add_constraint({
|
536
|
+
:path => "Employee",
|
537
|
+
:op => "IS",
|
538
|
+
:loopPath => "Employee.department.manager"
|
539
|
+
})
|
540
|
+
query.add_constraint({
|
541
|
+
:path => "Employee.department",
|
542
|
+
:op => "IS NOT",
|
543
|
+
:loopPath => "Employee.department.company.departments"
|
544
|
+
})
|
545
|
+
conA = query.constraints[0]
|
546
|
+
conB = query.constraints[1]
|
547
|
+
|
548
|
+
assert_equal(conA.path.to_s, "Employee")
|
549
|
+
assert_equal(conB.path.to_s, "Employee.department")
|
550
|
+
|
551
|
+
assert_equal(conA.op, "IS")
|
552
|
+
assert_equal(conB.op, "IS NOT")
|
553
|
+
|
554
|
+
assert_equal(conA.loopPath.to_s, "Employee.department.manager")
|
555
|
+
assert_equal(conB.loopPath.to_s, "Employee.department.company.departments")
|
556
|
+
|
557
|
+
end
|
558
|
+
|
559
|
+
def test_unqualified_loop_constraint
|
560
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
561
|
+
query.add_constraint({
|
562
|
+
:path => "department",
|
563
|
+
:op => "IS",
|
564
|
+
:loopPath => "department.company.departments"
|
565
|
+
})
|
566
|
+
|
567
|
+
conA = query.constraints[0]
|
568
|
+
assert_equal(conA.path.to_s, "Employee.department")
|
569
|
+
assert_equal(conA.op, "IS")
|
570
|
+
assert_equal(conA.loopPath.to_s, "Employee.department.company.departments")
|
571
|
+
end
|
572
|
+
|
573
|
+
def test_bad_lookup_constraint
|
574
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
575
|
+
assert_raise ArgumentError do
|
576
|
+
query.add_constraint({
|
577
|
+
:path => "name",
|
578
|
+
:op => "IS",
|
579
|
+
:loopPath => "department.manager"
|
580
|
+
})
|
581
|
+
end
|
582
|
+
|
583
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
584
|
+
assert_raise ArgumentError do
|
585
|
+
query.add_constraint({
|
586
|
+
:path => "Employee",
|
587
|
+
:op => "IS",
|
588
|
+
:loopPath => "department.manager.name"
|
589
|
+
})
|
590
|
+
end
|
591
|
+
|
592
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
593
|
+
assert_raise ArgumentError do
|
594
|
+
query.add_constraint({
|
595
|
+
:path => "Employee",
|
596
|
+
:op => "IS",
|
597
|
+
:loopPath => "department"
|
598
|
+
})
|
599
|
+
end
|
600
|
+
end
|
601
|
+
|
602
|
+
def test_multi_constraints
|
603
|
+
query = InterMine::PathQuery::Query.new(@model)
|
604
|
+
query.add_constraint({
|
605
|
+
:path => "Employee.name",
|
606
|
+
:op => "ONE OF",
|
607
|
+
:values => %w{foo bar baz}
|
608
|
+
})
|
609
|
+
|
610
|
+
query.add_constraint({
|
611
|
+
:path => "Employee.age",
|
612
|
+
:op => "NONE OF",
|
613
|
+
:values => [1, 2, 3]
|
614
|
+
})
|
615
|
+
|
616
|
+
conA = query.constraints[0]
|
617
|
+
conB = query.constraints[1]
|
618
|
+
|
619
|
+
assert_equal(conA.path.to_s, "Employee.name")
|
620
|
+
assert_equal(conB.path.to_s, "Employee.age")
|
621
|
+
|
622
|
+
assert_equal(conA.op, "ONE OF")
|
623
|
+
assert_equal(conB.op, "NONE OF")
|
624
|
+
|
625
|
+
assert_equal(conA.values, ["foo", "bar", "baz"])
|
626
|
+
assert_equal(conB.values, [1, 2, 3])
|
627
|
+
end
|
628
|
+
|
629
|
+
def test_unqualified_multi_constraint
|
630
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
631
|
+
query.add_constraint({
|
632
|
+
:path => "department.name",
|
633
|
+
:op => "ONE OF",
|
634
|
+
:values => %w{Sales Marketing Janitorial}
|
635
|
+
})
|
636
|
+
|
637
|
+
conA = query.constraints[0]
|
638
|
+
assert_equal(conA.path.to_s, "Employee.department.name")
|
639
|
+
assert_equal(conA.op, "ONE OF")
|
640
|
+
assert_equal(conA.values, %w{Sales Marketing Janitorial})
|
641
|
+
end
|
642
|
+
|
643
|
+
def test_bad_multi_constraint
|
644
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
645
|
+
assert_raise ArgumentError do
|
646
|
+
query.add_constraint({
|
647
|
+
:path => "name",
|
648
|
+
:op => "ONE OF",
|
649
|
+
:value => "foo"
|
650
|
+
})
|
651
|
+
end
|
652
|
+
|
653
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
654
|
+
assert_raise ArgumentError do
|
655
|
+
query.add_constraint({
|
656
|
+
:path => "Employee",
|
657
|
+
:op => "ONE OF",
|
658
|
+
:values => ["foo", "bar", "baz"]
|
659
|
+
})
|
660
|
+
end
|
661
|
+
|
662
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
663
|
+
assert_raise ArgumentError do
|
664
|
+
query.add_constraint({
|
665
|
+
:path => "Employee.age",
|
666
|
+
:op => "ONE OF",
|
667
|
+
:values => [1, 2, 3, "foo", 5]
|
668
|
+
})
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
672
|
+
def test_codes
|
673
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
674
|
+
# Check allocation of default codes
|
675
|
+
query.add_constraint({
|
676
|
+
:path => "name",
|
677
|
+
:op => "=",
|
678
|
+
:value => "foo"
|
679
|
+
})
|
680
|
+
|
681
|
+
# Check that subclass constraints don't get codes
|
682
|
+
query.add_constraint({
|
683
|
+
:path => "department.employees",
|
684
|
+
:sub_class => "Manager"
|
685
|
+
})
|
686
|
+
|
687
|
+
# Check default code is next available
|
688
|
+
query.add_constraint({
|
689
|
+
:path => "name",
|
690
|
+
:op => "IS NOT NULL"
|
691
|
+
})
|
692
|
+
|
693
|
+
# Check allocation of custom codes
|
694
|
+
query.add_constraint({
|
695
|
+
:path => "name",
|
696
|
+
:op => "IS NOT NULL",
|
697
|
+
:code => "Q"
|
698
|
+
})
|
699
|
+
|
700
|
+
# Check that we remember allocation of default codes
|
701
|
+
query.add_constraint({
|
702
|
+
:path => "name",
|
703
|
+
:op => "IS NOT NULL",
|
704
|
+
:code => "A"
|
705
|
+
})
|
706
|
+
|
707
|
+
# Check that we remember allocation of custom codes
|
708
|
+
query.add_constraint({
|
709
|
+
:path => "name",
|
710
|
+
:op => "IS NOT NULL",
|
711
|
+
:code => "Q"
|
712
|
+
})
|
713
|
+
|
714
|
+
codes = query.constraints.map { |x|
|
715
|
+
# Filter out subclass codes
|
716
|
+
begin
|
717
|
+
x.code
|
718
|
+
rescue
|
719
|
+
nil
|
720
|
+
end
|
721
|
+
}
|
722
|
+
assert_equal(["A", nil, "B", "Q", "C", "D"], codes)
|
723
|
+
end
|
724
|
+
|
725
|
+
def test_code_exhaustion
|
726
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
727
|
+
# Check we can allocate all 26 default codes
|
728
|
+
assert_nothing_raised do
|
729
|
+
26.times do
|
730
|
+
query.add_constraint({
|
731
|
+
:path => "name",
|
732
|
+
:op => "IS NOT NULL"
|
733
|
+
})
|
734
|
+
end
|
735
|
+
end
|
736
|
+
assert_equal(query.constraints.first.code, "A")
|
737
|
+
assert_equal(query.constraints.last.code, "Z")
|
738
|
+
|
739
|
+
# But 27 is too many
|
740
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
741
|
+
assert_raise RuntimeError do
|
742
|
+
27.times do
|
743
|
+
query.add_constraint({
|
744
|
+
:path => "name",
|
745
|
+
:op => "IS NOT NULL"
|
746
|
+
})
|
747
|
+
end
|
748
|
+
end
|
749
|
+
|
750
|
+
# One more tips the balance, even with a custom code
|
751
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
752
|
+
assert_raise RuntimeError do
|
753
|
+
26.times do
|
754
|
+
query.add_constraint({
|
755
|
+
:path => "name",
|
756
|
+
:op => "IS NOT NULL"
|
757
|
+
})
|
758
|
+
end
|
759
|
+
query.add_constraint({
|
760
|
+
:path => "name",
|
761
|
+
:op => "IS NOT NULL",
|
762
|
+
:code => "Z"
|
763
|
+
})
|
764
|
+
end
|
765
|
+
end
|
766
|
+
|
767
|
+
def test_illegal_codes
|
768
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
769
|
+
assert_raise ArgumentError do
|
770
|
+
query.add_constraint({
|
771
|
+
:path => "name",
|
772
|
+
:op => "IS NOT NULL",
|
773
|
+
:code => "a"
|
774
|
+
})
|
775
|
+
end
|
776
|
+
|
777
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
778
|
+
assert_raise ArgumentError do
|
779
|
+
query.add_constraint({
|
780
|
+
:path => "name",
|
781
|
+
:op => "IS NOT NULL",
|
782
|
+
:code => "AA"
|
783
|
+
})
|
784
|
+
end
|
785
|
+
|
786
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
787
|
+
assert_raise ArgumentError do
|
788
|
+
query.add_constraint({
|
789
|
+
:path => "name",
|
790
|
+
:op => "IS NOT NULL",
|
791
|
+
:code => "Ä"
|
792
|
+
})
|
793
|
+
end
|
794
|
+
end
|
795
|
+
|
796
|
+
def test_subclassed_constraints
|
797
|
+
|
798
|
+
query = InterMine::PathQuery::Query.new(@model, "Department")
|
799
|
+
|
800
|
+
query.add_constraint({:path => "employees", :sub_class => "Manager"})
|
801
|
+
query.add_constraint({:path => "employees.title", :op => "=", :value => "Ms"})
|
802
|
+
|
803
|
+
assert_equal(query.constraints.last.path.to_s, "Department.employees.title")
|
804
|
+
assert_equal(query.constraints.last.op, "=")
|
805
|
+
assert_equal(query.constraints.last.value, "Ms")
|
806
|
+
assert_equal(query.constraints.last.code, "A")
|
807
|
+
|
808
|
+
query = InterMine::PathQuery::Query.new(@model, "Department")
|
809
|
+
assert_raise InterMine::Metadata::PathException do
|
810
|
+
query.add_constraint({:path => "employees.title", :op => "=", :value => "Ms"})
|
811
|
+
end
|
812
|
+
end
|
813
|
+
|
814
|
+
def test_sort_order
|
815
|
+
|
816
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
817
|
+
|
818
|
+
query.add_views("name", "age", "end")
|
819
|
+
|
820
|
+
query.add_sort_order("name", "ASC")
|
821
|
+
|
822
|
+
assert_equal(query.sort_order.first.path, "Employee.name")
|
823
|
+
assert_equal(query.sort_order.first.direction, "ASC")
|
824
|
+
|
825
|
+
query.add_sort_order("age")
|
826
|
+
|
827
|
+
assert_equal(query.sort_order.last.path, "Employee.age")
|
828
|
+
assert_equal(query.sort_order.last.direction, "ASC")
|
829
|
+
|
830
|
+
query.add_sort_order("end", "DESC")
|
831
|
+
|
832
|
+
assert_equal(query.sort_order.last.path, "Employee.end")
|
833
|
+
assert_equal(query.sort_order.last.direction, "DESC")
|
834
|
+
|
835
|
+
assert_raise InterMine::Metadata::PathException do
|
836
|
+
query.add_sort_order("foo")
|
837
|
+
end
|
838
|
+
|
839
|
+
assert_raise ArgumentError do
|
840
|
+
query.add_sort_order("name", "FORWARDS")
|
841
|
+
end
|
842
|
+
|
843
|
+
assert_raise ArgumentError do
|
844
|
+
query.add_sort_order("department.name")
|
845
|
+
end
|
846
|
+
|
847
|
+
query.add_sort_order("name", "desc")
|
848
|
+
|
849
|
+
assert_equal(query.sort_order.last.path, "Employee.name")
|
850
|
+
assert_equal(query.sort_order.last.direction, "DESC")
|
851
|
+
end
|
852
|
+
|
853
|
+
def test_subclassed_sort_order
|
854
|
+
|
855
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
856
|
+
|
857
|
+
query.add_constraint(:path => "Employee", :sub_class => "Manager")
|
858
|
+
query.add_views(%w{name age fullTime title})
|
859
|
+
query.add_sort_order("title")
|
860
|
+
|
861
|
+
assert_equal(query.sort_order.first.path, "Employee.title")
|
862
|
+
|
863
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
864
|
+
assert_raise InterMine::Metadata::PathException do
|
865
|
+
query.add_sort_order("title")
|
866
|
+
end
|
867
|
+
end
|
868
|
+
|
869
|
+
def test_logic
|
870
|
+
|
871
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
872
|
+
|
873
|
+
5.times do
|
874
|
+
query.add_constraint(:path => "name", :op => "=", :value => "foo")
|
875
|
+
end
|
876
|
+
|
877
|
+
query.set_logic("A and B and C and D and E")
|
878
|
+
assert_equal("A and B and C and D and E", query.logic.to_s)
|
879
|
+
|
880
|
+
query.set_logic("A&B&C&D&E")
|
881
|
+
assert_equal("A and B and C and D and E", query.logic.to_s)
|
882
|
+
|
883
|
+
query.set_logic("A|B|C|D|E")
|
884
|
+
assert_equal("A or B or C or D or E", query.logic.to_s)
|
885
|
+
|
886
|
+
query.set_logic("A and B or C and D or E")
|
887
|
+
assert_equal("A and (B or C) and (D or E)", query.logic.to_s)
|
888
|
+
|
889
|
+
query.set_logic("A and (B or (C and (D or E)))")
|
890
|
+
assert_equal("A and (B or (C and (D or E)))", query.logic.to_s)
|
891
|
+
|
892
|
+
query.set_logic("(((A and B) and C) and D) and E")
|
893
|
+
assert_equal("A and B and C and D and E", query.logic.to_s)
|
894
|
+
|
895
|
+
query.set_logic("A and B | (C or D) and E")
|
896
|
+
assert_equal("A and (B or C or D) and E", query.logic.to_s)
|
897
|
+
|
898
|
+
query.set_logic("A or B or (C and D) and E")
|
899
|
+
assert_equal("(A or B or (C and D)) and E", query.logic.to_s)
|
900
|
+
|
901
|
+
query.set_logic("A or B or (C and D and E)")
|
902
|
+
assert_equal("A or B or (C and D and E)", query.logic.to_s)
|
903
|
+
|
904
|
+
assert_raise InterMine::PathQuery::LogicParseError do
|
905
|
+
query.set_logic("A B | (C or D) and E")
|
906
|
+
end
|
907
|
+
|
908
|
+
assert_raise InterMine::PathQuery::LogicParseError do
|
909
|
+
query.set_logic("A ( B and C)")
|
910
|
+
end
|
911
|
+
|
912
|
+
assert_raise InterMine::PathQuery::LogicParseError do
|
913
|
+
query.set_logic("A or B and C)")
|
914
|
+
end
|
915
|
+
|
916
|
+
assert_raise InterMine::PathQuery::LogicParseError do
|
917
|
+
query.set_logic("A or (B and C")
|
918
|
+
end
|
919
|
+
end
|
920
|
+
|
921
|
+
def test_query_element_xml
|
922
|
+
|
923
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
924
|
+
query.add_views("name", "age", "fullTime", "department.name")
|
925
|
+
|
926
|
+
expected = "<query model='testmodel' view='Employee.name Employee.age Employee.fullTime Employee.department.name' sortOrder='Employee.name ASC'/>"
|
927
|
+
|
928
|
+
compare_xml(expected, query.to_xml)
|
929
|
+
|
930
|
+
query.title = "Ruby Query"
|
931
|
+
query.add_sort_order("age", "desc")
|
932
|
+
|
933
|
+
expected = "<query model='testmodel' title='Ruby Query' view='Employee.name Employee.age Employee.fullTime Employee.department.name' sortOrder='Employee.age DESC'/>"
|
934
|
+
compare_xml(expected, query.to_xml)
|
935
|
+
|
936
|
+
query.add_sort_order("name")
|
937
|
+
expected = "<query model='testmodel' title='Ruby Query' view='Employee.name Employee.age Employee.fullTime Employee.department.name' sortOrder='Employee.age DESC Employee.name ASC'/>"
|
938
|
+
compare_xml(expected, query.to_xml)
|
939
|
+
|
940
|
+
end
|
941
|
+
|
942
|
+
def test_constraint_xml
|
943
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
944
|
+
query.add_views("name", "age", "fullTime", "department.name")
|
945
|
+
|
946
|
+
query.add_constraint({:path => "department", :op => "IS NOT NULL"})
|
947
|
+
query.add_constraint({
|
948
|
+
:path => "name",
|
949
|
+
:op => "<",
|
950
|
+
:value => "foo"
|
951
|
+
})
|
952
|
+
query.add_constraint({
|
953
|
+
:path => "age",
|
954
|
+
:op => "ONE OF",
|
955
|
+
:values => [17, 23, 37]
|
956
|
+
})
|
957
|
+
query.add_constraint({
|
958
|
+
:path => "Employee",
|
959
|
+
:op => "IN",
|
960
|
+
:value => "bar"
|
961
|
+
})
|
962
|
+
query.add_constraint({
|
963
|
+
:path => "Employee",
|
964
|
+
:op => "IS",
|
965
|
+
:loopPath => "department.manager"
|
966
|
+
})
|
967
|
+
query.add_constraint({
|
968
|
+
:path => "Employee",
|
969
|
+
:op => "LOOKUP",
|
970
|
+
:value => "quux"
|
971
|
+
})
|
972
|
+
query.add_constraint({
|
973
|
+
:path => "Employee",
|
974
|
+
:op => "LOOKUP",
|
975
|
+
:value => "zop",
|
976
|
+
:extra_value => "zip"
|
977
|
+
})
|
978
|
+
query.add_constraint({
|
979
|
+
:path => "Employee",
|
980
|
+
:sub_class => "Manager"
|
981
|
+
})
|
982
|
+
query.add_views("title")
|
983
|
+
|
984
|
+
expected = "<query model='testmodel' view='Employee.name Employee.age Employee.fullTime Employee.department.name Employee.title' sortOrder='Employee.name ASC'>" +
|
985
|
+
"<constraint type='Manager' path='Employee'/>" +
|
986
|
+
"<constraint op='IS NOT NULL' code='A' path='Employee.department'/>" +
|
987
|
+
"<constraint op='<' code='B' value='foo' path='Employee.name'/>" +
|
988
|
+
"<constraint op='ONE OF' code='C' path='Employee.age'>" +
|
989
|
+
"<value>17</value><value>23</value><value>37</value>" +
|
990
|
+
"</constraint>" +
|
991
|
+
"<constraint op='IN' code='D' value='bar' path='Employee'/>" +
|
992
|
+
"<constraint loopPath='Employee.department.manager' op='=' code='E' path='Employee'/>" +
|
993
|
+
"<constraint op='LOOKUP' code='F' value='quux' path='Employee'/>" +
|
994
|
+
"<constraint extraValue='zip' op='LOOKUP' code='G' value='zop' path='Employee'/>" +
|
995
|
+
"</query>"
|
996
|
+
|
997
|
+
compare_xml(expected, query.to_xml.to_s)
|
998
|
+
end
|
999
|
+
|
1000
|
+
def test_join_xml
|
1001
|
+
|
1002
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
1003
|
+
query.add_views("name", "age", "fullTime", "department.name")
|
1004
|
+
|
1005
|
+
query.add_join("department")
|
1006
|
+
query.add_join("department.company", "INNER")
|
1007
|
+
query.add_join("department.company.address", "OUTER")
|
1008
|
+
|
1009
|
+
expected = "<query model='testmodel' view='Employee.name Employee.age Employee.fullTime Employee.department.name' sortOrder='Employee.name ASC'>" +
|
1010
|
+
"<join path='Employee.department' style='OUTER'/>" +
|
1011
|
+
"<join path='Employee.department.company' style='INNER'/>" +
|
1012
|
+
"<join path='Employee.department.company.address' style='OUTER'/>" +
|
1013
|
+
"</query>"
|
1014
|
+
|
1015
|
+
compare_xml(expected, query.to_xml)
|
1016
|
+
end
|
1017
|
+
|
1018
|
+
def test_all_xml
|
1019
|
+
query = InterMine::PathQuery::Query.new(@model, "Employee")
|
1020
|
+
query.add_views("name", "age", "fullTime", "department.name")
|
1021
|
+
query.add_constraint({
|
1022
|
+
:path => "Employee",
|
1023
|
+
:sub_class => "Manager"
|
1024
|
+
})
|
1025
|
+
query.add_views("title")
|
1026
|
+
query.add_sort_order("title", "desc")
|
1027
|
+
|
1028
|
+
query.add_join("department")
|
1029
|
+
query.add_join("department.company", "INNER")
|
1030
|
+
query.add_join("department.company.address", "OUTER")
|
1031
|
+
|
1032
|
+
query.add_constraint({:path => "department", :op => "IS NOT NULL"})
|
1033
|
+
query.add_constraint({
|
1034
|
+
:path => "name",
|
1035
|
+
:op => "<",
|
1036
|
+
:value => "foo"
|
1037
|
+
})
|
1038
|
+
query.add_constraint({
|
1039
|
+
:path => "age",
|
1040
|
+
:op => "ONE OF",
|
1041
|
+
:values => [17, 23, 37]
|
1042
|
+
})
|
1043
|
+
query.add_constraint({
|
1044
|
+
:path => "Employee",
|
1045
|
+
:op => "IN",
|
1046
|
+
:value => "bar"
|
1047
|
+
})
|
1048
|
+
query.add_constraint({
|
1049
|
+
:path => "Employee",
|
1050
|
+
:op => "IS",
|
1051
|
+
:loopPath => "department.manager"
|
1052
|
+
})
|
1053
|
+
query.add_constraint({
|
1054
|
+
:path => "Employee",
|
1055
|
+
:op => "LOOKUP",
|
1056
|
+
:value => "quux"
|
1057
|
+
})
|
1058
|
+
query.add_constraint({
|
1059
|
+
:path => "Employee",
|
1060
|
+
:op => "LOOKUP",
|
1061
|
+
:value => "zop",
|
1062
|
+
:extra_value => "zip"
|
1063
|
+
})
|
1064
|
+
|
1065
|
+
expected = "<query model='testmodel' view='Employee.name Employee.age Employee.fullTime Employee.department.name Employee.title' sortOrder='Employee.title DESC'>" +
|
1066
|
+
"<join path='Employee.department' style='OUTER'/>" +
|
1067
|
+
"<join path='Employee.department.company' style='INNER'/>" +
|
1068
|
+
"<join path='Employee.department.company.address' style='OUTER'/>" +
|
1069
|
+
"<constraint type='Manager' path='Employee'/>" +
|
1070
|
+
"<constraint op='IS NOT NULL' code='A' path='Employee.department'/>" +
|
1071
|
+
"<constraint op='<' code='B' value='foo' path='Employee.name'/>" +
|
1072
|
+
"<constraint op='ONE OF' code='C' path='Employee.age'>" +
|
1073
|
+
"<value>17</value><value>23</value><value>37</value>" +
|
1074
|
+
"</constraint>" +
|
1075
|
+
"<constraint op='IN' code='D' value='bar' path='Employee'/>" +
|
1076
|
+
"<constraint loopPath='Employee.department.manager' op='=' code='E' path='Employee'/>" +
|
1077
|
+
"<constraint op='LOOKUP' code='F' value='quux' path='Employee'/>" +
|
1078
|
+
"<constraint extraValue='zip' op='LOOKUP' code='G' value='zop' path='Employee'/>" +
|
1079
|
+
"</query>"
|
1080
|
+
|
1081
|
+
compare_xml(expected, query.to_xml)
|
1082
|
+
|
1083
|
+
end
|
1084
|
+
|
1085
|
+
def test_unmarshall
|
1086
|
+
# Tricky xml with all constraint types and subclassing, as well as integer values
|
1087
|
+
xml = "<query model='testmodel' view='Employee.name Employee.age Employee.fullTime Employee.department.name Employee.title' sortOrder='Employee.title DESC' constraintLogic='(A or B) and (C or D) and (E or F)'>" +
|
1088
|
+
"<join path='Employee.department' style='OUTER'/>" +
|
1089
|
+
"<join path='Employee.department.company' style='INNER'/>" +
|
1090
|
+
"<join path='Employee.department.company.address' style='OUTER'/>" +
|
1091
|
+
"<constraint type='Manager' path='Employee'/>" +
|
1092
|
+
"<constraint op='IS NOT NULL' code='A' path='Employee.department'/>" +
|
1093
|
+
"<constraint op='<' code='B' value='foo' path='Employee.name'/>" +
|
1094
|
+
"<constraint op='ONE OF' code='C' path='Employee.age'>" +
|
1095
|
+
"<value>17</value><value>23</value><value>37</value>" +
|
1096
|
+
"</constraint>" +
|
1097
|
+
"<constraint op='IN' code='D' value='bar' path='Employee'/>" +
|
1098
|
+
"<constraint loopPath='Employee.department.manager' op='=' code='E' path='Employee'/>" +
|
1099
|
+
"<constraint op='LOOKUP' code='F' value='quux' path='Employee'/>" +
|
1100
|
+
"<constraint extraValue='zip' op='LOOKUP' code='G' value='zop' path='Employee'/>" +
|
1101
|
+
"</query>"
|
1102
|
+
|
1103
|
+
q = InterMine::PathQuery::Query.parser(@model).parse(xml)
|
1104
|
+
|
1105
|
+
compare_xml(xml, q.to_xml)
|
1106
|
+
end
|
1107
|
+
|
1108
|
+
def test_unmarshall_template
|
1109
|
+
# Tricky xml with all constraint types and subclassing, as well as integer values
|
1110
|
+
src = "<template name='unmarshal_template' longDescription='Some kind of text description' comment='some comment'>" +
|
1111
|
+
"<query model='testmodel' sortOrder='Employee.title DESC' view='Employee.name Employee.age Employee.fullTime Employee.department.name Employee.title'>" +
|
1112
|
+
"<join path='Employee.department' style='OUTER'/>" +
|
1113
|
+
"<join path='Employee.department.company' style='INNER'/>" +
|
1114
|
+
"<join path='Employee.department.company.address' style='OUTER'/>" +
|
1115
|
+
"<constraint type='Manager' path='Employee'/>" +
|
1116
|
+
"<constraint op='IS NOT NULL' code='A' path='Employee.department'/>" +
|
1117
|
+
"<constraint op='<' code='B' value='foo' path='Employee.name'/>" +
|
1118
|
+
"<constraint op='ONE OF' code='C' path='Employee.age'>" +
|
1119
|
+
"<value>17</value><value>23</value><value>37</value>" +
|
1120
|
+
"</constraint>" +
|
1121
|
+
"<constraint op='IN' code='D' value='bar' path='Employee'/>" +
|
1122
|
+
"<constraint loopPath='Employee.department.manager' op='=' code='E' path='Employee'/>" +
|
1123
|
+
"<constraint op='LOOKUP' code='F' value='quux' path='Employee'/>" +
|
1124
|
+
"<constraint extraValue='zip' op='LOOKUP' code='G' value='zop' path='Employee'/>" +
|
1125
|
+
"</query>" +
|
1126
|
+
"</template>"
|
1127
|
+
|
1128
|
+
expected = "<template name='unmarshal_template' longDescription='Some kind of text description' comment='some comment'>" +
|
1129
|
+
"<query name='unmarshal_template' model='testmodel' sortOrder='Employee.title DESC' view='Employee.name Employee.age Employee.fullTime Employee.department.name Employee.title'>" +
|
1130
|
+
"<join path='Employee.department' style='OUTER'/>" +
|
1131
|
+
"<join path='Employee.department.company' style='INNER'/>" +
|
1132
|
+
"<join path='Employee.department.company.address' style='OUTER'/>" +
|
1133
|
+
"<constraint type='Manager' path='Employee'/>" +
|
1134
|
+
"<constraint op='IS NOT NULL' code='A' path='Employee.department' switchable='locked' editable='true'/>" +
|
1135
|
+
"<constraint op='<' code='B' value='foo' path='Employee.name' switchable='locked' editable='true'/>" +
|
1136
|
+
"<constraint op='ONE OF' code='C' path='Employee.age' switchable='locked' editable='true'>" +
|
1137
|
+
"<value>17</value><value>23</value><value>37</value>" +
|
1138
|
+
"</constraint>" +
|
1139
|
+
"<constraint op='IN' code='D' value='bar' path='Employee' switchable='locked' editable='true'/>" +
|
1140
|
+
"<constraint loopPath='Employee.department.manager' op='=' code='E' path='Employee' switchable='locked' editable='true'/>" +
|
1141
|
+
"<constraint op='LOOKUP' code='F' value='quux' path='Employee' switchable='locked' editable='true'/>" +
|
1142
|
+
"<constraint extraValue='zip' op='LOOKUP' code='G' value='zop' path='Employee' switchable='locked' editable='true'/>" +
|
1143
|
+
"</query>" +
|
1144
|
+
"</template>"
|
1145
|
+
|
1146
|
+
q = InterMine::PathQuery::Template.parser(@model).parse(src)
|
1147
|
+
|
1148
|
+
compare_xml expected, q.to_xml
|
1149
|
+
end
|
1150
|
+
|
1151
|
+
def test_template_parameters
|
1152
|
+
|
1153
|
+
# Tricky xml with all constraint types and subclassing, as well as integer values
|
1154
|
+
src = "<template name='unmarshal_template' longDescription='Some kind of text description' comment='some comment'>" +
|
1155
|
+
"<query model='testmodel' sortOrder='Employee.title DESC' view='Employee.name Employee.age Employee.fullTime Employee.department.name Employee.title'>" +
|
1156
|
+
"<join path='Employee.department' style='OUTER'/>" +
|
1157
|
+
"<join path='Employee.department.company' style='INNER'/>" +
|
1158
|
+
"<join path='Employee.department.company.address' style='OUTER'/>" +
|
1159
|
+
"<constraint type='Manager' path='Employee'/>" +
|
1160
|
+
"<constraint op='IS NOT NULL' code='A' path='Employee.department'/>" +
|
1161
|
+
"<constraint op='<' code='B' value='foo' path='Employee.name'/>" +
|
1162
|
+
"<constraint op='ONE OF' code='C' path='Employee.age'>" +
|
1163
|
+
"<value>17</value><value>23</value><value>37</value>" +
|
1164
|
+
"</constraint>" +
|
1165
|
+
"<constraint op='IN' code='D' value='bar' path='Employee'/>" +
|
1166
|
+
"<constraint loopPath='Employee.department.manager' op='=' code='E' path='Employee'/>" +
|
1167
|
+
"<constraint op='LOOKUP' code='F' value='quux' path='Employee'/>" +
|
1168
|
+
"<constraint extraValue='zip' op='LOOKUP' code='G' value='zop' path='Employee'/>" +
|
1169
|
+
"</query>" +
|
1170
|
+
"</template>"
|
1171
|
+
|
1172
|
+
q = InterMine::PathQuery::Template.parser(@model).parse(src)
|
1173
|
+
|
1174
|
+
expected = {
|
1175
|
+
"name"=>"unmarshal_template",
|
1176
|
+
"constraint1"=>"Employee.department",
|
1177
|
+
"constraint2"=>"Employee.name",
|
1178
|
+
"constraint3"=>"Employee.age",
|
1179
|
+
"constraint4"=>"Employee",
|
1180
|
+
"constraint5"=>"Employee",
|
1181
|
+
"constraint6"=>"Employee",
|
1182
|
+
"constraint7"=>"Employee",
|
1183
|
+
"op1"=>"IS NOT NULL",
|
1184
|
+
"op2"=>"lt",
|
1185
|
+
"op3"=>"ONE OF",
|
1186
|
+
"op4"=>"IN",
|
1187
|
+
"op5"=>"eq",
|
1188
|
+
"op6"=>"LOOKUP",
|
1189
|
+
"op7"=>"LOOKUP",
|
1190
|
+
"value2"=>"foo",
|
1191
|
+
"value3"=>[17, 23, 37],
|
1192
|
+
"value4"=>"bar",
|
1193
|
+
"loopPath5"=>"Employee.department.manager",
|
1194
|
+
"value6"=>"quux",
|
1195
|
+
"value7"=>"zop",
|
1196
|
+
"extra7"=>"zip"
|
1197
|
+
}
|
1198
|
+
|
1199
|
+
assert_equal(expected, q.params)
|
1200
|
+
end
|
1201
|
+
|
1202
|
+
end
|