cuprum-collections 0.5.1 → 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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +47 -0
  3. data/lib/cuprum/collections/adaptable/collection.rb +18 -0
  4. data/lib/cuprum/collections/adaptable/command.rb +22 -0
  5. data/lib/cuprum/collections/adaptable/commands/abstract_assign_one.rb +27 -0
  6. data/lib/cuprum/collections/adaptable/commands/abstract_build_one.rb +25 -0
  7. data/lib/cuprum/collections/adaptable/commands/abstract_validate_one.rb +35 -0
  8. data/lib/cuprum/collections/adaptable/commands.rb +15 -0
  9. data/lib/cuprum/collections/adaptable/query.rb +64 -0
  10. data/lib/cuprum/collections/adaptable.rb +13 -0
  11. data/lib/cuprum/collections/adapter.rb +300 -0
  12. data/lib/cuprum/collections/adapters/data_adapter.rb +82 -0
  13. data/lib/cuprum/collections/adapters/entity_adapter.rb +76 -0
  14. data/lib/cuprum/collections/adapters/hash_adapter.rb +48 -0
  15. data/lib/cuprum/collections/adapters.rb +14 -0
  16. data/lib/cuprum/collections/basic/collection.rb +2 -20
  17. data/lib/cuprum/collections/basic/commands/destroy_one.rb +1 -1
  18. data/lib/cuprum/collections/basic/commands/find_many.rb +0 -31
  19. data/lib/cuprum/collections/basic/commands/find_matching.rb +0 -94
  20. data/lib/cuprum/collections/basic/commands/find_one.rb +0 -18
  21. data/lib/cuprum/collections/basic/commands/insert_one.rb +1 -1
  22. data/lib/cuprum/collections/basic/commands/update_one.rb +1 -1
  23. data/lib/cuprum/collections/basic/scopes/criteria_scope.rb +36 -21
  24. data/lib/cuprum/collections/basic.rb +6 -5
  25. data/lib/cuprum/collections/collection.rb +6 -0
  26. data/lib/cuprum/collections/collection_command.rb +1 -1
  27. data/lib/cuprum/collections/commands/abstract_find_many.rb +40 -3
  28. data/lib/cuprum/collections/commands/abstract_find_matching.rb +102 -0
  29. data/lib/cuprum/collections/commands/abstract_find_one.rb +23 -1
  30. data/lib/cuprum/collections/commands/associations/find_many.rb +1 -3
  31. data/lib/cuprum/collections/commands/associations/require_many.rb +1 -1
  32. data/lib/cuprum/collections/commands/find_one_matching.rb +10 -10
  33. data/lib/cuprum/collections/commands/query_command.rb +6 -4
  34. data/lib/cuprum/collections/commands/upsert.rb +0 -2
  35. data/lib/cuprum/collections/constraints/order/attributes_array.rb +5 -4
  36. data/lib/cuprum/collections/constraints/order/attributes_hash.rb +5 -4
  37. data/lib/cuprum/collections/constraints/order/sort_direction.rb +2 -2
  38. data/lib/cuprum/collections/constraints/ordering.rb +11 -9
  39. data/lib/cuprum/collections/constraints/query_hash.rb +2 -2
  40. data/lib/cuprum/collections/errors/abstract_find_error.rb +101 -23
  41. data/lib/cuprum/collections/errors/extra_attributes.rb +3 -3
  42. data/lib/cuprum/collections/errors/failed_validation.rb +3 -3
  43. data/lib/cuprum/collections/errors/missing_default_contract.rb +12 -4
  44. data/lib/cuprum/collections/queries.rb +4 -0
  45. data/lib/cuprum/collections/relation.rb +0 -2
  46. data/lib/cuprum/collections/relations/parameters.rb +120 -68
  47. data/lib/cuprum/collections/repository.rb +71 -6
  48. data/lib/cuprum/collections/rspec/contracts/query_contracts.rb +23 -4
  49. data/lib/cuprum/collections/rspec/contracts/repository_contracts.rb +18 -0
  50. data/lib/cuprum/collections/rspec/contracts/scope_contracts.rb +51 -0
  51. data/lib/cuprum/collections/rspec/contracts/scopes/builder_contracts.rb +10 -0
  52. data/lib/cuprum/collections/rspec/contracts/scopes/composition_contracts.rb +8 -0
  53. data/lib/cuprum/collections/rspec/contracts/scopes/criteria_contracts.rb +18 -366
  54. data/lib/cuprum/collections/rspec/contracts/scopes/logical_contracts.rb +30 -0
  55. data/lib/cuprum/collections/rspec/contracts/scopes.rb +2 -0
  56. data/lib/cuprum/collections/rspec/contracts.rb +2 -10
  57. data/lib/cuprum/collections/rspec/deferred/adapter_examples.rb +1077 -0
  58. data/lib/cuprum/collections/rspec/deferred/collection_examples.rb +27 -7
  59. data/lib/cuprum/collections/rspec/deferred/commands/assign_one_examples.rb +4 -4
  60. data/lib/cuprum/collections/rspec/deferred/commands/build_one_examples.rb +2 -2
  61. data/lib/cuprum/collections/rspec/deferred/commands/destroy_one_examples.rb +2 -2
  62. data/lib/cuprum/collections/rspec/deferred/commands/find_many_examples.rb +5 -5
  63. data/lib/cuprum/collections/rspec/deferred/commands/find_matching_examples.rb +45 -12
  64. data/lib/cuprum/collections/rspec/deferred/commands/find_one_examples.rb +2 -2
  65. data/lib/cuprum/collections/rspec/deferred/commands/insert_one_examples.rb +1 -1
  66. data/lib/cuprum/collections/rspec/deferred/commands/update_one_examples.rb +1 -1
  67. data/lib/cuprum/collections/rspec/deferred/query_examples.rb +930 -0
  68. data/lib/cuprum/collections/rspec/deferred/relation_examples.rb +48 -17
  69. data/lib/cuprum/collections/rspec/deferred/repository_examples.rb +961 -0
  70. data/lib/cuprum/collections/rspec/deferred/scope_examples.rb +598 -0
  71. data/lib/cuprum/collections/rspec/deferred/scopes/all_examples.rb +391 -0
  72. data/lib/cuprum/collections/rspec/deferred/scopes/builder_examples.rb +857 -0
  73. data/lib/cuprum/collections/rspec/deferred/scopes/composition_examples.rb +93 -0
  74. data/lib/cuprum/collections/rspec/deferred/scopes/conjunction_examples.rb +438 -0
  75. data/lib/cuprum/collections/rspec/deferred/scopes/criteria_examples.rb +1941 -0
  76. data/lib/cuprum/collections/rspec/deferred/scopes/disjunction_examples.rb +415 -0
  77. data/lib/cuprum/collections/rspec/deferred/scopes/none_examples.rb +385 -0
  78. data/lib/cuprum/collections/rspec/deferred/scopes/parser_examples.rb +740 -0
  79. data/lib/cuprum/collections/rspec/deferred/scopes.rb +8 -0
  80. data/lib/cuprum/collections/scope.rb +2 -2
  81. data/lib/cuprum/collections/scopes/container.rb +5 -4
  82. data/lib/cuprum/collections/scopes/criteria/parser.rb +24 -48
  83. data/lib/cuprum/collections/scopes/criteria.rb +7 -6
  84. data/lib/cuprum/collections/version.rb +4 -4
  85. data/lib/cuprum/collections.rb +5 -1
  86. metadata +47 -11
  87. data/lib/cuprum/collections/rspec/contracts/association_contracts.rb +0 -2127
  88. data/lib/cuprum/collections/rspec/contracts/basic.rb +0 -11
  89. data/lib/cuprum/collections/rspec/contracts/collection_contracts.rb +0 -387
  90. data/lib/cuprum/collections/rspec/contracts/command_contracts.rb +0 -169
  91. data/lib/cuprum/collections/rspec/contracts/relation_contracts.rb +0 -1264
@@ -0,0 +1,391 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspec/sleeping_king_studios/deferred'
4
+
5
+ require 'cuprum/collections/rspec/deferred/scope_examples'
6
+ require 'cuprum/collections/rspec/deferred/scopes'
7
+
8
+ module Cuprum::Collections::RSpec::Deferred::Scopes
9
+ # Deferred examples for asserting on All scope objects.
10
+ module AllExamples
11
+ include RSpec::SleepingKingStudios::Deferred::Provider
12
+ include Cuprum::Collections::RSpec::Deferred::ScopeExamples
13
+
14
+ deferred_examples 'should implement the AllScope methods' \
15
+ do |**deferred_options|
16
+ include_deferred 'should implement the Scope methods'
17
+
18
+ include_deferred 'should compose Scopes as an AllScope'
19
+
20
+ unless deferred_options.fetch(:abstract, false)
21
+ include_deferred 'should match all data'
22
+ end
23
+
24
+ describe '#==' do
25
+ describe 'with a scope with the same class' do
26
+ let(:other) { described_class.new }
27
+
28
+ it { expect(subject == other).to be true }
29
+ end
30
+
31
+ describe 'with a scope with the same type' do
32
+ let(:other) { Spec::CustomScope.new }
33
+
34
+ example_class 'Spec::CustomScope', Cuprum::Collections::Scopes::Base \
35
+ do |klass|
36
+ klass.define_method(:type) { :all }
37
+ end
38
+
39
+ it { expect(subject == other).to be true }
40
+ end
41
+ end
42
+
43
+ describe '#as_json' do
44
+ let(:expected) { { 'type' => subject.type } }
45
+
46
+ it { expect(subject.as_json).to be == expected }
47
+ end
48
+
49
+ describe '#empty?' do
50
+ it { expect(subject.empty?).to be false }
51
+ end
52
+
53
+ describe '#invert' do
54
+ let(:expected) { Cuprum::Collections::Scopes::NoneScope.new }
55
+
56
+ it { expect(subject.invert).to be == expected }
57
+ end
58
+
59
+ describe '#type' do
60
+ it { expect(subject.type).to be :all }
61
+ end
62
+ end
63
+
64
+ deferred_examples 'should compose Scopes as an AllScope' do
65
+ describe '#and' do
66
+ it 'should define the method' do
67
+ expect(subject)
68
+ .to respond_to(:and)
69
+ .with(0..1).arguments
70
+ .and_a_block
71
+ end
72
+
73
+ it { expect(subject).to have_aliased_method(:and).as(:where) }
74
+
75
+ describe 'with a block' do
76
+ let(:block) { -> { { 'title' => 'A Wizard of Earthsea' } } }
77
+ let(:expected) do
78
+ Cuprum::Collections::Scope.new(&block)
79
+ end
80
+
81
+ it { expect(subject.and(&block)).to be == expected }
82
+ end
83
+
84
+ describe 'with a hash' do
85
+ let(:value) { { 'title' => 'A Wizard of Earthsea' } }
86
+ let(:expected) do
87
+ Cuprum::Collections::Scope.new(value)
88
+ end
89
+
90
+ it { expect(subject.and(value)).to be == expected }
91
+ end
92
+
93
+ describe 'with an all scope' do
94
+ let(:original) do
95
+ Cuprum::Collections::Scopes::AllScope.new
96
+ end
97
+
98
+ it { expect(subject.and(original)).to be == original }
99
+ end
100
+
101
+ describe 'with a none scope' do
102
+ let(:original) do
103
+ Cuprum::Collections::Scopes::NoneScope.new
104
+ end
105
+
106
+ it { expect(subject.and(original)).to be == original }
107
+ end
108
+
109
+ describe 'with an empty conjunction scope' do
110
+ let(:original) do
111
+ Cuprum::Collections::Scopes::ConjunctionScope.new(scopes: [])
112
+ end
113
+
114
+ it { expect(subject.and(original)).to be subject }
115
+ end
116
+
117
+ describe 'with an empty criteria scope' do
118
+ let(:original) do
119
+ Cuprum::Collections::Scopes::CriteriaScope.new(criteria: [])
120
+ end
121
+
122
+ it { expect(subject.and(original)).to be subject }
123
+ end
124
+
125
+ describe 'with an empty disjunction scope' do
126
+ let(:original) do
127
+ Cuprum::Collections::Scopes::DisjunctionScope.new(scopes: [])
128
+ end
129
+
130
+ it { expect(subject.and(original)).to be subject }
131
+ end
132
+
133
+ describe 'with a non-empty conjunction scope' do
134
+ let(:original) do
135
+ wrapped =
136
+ Cuprum::Collections::Scope
137
+ .new({ 'title' => 'A Wizard of Earthsea' })
138
+
139
+ Cuprum::Collections::Scopes::ConjunctionScope
140
+ .new(scopes: [wrapped])
141
+ end
142
+
143
+ it { expect(subject.and(original)).to be == original }
144
+ end
145
+
146
+ describe 'with a non-empty criteria scope' do
147
+ let(:original) do
148
+ Cuprum::Collections::Scope
149
+ .new({ 'title' => 'A Wizard of Earthsea' })
150
+ end
151
+
152
+ it { expect(subject.and(original)).to be == original }
153
+ end
154
+
155
+ describe 'with a non-empty disjunction scope' do
156
+ let(:original) do
157
+ wrapped =
158
+ Cuprum::Collections::Scope
159
+ .new({ 'title' => 'A Wizard of Earthsea' })
160
+
161
+ Cuprum::Collections::Scopes::DisjunctionScope
162
+ .new(scopes: [wrapped])
163
+ end
164
+
165
+ it { expect(subject.and(original)).to be == original }
166
+ end
167
+ end
168
+
169
+ describe '#not' do
170
+ it 'should define the method' do
171
+ expect(subject)
172
+ .to respond_to(:not)
173
+ .with(0..1).arguments
174
+ .and_a_block
175
+ end
176
+
177
+ describe 'with a block' do
178
+ let(:block) { -> { { 'title' => 'A Wizard of Earthsea' } } }
179
+ let(:expected) do
180
+ Cuprum::Collections::Scope.new(&block).invert
181
+ end
182
+
183
+ it { expect(subject.not(&block)).to be == expected }
184
+ end
185
+
186
+ describe 'with a hash' do
187
+ let(:value) { { 'title' => 'A Wizard of Earthsea' } }
188
+ let(:expected) do
189
+ Cuprum::Collections::Scope.new(value).invert
190
+ end
191
+
192
+ it { expect(subject.not(value)).to be == expected }
193
+ end
194
+
195
+ describe 'with an all scope' do
196
+ let(:original) do
197
+ Cuprum::Collections::Scopes::AllScope.new
198
+ end
199
+ let(:expected) do
200
+ Cuprum::Collections::Scopes::NoneScope.new
201
+ end
202
+
203
+ it { expect(subject.not(original)).to be == expected }
204
+ end
205
+
206
+ describe 'with a none scope' do
207
+ let(:original) do
208
+ Cuprum::Collections::Scopes::NoneScope.new
209
+ end
210
+
211
+ it { expect(subject.not(original)).to be == subject }
212
+ end
213
+
214
+ describe 'with an empty conjunction scope' do
215
+ let(:original) do
216
+ Cuprum::Collections::Scopes::ConjunctionScope.new(scopes: [])
217
+ end
218
+
219
+ it { expect(subject.not(original)).to be subject }
220
+ end
221
+
222
+ describe 'with an empty criteria scope' do
223
+ let(:original) do
224
+ Cuprum::Collections::Scopes::CriteriaScope.new(criteria: [])
225
+ end
226
+
227
+ it { expect(subject.not(original)).to be subject }
228
+ end
229
+
230
+ describe 'with an empty disjunction scope' do
231
+ let(:original) do
232
+ Cuprum::Collections::Scopes::DisjunctionScope.new(scopes: [])
233
+ end
234
+
235
+ it { expect(subject.not(original)).to be subject }
236
+ end
237
+
238
+ describe 'with a non-empty conjunction scope' do
239
+ let(:original) do
240
+ wrapped =
241
+ Cuprum::Collections::Scope
242
+ .new({ 'title' => 'A Wizard of Earthsea' })
243
+
244
+ Cuprum::Collections::Scopes::ConjunctionScope
245
+ .new(scopes: [wrapped])
246
+ end
247
+
248
+ it { expect(subject.not(original)).to be == original.invert }
249
+ end
250
+
251
+ describe 'with a non-empty criteria scope' do
252
+ let(:original) do
253
+ Cuprum::Collections::Scope
254
+ .new({ 'title' => 'A Wizard of Earthsea' })
255
+ end
256
+
257
+ it { expect(subject.not(original)).to be == original.invert }
258
+ end
259
+
260
+ describe 'with a non-empty disjunction scope' do
261
+ let(:original) do
262
+ wrapped =
263
+ Cuprum::Collections::Scope
264
+ .new({ 'title' => 'A Wizard of Earthsea' })
265
+
266
+ Cuprum::Collections::Scopes::DisjunctionScope
267
+ .new(scopes: [wrapped])
268
+ end
269
+
270
+ it { expect(subject.not(original)).to be == original.invert }
271
+ end
272
+ end
273
+
274
+ describe '#or' do
275
+ it 'should define the method' do
276
+ expect(subject)
277
+ .to respond_to(:or)
278
+ .with(0..1).arguments
279
+ .and_a_block
280
+ end
281
+
282
+ describe 'with a block' do
283
+ let(:block) { -> { { 'title' => 'A Wizard of Earthsea' } } }
284
+ let(:expected) do
285
+ Cuprum::Collections::Scope.new(&block)
286
+ end
287
+
288
+ it { expect(subject.or(&block)).to be == expected }
289
+ end
290
+
291
+ describe 'with a hash' do
292
+ let(:value) { { 'title' => 'A Wizard of Earthsea' } }
293
+ let(:expected) do
294
+ Cuprum::Collections::Scope.new(value)
295
+ end
296
+
297
+ it { expect(subject.or(value)).to be == expected }
298
+ end
299
+
300
+ describe 'with an all scope' do
301
+ let(:original) do
302
+ Cuprum::Collections::Scopes::AllScope.new
303
+ end
304
+
305
+ it { expect(subject.and(original)).to be == original }
306
+ end
307
+
308
+ describe 'with an empty conjunction scope' do
309
+ let(:original) do
310
+ Cuprum::Collections::Scopes::ConjunctionScope.new(scopes: [])
311
+ end
312
+
313
+ it { expect(subject.or(original)).to be subject }
314
+ end
315
+
316
+ describe 'with an empty criteria scope' do
317
+ let(:original) do
318
+ Cuprum::Collections::Scopes::CriteriaScope.new(criteria: [])
319
+ end
320
+
321
+ it { expect(subject.or(original)).to be subject }
322
+ end
323
+
324
+ describe 'with an empty disjunction scope' do
325
+ let(:original) do
326
+ Cuprum::Collections::Scopes::DisjunctionScope.new(scopes: [])
327
+ end
328
+
329
+ it { expect(subject.or(original)).to be subject }
330
+ end
331
+
332
+ describe 'with a non-empty conjunction scope' do
333
+ let(:original) do
334
+ wrapped =
335
+ Cuprum::Collections::Scope
336
+ .new({ 'title' => 'A Wizard of Earthsea' })
337
+
338
+ Cuprum::Collections::Scopes::ConjunctionScope
339
+ .new(scopes: [wrapped])
340
+ end
341
+
342
+ it { expect(subject.or(original)).to be == original }
343
+ end
344
+
345
+ describe 'with a non-empty criteria scope' do
346
+ let(:original) do
347
+ Cuprum::Collections::Scope
348
+ .new({ 'title' => 'A Wizard of Earthsea' })
349
+ end
350
+
351
+ it { expect(subject.or(original)).to be == original }
352
+ end
353
+
354
+ describe 'with a non-empty disjunction scope' do
355
+ let(:original) do
356
+ wrapped =
357
+ Cuprum::Collections::Scope
358
+ .new({ 'title' => 'A Wizard of Earthsea' })
359
+
360
+ Cuprum::Collections::Scopes::DisjunctionScope
361
+ .new(scopes: [wrapped])
362
+ end
363
+
364
+ it { expect(subject.or(original)).to be == original }
365
+ end
366
+ end
367
+ end
368
+
369
+ deferred_examples 'should match all data' do
370
+ describe '#call' do
371
+ shared_context 'with data' do
372
+ let(:data) do
373
+ Cuprum::Collections::RSpec::Fixtures::BOOKS_FIXTURES
374
+ end
375
+ end
376
+
377
+ describe 'with empty data' do
378
+ let(:data) { [] }
379
+
380
+ it { expect(filtered_data).to be == [] }
381
+ end
382
+
383
+ wrap_context 'with data' do
384
+ let(:expected) { data }
385
+
386
+ it { expect(filtered_data).to match_array expected }
387
+ end
388
+ end
389
+ end
390
+ end
391
+ end