cuprum-collections 0.5.0 → 0.6.0.rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +51 -0
  3. data/README.md +1 -1
  4. data/config/locales/en.rb +18 -0
  5. data/lib/cuprum/collections/adaptable/collection.rb +18 -0
  6. data/lib/cuprum/collections/adaptable/command.rb +22 -0
  7. data/lib/cuprum/collections/adaptable/commands/abstract_assign_one.rb +27 -0
  8. data/lib/cuprum/collections/adaptable/commands/abstract_build_one.rb +25 -0
  9. data/lib/cuprum/collections/adaptable/commands/abstract_validate_one.rb +35 -0
  10. data/lib/cuprum/collections/adaptable/commands.rb +15 -0
  11. data/lib/cuprum/collections/adaptable/query.rb +64 -0
  12. data/lib/cuprum/collections/adaptable.rb +13 -0
  13. data/lib/cuprum/collections/adapter.rb +300 -0
  14. data/lib/cuprum/collections/adapters/data_adapter.rb +82 -0
  15. data/lib/cuprum/collections/adapters/entity_adapter.rb +76 -0
  16. data/lib/cuprum/collections/adapters/hash_adapter.rb +48 -0
  17. data/lib/cuprum/collections/adapters.rb +14 -0
  18. data/lib/cuprum/collections/basic/collection.rb +2 -20
  19. data/lib/cuprum/collections/basic/commands/destroy_one.rb +1 -1
  20. data/lib/cuprum/collections/basic/commands/find_many.rb +0 -31
  21. data/lib/cuprum/collections/basic/commands/find_matching.rb +0 -94
  22. data/lib/cuprum/collections/basic/commands/find_one.rb +0 -18
  23. data/lib/cuprum/collections/basic/commands/insert_one.rb +1 -1
  24. data/lib/cuprum/collections/basic/commands/update_one.rb +1 -1
  25. data/lib/cuprum/collections/basic/scopes/criteria_scope.rb +36 -21
  26. data/lib/cuprum/collections/basic.rb +6 -5
  27. data/lib/cuprum/collections/collection.rb +6 -0
  28. data/lib/cuprum/collections/collection_command.rb +1 -1
  29. data/lib/cuprum/collections/commands/abstract_find_many.rb +40 -3
  30. data/lib/cuprum/collections/commands/abstract_find_matching.rb +102 -0
  31. data/lib/cuprum/collections/commands/abstract_find_one.rb +23 -1
  32. data/lib/cuprum/collections/commands/associations/find_many.rb +1 -3
  33. data/lib/cuprum/collections/commands/associations/require_many.rb +1 -1
  34. data/lib/cuprum/collections/commands/find_one_matching.rb +10 -10
  35. data/lib/cuprum/collections/commands/query_command.rb +6 -4
  36. data/lib/cuprum/collections/commands/upsert.rb +0 -2
  37. data/lib/cuprum/collections/constraints/order/attributes_array.rb +5 -4
  38. data/lib/cuprum/collections/constraints/order/attributes_hash.rb +5 -4
  39. data/lib/cuprum/collections/constraints/order/sort_direction.rb +2 -2
  40. data/lib/cuprum/collections/constraints/ordering.rb +11 -9
  41. data/lib/cuprum/collections/constraints/query_hash.rb +2 -2
  42. data/lib/cuprum/collections/errors/abstract_find_error.rb +101 -23
  43. data/lib/cuprum/collections/errors/extra_attributes.rb +3 -3
  44. data/lib/cuprum/collections/errors/failed_validation.rb +3 -3
  45. data/lib/cuprum/collections/errors/missing_default_contract.rb +12 -4
  46. data/lib/cuprum/collections/queries.rb +4 -0
  47. data/lib/cuprum/collections/relation.rb +0 -2
  48. data/lib/cuprum/collections/relations/parameters.rb +120 -68
  49. data/lib/cuprum/collections/repository.rb +71 -6
  50. data/lib/cuprum/collections/rspec/contracts/query_contracts.rb +23 -4
  51. data/lib/cuprum/collections/rspec/contracts/repository_contracts.rb +18 -0
  52. data/lib/cuprum/collections/rspec/contracts/scope_contracts.rb +51 -0
  53. data/lib/cuprum/collections/rspec/contracts/scopes/builder_contracts.rb +10 -0
  54. data/lib/cuprum/collections/rspec/contracts/scopes/composition_contracts.rb +8 -0
  55. data/lib/cuprum/collections/rspec/contracts/scopes/criteria_contracts.rb +18 -366
  56. data/lib/cuprum/collections/rspec/contracts/scopes/logical_contracts.rb +30 -0
  57. data/lib/cuprum/collections/rspec/contracts/scopes.rb +2 -0
  58. data/lib/cuprum/collections/rspec/contracts.rb +2 -10
  59. data/lib/cuprum/collections/rspec/deferred/adapter_examples.rb +1077 -0
  60. data/lib/cuprum/collections/rspec/deferred/collection_examples.rb +27 -7
  61. data/lib/cuprum/collections/rspec/deferred/commands/assign_one_examples.rb +4 -4
  62. data/lib/cuprum/collections/rspec/deferred/commands/build_one_examples.rb +2 -2
  63. data/lib/cuprum/collections/rspec/deferred/commands/destroy_one_examples.rb +2 -2
  64. data/lib/cuprum/collections/rspec/deferred/commands/find_many_examples.rb +5 -5
  65. data/lib/cuprum/collections/rspec/deferred/commands/find_matching_examples.rb +45 -12
  66. data/lib/cuprum/collections/rspec/deferred/commands/find_one_examples.rb +2 -2
  67. data/lib/cuprum/collections/rspec/deferred/commands/insert_one_examples.rb +1 -1
  68. data/lib/cuprum/collections/rspec/deferred/commands/update_one_examples.rb +1 -1
  69. data/lib/cuprum/collections/rspec/deferred/query_examples.rb +930 -0
  70. data/lib/cuprum/collections/rspec/deferred/relation_examples.rb +48 -17
  71. data/lib/cuprum/collections/rspec/deferred/repository_examples.rb +961 -0
  72. data/lib/cuprum/collections/rspec/deferred/scope_examples.rb +598 -0
  73. data/lib/cuprum/collections/rspec/deferred/scopes/all_examples.rb +391 -0
  74. data/lib/cuprum/collections/rspec/deferred/scopes/builder_examples.rb +857 -0
  75. data/lib/cuprum/collections/rspec/deferred/scopes/composition_examples.rb +93 -0
  76. data/lib/cuprum/collections/rspec/deferred/scopes/conjunction_examples.rb +438 -0
  77. data/lib/cuprum/collections/rspec/deferred/scopes/criteria_examples.rb +1941 -0
  78. data/lib/cuprum/collections/rspec/deferred/scopes/disjunction_examples.rb +415 -0
  79. data/lib/cuprum/collections/rspec/deferred/scopes/none_examples.rb +385 -0
  80. data/lib/cuprum/collections/rspec/deferred/scopes/parser_examples.rb +740 -0
  81. data/lib/cuprum/collections/rspec/deferred/scopes.rb +8 -0
  82. data/lib/cuprum/collections/scope.rb +2 -2
  83. data/lib/cuprum/collections/scopes/container.rb +5 -4
  84. data/lib/cuprum/collections/scopes/criteria/parser.rb +24 -48
  85. data/lib/cuprum/collections/scopes/criteria.rb +7 -6
  86. data/lib/cuprum/collections/version.rb +3 -3
  87. data/lib/cuprum/collections.rb +5 -1
  88. metadata +48 -11
  89. data/lib/cuprum/collections/rspec/contracts/association_contracts.rb +0 -2127
  90. data/lib/cuprum/collections/rspec/contracts/basic.rb +0 -11
  91. data/lib/cuprum/collections/rspec/contracts/collection_contracts.rb +0 -387
  92. data/lib/cuprum/collections/rspec/contracts/command_contracts.rb +0 -169
  93. data/lib/cuprum/collections/rspec/contracts/relation_contracts.rb +0 -1264
@@ -0,0 +1,740 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspec/sleeping_king_studios/deferred'
4
+
5
+ require 'cuprum/collections/rspec/deferred/scopes'
6
+
7
+ module Cuprum::Collections::RSpec::Deferred::Scopes
8
+ # Deferred examples for asserting on scope parsing.
9
+ module ParserExamples
10
+ include RSpec::SleepingKingStudios::Deferred::Provider
11
+
12
+ deferred_examples 'should parse Scope criteria' do
13
+ describe 'with a block' do
14
+ describe 'without a block' do
15
+ let(:error_message) { 'no block given' }
16
+
17
+ it 'should raise an exception' do
18
+ expect { parse_criteria }
19
+ .to raise_error ArgumentError, error_message
20
+ end
21
+ end
22
+
23
+ include_deferred 'should parse Scope criteria from a block'
24
+ end
25
+
26
+ describe 'with a proc' do
27
+ define_method :parse_criteria do |&block|
28
+ super(block)
29
+ end
30
+
31
+ include_deferred 'should parse Scope criteria from a block'
32
+ end
33
+
34
+ describe 'with a hash' do
35
+ include_deferred 'should parse Scope criteria from a Hash'
36
+ end
37
+
38
+ describe 'with a hash and a block' do
39
+ let(:operators) { Cuprum::Collections::Queries::Operators }
40
+ let(:block) do
41
+ lambda do |scope|
42
+ { 'author' => scope.one_of('J.R.R. Tolkien', 'Ursula K. LeGuin') }
43
+ end
44
+ end
45
+ let(:value) do
46
+ { 'category' => 'Science Fiction and Fantasy' }
47
+ end
48
+ let(:expected) do
49
+ [
50
+ [
51
+ 'category',
52
+ operators::EQUAL,
53
+ 'Science Fiction and Fantasy'
54
+ ],
55
+ [
56
+ 'author',
57
+ operators::ONE_OF,
58
+ ['J.R.R. Tolkien', 'Ursula K. LeGuin']
59
+ ]
60
+ ]
61
+ end
62
+
63
+ it 'should parse the criteria' do
64
+ expect(parse_criteria(value, &block)).to be == expected
65
+ end
66
+ end
67
+ end
68
+
69
+ deferred_examples 'should parse Scope criteria from a Hash' do
70
+ describe 'with nil' do
71
+ let(:error_message) do
72
+ 'value must be a Hash with String or Symbol keys'
73
+ end
74
+
75
+ it 'should raise an exception' do
76
+ expect { parse_criteria(nil) }
77
+ .to raise_error ArgumentError, error_message
78
+ end
79
+ end
80
+
81
+ describe 'with an Object' do
82
+ let(:error_message) do
83
+ 'value must be a Hash with String or Symbol keys'
84
+ end
85
+
86
+ it 'should raise an exception' do
87
+ expect { parse_criteria(Object.new.freeze) }
88
+ .to raise_error ArgumentError, error_message
89
+ end
90
+ end
91
+
92
+ describe 'with a Hash with invalid keys' do
93
+ let(:error_message) do
94
+ 'value must be a Hash with String or Symbol keys'
95
+ end
96
+ let(:value) { { nil => 'invalid' } }
97
+
98
+ it 'should raise an exception' do
99
+ expect { parse_criteria(value) }
100
+ .to raise_error ArgumentError, error_message
101
+ end
102
+ end
103
+
104
+ describe 'with an empty Hash' do
105
+ let(:value) { {} }
106
+
107
+ it { expect(parse_criteria(value)).to be == [] }
108
+ end
109
+
110
+ describe 'with a Hash with one key' do
111
+ let(:operators) { Cuprum::Collections::Queries::Operators }
112
+ let(:value) do
113
+ { 'title' => 'A Wizard of Earthsea' }
114
+ end
115
+ let(:expected) do
116
+ [['title', operators::EQUAL, 'A Wizard of Earthsea']]
117
+ end
118
+
119
+ it { expect(parse_criteria(value)).to be == expected }
120
+ end
121
+
122
+ describe 'with a Hash with many String keys' do
123
+ let(:operators) { Cuprum::Collections::Queries::Operators }
124
+ let(:value) do
125
+ {
126
+ 'title' => 'A Wizard of Earthsea',
127
+ 'author' => 'Ursula K. LeGuin',
128
+ 'series' => 'Earthsea'
129
+ }
130
+ end
131
+ let(:expected) do
132
+ [
133
+ ['title', operators::EQUAL, 'A Wizard of Earthsea'],
134
+ ['author', operators::EQUAL, 'Ursula K. LeGuin'],
135
+ ['series', operators::EQUAL, 'Earthsea']
136
+ ]
137
+ end
138
+
139
+ it { expect(parse_criteria(value)).to be == expected }
140
+ end
141
+
142
+ describe 'with a Hash with many Symbol keys' do
143
+ let(:operators) { Cuprum::Collections::Queries::Operators }
144
+ let(:value) do
145
+ {
146
+ title: 'A Wizard of Earthsea',
147
+ author: 'Ursula K. LeGuin',
148
+ series: 'Earthsea'
149
+ }
150
+ end
151
+ let(:expected) do
152
+ [
153
+ ['title', operators::EQUAL, 'A Wizard of Earthsea'],
154
+ ['author', operators::EQUAL, 'Ursula K. LeGuin'],
155
+ ['series', operators::EQUAL, 'Earthsea']
156
+ ]
157
+ end
158
+
159
+ it { expect(parse_criteria(value)).to be == expected }
160
+ end
161
+ end
162
+
163
+ deferred_examples 'should parse Scope criteria from a block' do
164
+ describe 'with a block returning nil' do
165
+ let(:error_message) do
166
+ 'value must be a Hash with String or Symbol keys'
167
+ end
168
+
169
+ it 'should raise an exception' do
170
+ expect { parse_criteria { nil } }
171
+ .to raise_error ArgumentError, error_message
172
+ end
173
+ end
174
+
175
+ describe 'with a block returning an Object' do
176
+ let(:error_message) do
177
+ 'value must be a Hash with String or Symbol keys'
178
+ end
179
+
180
+ it 'should raise an exception' do
181
+ expect { parse_criteria { Object.new.freeze } }
182
+ .to raise_error ArgumentError, error_message
183
+ end
184
+ end
185
+
186
+ describe 'with a block returning a Hash with invalid keys' do
187
+ let(:error_message) do
188
+ 'value must be a Hash with String or Symbol keys'
189
+ end
190
+ let(:block) { -> { { nil => 'invalid' } } }
191
+
192
+ it 'should raise an exception' do
193
+ expect { parse_criteria(&block) }
194
+ .to raise_error ArgumentError, error_message
195
+ end
196
+ end
197
+
198
+ describe 'with a block returning an empty Hash' do
199
+ let(:block) { -> { {} } }
200
+
201
+ it { expect(parse_criteria(&block)).to be == [] }
202
+ end
203
+
204
+ describe 'with a block returning a Hash with one key' do
205
+ let(:operators) { Cuprum::Collections::Queries::Operators }
206
+ let(:block) do
207
+ -> { { 'title' => 'A Wizard of Earthsea' } }
208
+ end
209
+ let(:expected) do
210
+ [['title', operators::EQUAL, 'A Wizard of Earthsea']]
211
+ end
212
+
213
+ it { expect(parse_criteria(&block)).to be == expected }
214
+ end
215
+
216
+ describe 'with a Hash with many String keys' do
217
+ let(:operators) { Cuprum::Collections::Queries::Operators }
218
+ let(:block) do
219
+ lambda do
220
+ {
221
+ 'title' => 'A Wizard of Earthsea',
222
+ 'author' => 'Ursula K. LeGuin',
223
+ 'series' => 'Earthsea'
224
+ }
225
+ end
226
+ end
227
+ let(:expected) do
228
+ [
229
+ ['title', operators::EQUAL, 'A Wizard of Earthsea'],
230
+ ['author', operators::EQUAL, 'Ursula K. LeGuin'],
231
+ ['series', operators::EQUAL, 'Earthsea']
232
+ ]
233
+ end
234
+
235
+ it { expect(parse_criteria(&block)).to be == expected }
236
+ end
237
+
238
+ describe 'with a Hash with many Symbol keys' do
239
+ let(:operators) { Cuprum::Collections::Queries::Operators }
240
+ let(:block) do
241
+ lambda do
242
+ {
243
+ title: 'A Wizard of Earthsea',
244
+ author: 'Ursula K. LeGuin',
245
+ series: 'Earthsea'
246
+ }
247
+ end
248
+ end
249
+ let(:expected) do
250
+ [
251
+ ['title', operators::EQUAL, 'A Wizard of Earthsea'],
252
+ ['author', operators::EQUAL, 'Ursula K. LeGuin'],
253
+ ['series', operators::EQUAL, 'Earthsea']
254
+ ]
255
+ end
256
+
257
+ it { expect(parse_criteria(&block)).to be == expected }
258
+ end
259
+
260
+ describe 'with a Hash with an "eq" operator' do
261
+ let(:operators) { Cuprum::Collections::Queries::Operators }
262
+ let(:block) do
263
+ ->(scope) { { 'title' => scope.eq('A Wizard of Earthsea') } }
264
+ end
265
+ let(:expected) do
266
+ [['title', operators::EQUAL, 'A Wizard of Earthsea']]
267
+ end
268
+
269
+ it 'should parse the criteria' do
270
+ expect(parse_criteria(&block)).to be == expected
271
+ end
272
+ end
273
+
274
+ describe 'with a Hash with an "equal" operator' do
275
+ let(:operators) { Cuprum::Collections::Queries::Operators }
276
+ let(:block) do
277
+ ->(scope) { { 'title' => scope.equal('A Wizard of Earthsea') } }
278
+ end
279
+ let(:expected) do
280
+ [['title', operators::EQUAL, 'A Wizard of Earthsea']]
281
+ end
282
+
283
+ it 'should parse the criteria' do
284
+ expect(parse_criteria(&block)).to be == expected
285
+ end
286
+ end
287
+
288
+ describe 'with a Hash with an "equals" operator' do
289
+ let(:operators) { Cuprum::Collections::Queries::Operators }
290
+ let(:block) do
291
+ ->(scope) { { 'title' => scope.equals('A Wizard of Earthsea') } }
292
+ end
293
+ let(:expected) do
294
+ [['title', operators::EQUAL, 'A Wizard of Earthsea']]
295
+ end
296
+
297
+ it 'should parse the criteria' do
298
+ expect(parse_criteria(&block)).to be == expected
299
+ end
300
+ end
301
+
302
+ describe 'with a Hash with a "greater_than" operator' do
303
+ let(:operators) { Cuprum::Collections::Queries::Operators }
304
+ let(:block) do
305
+ ->(scope) { { 'published_at' => scope.greater_than('1970-01-01') } }
306
+ end
307
+ let(:expected) do
308
+ [['published_at', operators::GREATER_THAN, '1970-01-01']]
309
+ end
310
+
311
+ it 'should parse the criteria' do
312
+ expect(parse_criteria(&block)).to be == expected
313
+ end
314
+ end
315
+
316
+ describe 'with a Hash with a "greater_than_or_equal_to" operator' do
317
+ let(:operators) { Cuprum::Collections::Queries::Operators }
318
+ let(:block) do
319
+ lambda do |scope|
320
+ { 'published_at' => scope.greater_than_or_equal_to('1970-01-01') }
321
+ end
322
+ end
323
+ let(:expected) do
324
+ [
325
+ [
326
+ 'published_at',
327
+ operators::GREATER_THAN_OR_EQUAL_TO,
328
+ '1970-01-01'
329
+ ]
330
+ ]
331
+ end
332
+
333
+ it 'should parse the criteria' do
334
+ expect(parse_criteria(&block)).to be == expected
335
+ end
336
+ end
337
+
338
+ describe 'with a Hash with a "gt" operator' do
339
+ let(:operators) { Cuprum::Collections::Queries::Operators }
340
+ let(:block) do
341
+ ->(scope) { { 'published_at' => scope.gt('1970-01-01') } }
342
+ end
343
+ let(:expected) do
344
+ [['published_at', operators::GREATER_THAN, '1970-01-01']]
345
+ end
346
+
347
+ it 'should parse the criteria' do
348
+ expect(parse_criteria(&block)).to be == expected
349
+ end
350
+ end
351
+
352
+ describe 'with a Hash with a "gte" operator' do
353
+ let(:operators) { Cuprum::Collections::Queries::Operators }
354
+ let(:block) do
355
+ ->(scope) { { 'published_at' => scope.gte('1970-01-01') } }
356
+ end
357
+ let(:expected) do
358
+ [
359
+ [
360
+ 'published_at',
361
+ operators::GREATER_THAN_OR_EQUAL_TO,
362
+ '1970-01-01'
363
+ ]
364
+ ]
365
+ end
366
+
367
+ it 'should parse the criteria' do
368
+ expect(parse_criteria(&block)).to be == expected
369
+ end
370
+ end
371
+
372
+ describe 'with a Hash with a "less_than" operator' do
373
+ let(:operators) { Cuprum::Collections::Queries::Operators }
374
+ let(:block) do
375
+ ->(scope) { { 'published_at' => scope.less_than('1970-01-01') } }
376
+ end
377
+ let(:expected) do
378
+ [['published_at', operators::LESS_THAN, '1970-01-01']]
379
+ end
380
+
381
+ it 'should parse the criteria' do
382
+ expect(parse_criteria(&block)).to be == expected
383
+ end
384
+ end
385
+
386
+ describe 'with a Hash with a "less_than_or_equal_to" operator' do
387
+ let(:operators) { Cuprum::Collections::Queries::Operators }
388
+ let(:block) do
389
+ lambda do |scope|
390
+ { 'published_at' => scope.less_than_or_equal_to('1970-01-01') }
391
+ end
392
+ end
393
+ let(:expected) do
394
+ [['published_at', operators::LESS_THAN_OR_EQUAL_TO, '1970-01-01']]
395
+ end
396
+
397
+ it 'should parse the criteria' do
398
+ expect(parse_criteria(&block)).to be == expected
399
+ end
400
+ end
401
+
402
+ describe 'with a Hash with a "lt" operator' do
403
+ let(:operators) { Cuprum::Collections::Queries::Operators }
404
+ let(:block) do
405
+ ->(scope) { { 'published_at' => scope.lt('1970-01-01') } }
406
+ end
407
+ let(:expected) do
408
+ [['published_at', operators::LESS_THAN, '1970-01-01']]
409
+ end
410
+
411
+ it 'should parse the criteria' do
412
+ expect(parse_criteria(&block)).to be == expected
413
+ end
414
+ end
415
+
416
+ describe 'with a Hash with a "lte" operator' do
417
+ let(:operators) { Cuprum::Collections::Queries::Operators }
418
+ let(:block) do
419
+ ->(scope) { { 'published_at' => scope.lte('1970-01-01') } }
420
+ end
421
+ let(:expected) do
422
+ [['published_at', operators::LESS_THAN_OR_EQUAL_TO, '1970-01-01']]
423
+ end
424
+
425
+ it 'should parse the criteria' do
426
+ expect(parse_criteria(&block)).to be == expected
427
+ end
428
+ end
429
+
430
+ describe 'with a Hash with a "ne" operator' do
431
+ let(:operators) { Cuprum::Collections::Queries::Operators }
432
+ let(:block) do
433
+ ->(scope) { { 'series' => scope.ne('Earthsea') } }
434
+ end
435
+ let(:expected) do
436
+ [['series', operators::NOT_EQUAL, 'Earthsea']]
437
+ end
438
+
439
+ it 'should parse the criteria' do
440
+ expect(parse_criteria(&block)).to be == expected
441
+ end
442
+ end
443
+
444
+ describe 'with a Hash with a "not_equal" operator' do
445
+ let(:operators) { Cuprum::Collections::Queries::Operators }
446
+ let(:block) do
447
+ ->(scope) { { 'series' => scope.not_equal('Earthsea') } }
448
+ end
449
+ let(:expected) do
450
+ [['series', operators::NOT_EQUAL, 'Earthsea']]
451
+ end
452
+
453
+ it 'should parse the criteria' do
454
+ expect(parse_criteria(&block)).to be == expected
455
+ end
456
+ end
457
+
458
+ describe 'with a Hash with a "not_null" operator' do
459
+ let(:operators) { Cuprum::Collections::Queries::Operators }
460
+ let(:block) do
461
+ ->(scope) { { 'series' => scope.not_null } }
462
+ end
463
+ let(:expected) do
464
+ [['series', operators::NOT_NULL, nil]]
465
+ end
466
+
467
+ it 'should parse the criteria' do
468
+ expect(parse_criteria(&block)).to be == expected
469
+ end
470
+ end
471
+
472
+ describe 'with a Hash with a "not_one_of" operator and an Array' do
473
+ let(:operators) { Cuprum::Collections::Queries::Operators }
474
+ let(:block) do
475
+ lambda do |scope|
476
+ {
477
+ 'series' => scope.not_one_of(
478
+ ['Earthsea', 'The Lord of the Rings']
479
+ )
480
+ }
481
+ end
482
+ end
483
+ let(:expected) do
484
+ [
485
+ [
486
+ 'series',
487
+ operators::NOT_ONE_OF,
488
+ ['Earthsea', 'The Lord of the Rings']
489
+ ]
490
+ ]
491
+ end
492
+
493
+ it 'should parse the criteria' do
494
+ expect(parse_criteria(&block)).to be == expected
495
+ end
496
+ end
497
+
498
+ describe 'with a Hash with a "not_one_of" operator and a Set' do
499
+ let(:operators) { Cuprum::Collections::Queries::Operators }
500
+ let(:block) do
501
+ lambda do |scope|
502
+ {
503
+ 'series' => scope.not_one_of(
504
+ Set.new(['Earthsea', 'The Lord of the Rings'])
505
+ )
506
+ }
507
+ end
508
+ end
509
+ let(:expected) do
510
+ [
511
+ [
512
+ 'series',
513
+ operators::NOT_ONE_OF,
514
+ ['Earthsea', 'The Lord of the Rings']
515
+ ]
516
+ ]
517
+ end
518
+
519
+ it 'should parse the criteria' do
520
+ expect(parse_criteria(&block)).to be == expected
521
+ end
522
+ end
523
+
524
+ describe 'with a Hash with a "not_one_of" operator and values' do
525
+ let(:operators) { Cuprum::Collections::Queries::Operators }
526
+ let(:block) do
527
+ lambda do |scope|
528
+ {
529
+ 'series' => scope.not_one_of(
530
+ 'Earthsea',
531
+ 'The Lord of the Rings'
532
+ )
533
+ }
534
+ end
535
+ end
536
+ let(:expected) do
537
+ [
538
+ [
539
+ 'series',
540
+ operators::NOT_ONE_OF,
541
+ ['Earthsea', 'The Lord of the Rings']
542
+ ]
543
+ ]
544
+ end
545
+
546
+ it 'should parse the criteria' do
547
+ expect(parse_criteria(&block)).to be == expected
548
+ end
549
+ end
550
+
551
+ describe 'with a Hash with a "null" operator' do
552
+ let(:operators) { Cuprum::Collections::Queries::Operators }
553
+ let(:block) do
554
+ ->(scope) { { 'series' => scope.null } }
555
+ end
556
+ let(:expected) do
557
+ [['series', operators::NULL, nil]]
558
+ end
559
+
560
+ it 'should parse the criteria' do
561
+ expect(parse_criteria(&block)).to be == expected
562
+ end
563
+ end
564
+
565
+ describe 'with a Hash with a "one_of" operator and an Array' do
566
+ let(:operators) { Cuprum::Collections::Queries::Operators }
567
+ let(:block) do
568
+ lambda do |scope|
569
+ {
570
+ 'series' => scope.one_of(
571
+ ['Earthsea', 'The Lord of the Rings']
572
+ )
573
+ }
574
+ end
575
+ end
576
+ let(:expected) do
577
+ [
578
+ [
579
+ 'series',
580
+ operators::ONE_OF,
581
+ ['Earthsea', 'The Lord of the Rings']
582
+ ]
583
+ ]
584
+ end
585
+
586
+ it 'should parse the criteria' do
587
+ expect(parse_criteria(&block)).to be == expected
588
+ end
589
+ end
590
+
591
+ describe 'with a Hash with a "one_of" operator and a Set' do
592
+ let(:operators) { Cuprum::Collections::Queries::Operators }
593
+ let(:block) do
594
+ lambda do |scope|
595
+ {
596
+ 'series' => scope.one_of(
597
+ Set.new(['Earthsea', 'The Lord of the Rings'])
598
+ )
599
+ }
600
+ end
601
+ end
602
+ let(:expected) do
603
+ [
604
+ [
605
+ 'series',
606
+ operators::ONE_OF,
607
+ ['Earthsea', 'The Lord of the Rings']
608
+ ]
609
+ ]
610
+ end
611
+
612
+ it 'should parse the criteria' do
613
+ expect(parse_criteria(&block)).to be == expected
614
+ end
615
+ end
616
+
617
+ describe 'with a Hash with a "one_of" operator and values' do
618
+ let(:operators) { Cuprum::Collections::Queries::Operators }
619
+ let(:block) do
620
+ lambda do |scope|
621
+ {
622
+ 'series' => scope.one_of(
623
+ 'Earthsea',
624
+ 'The Lord of the Rings'
625
+ )
626
+ }
627
+ end
628
+ end
629
+ let(:expected) do
630
+ [
631
+ [
632
+ 'series',
633
+ operators::ONE_OF,
634
+ ['Earthsea', 'The Lord of the Rings']
635
+ ]
636
+ ]
637
+ end
638
+
639
+ it 'should parse the criteria' do
640
+ expect(parse_criteria(&block)).to be == expected
641
+ end
642
+ end
643
+
644
+ describe 'with a Hash with an unknown operator' do
645
+ let(:error_class) do
646
+ Cuprum::Collections::Queries::UnknownOperatorException
647
+ end
648
+ let(:error_message) do
649
+ 'unknown operator "random"'
650
+ end
651
+ let(:block) do
652
+ -> { { 'genre' => random('Science Fiction', 'Fantasy') } }
653
+ end
654
+
655
+ it 'should raise an exception' do
656
+ expect { parse_criteria(&block) }
657
+ .to raise_error error_class, error_message
658
+ end
659
+
660
+ it 'should preserve the original exception', :aggregate_failures do
661
+ parse_criteria(&block)
662
+ rescue error_class => exception
663
+ expect(exception.cause).to be_a NameError
664
+ expect(exception.name).to be == :random
665
+ end
666
+ end
667
+
668
+ describe 'with a Hash with multiple operators' do
669
+ let(:operators) { Cuprum::Collections::Queries::Operators }
670
+ let(:block) do
671
+ lambda do |scope|
672
+ {
673
+ 'published_at' => scope.greater_than('1970-01-01'),
674
+ 'series' => scope.one_of(
675
+ ['Earthsea', 'The Lord of the Rings']
676
+ ),
677
+ 'title' => scope.not_equal('The Tombs of Atuan')
678
+ }
679
+ end
680
+ end
681
+ let(:expected) do
682
+ [
683
+ [
684
+ 'published_at',
685
+ operators::GREATER_THAN,
686
+ '1970-01-01'
687
+ ],
688
+ [
689
+ 'series',
690
+ operators::ONE_OF,
691
+ ['Earthsea', 'The Lord of the Rings']
692
+ ],
693
+ [
694
+ 'title',
695
+ operators::NOT_EQUAL,
696
+ 'The Tombs of Atuan'
697
+ ]
698
+ ]
699
+ end
700
+
701
+ it 'should parse the criteria' do
702
+ expect(parse_criteria(&block)).to be == expected
703
+ end
704
+ end
705
+
706
+ describe 'with a Hash with mixed keys and operators' do
707
+ let(:operators) { Cuprum::Collections::Queries::Operators }
708
+ let(:block) do
709
+ lambda do |scope|
710
+ {
711
+ 'author' => scope.one_of(
712
+ 'J.R.R. Tolkien',
713
+ 'Ursula K. LeGuin'
714
+ ),
715
+ 'category' => 'Science Fiction and Fantasy'
716
+ }
717
+ end
718
+ end
719
+ let(:expected) do
720
+ [
721
+ [
722
+ 'author',
723
+ operators::ONE_OF,
724
+ ['J.R.R. Tolkien', 'Ursula K. LeGuin']
725
+ ],
726
+ [
727
+ 'category',
728
+ operators::EQUAL,
729
+ 'Science Fiction and Fantasy'
730
+ ]
731
+ ]
732
+ end
733
+
734
+ it 'should parse the criteria' do
735
+ expect(parse_criteria(&block)).to be == expected
736
+ end
737
+ end
738
+ end
739
+ end
740
+ end