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,385 @@
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 None scope objects.
10
+ module NoneExamples
11
+ include RSpec::SleepingKingStudios::Deferred::Provider
12
+ include Cuprum::Collections::RSpec::Deferred::ScopeExamples
13
+
14
+ deferred_examples 'should implement the NoneScope methods' \
15
+ do |**deferred_options|
16
+ include_deferred 'should implement the Scope methods'
17
+
18
+ include_deferred 'should compose Scopes as a NoneScope'
19
+
20
+ unless deferred_options.fetch(:abstract, false)
21
+ include_deferred 'should match no 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',
35
+ Cuprum::Collections::Scopes::Base \
36
+ do |klass|
37
+ klass.define_method(:type) { :none }
38
+ end
39
+
40
+ it { expect(subject == other).to be true }
41
+ end
42
+ end
43
+
44
+ describe '#as_json' do
45
+ let(:expected) { { 'type' => subject.type } }
46
+
47
+ it { expect(subject.as_json).to be == expected }
48
+ end
49
+
50
+ describe '#empty?' do
51
+ it { expect(subject.empty?).to be false }
52
+ end
53
+
54
+ describe '#invert' do
55
+ let(:expected) { Cuprum::Collections::Scopes::AllScope.new }
56
+
57
+ it { expect(subject.invert).to be == expected }
58
+ end
59
+
60
+ describe '#type' do
61
+ it { expect(subject.type).to be :none }
62
+ end
63
+ end
64
+
65
+ deferred_examples 'should compose Scopes as a NoneScope' do
66
+ describe '#and' do
67
+ it 'should define the method' do
68
+ expect(subject)
69
+ .to respond_to(:and)
70
+ .with(0..1).arguments
71
+ .and_a_block
72
+ end
73
+
74
+ it { expect(subject).to have_aliased_method(:and).as(:where) }
75
+
76
+ describe 'with a block' do
77
+ let(:block) { -> { { 'title' => 'A Wizard of Earthsea' } } }
78
+
79
+ it { expect(subject.and(&block)).to be subject }
80
+ end
81
+
82
+ describe 'with a hash' do
83
+ let(:value) { { 'title' => 'A Wizard of Earthsea' } }
84
+
85
+ it { expect(subject.and(value)).to be subject }
86
+ end
87
+
88
+ describe 'with an all scope' do
89
+ let(:original) do
90
+ Cuprum::Collections::Scopes::AllScope.new
91
+ end
92
+
93
+ it { expect(subject.and(original)).to be subject }
94
+ end
95
+
96
+ describe 'with a none scope' do
97
+ let(:original) do
98
+ Cuprum::Collections::Scopes::NoneScope.new
99
+ end
100
+
101
+ it { expect(subject.and(original)).to be subject }
102
+ end
103
+
104
+ describe 'with an empty conjunction scope' do
105
+ let(:original) do
106
+ Cuprum::Collections::Scopes::ConjunctionScope.new(scopes: [])
107
+ end
108
+
109
+ it { expect(subject.and(original)).to be subject }
110
+ end
111
+
112
+ describe 'with an empty criteria scope' do
113
+ let(:original) do
114
+ Cuprum::Collections::Scopes::CriteriaScope.new(criteria: [])
115
+ end
116
+
117
+ it { expect(subject.and(original)).to be subject }
118
+ end
119
+
120
+ describe 'with an empty disjunction scope' do
121
+ let(:original) do
122
+ Cuprum::Collections::Scopes::DisjunctionScope.new(scopes: [])
123
+ end
124
+
125
+ it { expect(subject.and(original)).to be subject }
126
+ end
127
+
128
+ describe 'with a non-empty conjunction scope' do
129
+ let(:original) do
130
+ wrapped =
131
+ Cuprum::Collections::Scope
132
+ .new({ 'title' => 'A Wizard of Earthsea' })
133
+
134
+ Cuprum::Collections::Scopes::ConjunctionScope
135
+ .new(scopes: [wrapped])
136
+ end
137
+
138
+ it { expect(subject.and(original)).to be subject }
139
+ end
140
+
141
+ describe 'with a non-empty criteria scope' do
142
+ let(:original) do
143
+ Cuprum::Collections::Scope
144
+ .new({ 'title' => 'A Wizard of Earthsea' })
145
+ end
146
+
147
+ it { expect(subject.and(original)).to be subject }
148
+ end
149
+
150
+ describe 'with a non-empty disjunction scope' do
151
+ let(:original) do
152
+ wrapped =
153
+ Cuprum::Collections::Scope
154
+ .new({ 'title' => 'A Wizard of Earthsea' })
155
+
156
+ Cuprum::Collections::Scopes::DisjunctionScope
157
+ .new(scopes: [wrapped])
158
+ end
159
+
160
+ it { expect(subject.and(original)).to be subject }
161
+ end
162
+ end
163
+
164
+ describe '#not' do
165
+ it 'should define the method' do
166
+ expect(subject)
167
+ .to respond_to(:not)
168
+ .with(0..1).arguments
169
+ .and_a_block
170
+ end
171
+
172
+ describe 'with a block' do
173
+ let(:block) { -> { { 'title' => 'A Wizard of Earthsea' } } }
174
+
175
+ it { expect(subject.not(&block)).to be subject }
176
+ end
177
+
178
+ describe 'with a hash' do
179
+ let(:value) { { 'title' => 'A Wizard of Earthsea' } }
180
+
181
+ it { expect(subject.not(value)).to be subject }
182
+ end
183
+
184
+ describe 'with an all scope' do
185
+ let(:original) do
186
+ Cuprum::Collections::Scopes::AllScope.new
187
+ end
188
+
189
+ it { expect(subject.not(original)).to be subject }
190
+ end
191
+
192
+ describe 'with a none scope' do
193
+ let(:original) do
194
+ Cuprum::Collections::Scopes::AllScope.new
195
+ end
196
+
197
+ it { expect(subject.not(original)).to be subject }
198
+ end
199
+
200
+ describe 'with an empty conjunction scope' do
201
+ let(:original) do
202
+ Cuprum::Collections::Scopes::ConjunctionScope.new(scopes: [])
203
+ end
204
+
205
+ it { expect(subject.not(original)).to be subject }
206
+ end
207
+
208
+ describe 'with an empty criteria scope' do
209
+ let(:original) do
210
+ Cuprum::Collections::Scopes::CriteriaScope.new(criteria: [])
211
+ end
212
+
213
+ it { expect(subject.not(original)).to be subject }
214
+ end
215
+
216
+ describe 'with an empty disjunction scope' do
217
+ let(:original) do
218
+ Cuprum::Collections::Scopes::DisjunctionScope.new(scopes: [])
219
+ end
220
+
221
+ it { expect(subject.not(original)).to be subject }
222
+ end
223
+
224
+ describe 'with a non-empty conjunction scope' do
225
+ let(:original) do
226
+ wrapped =
227
+ Cuprum::Collections::Scope
228
+ .new({ 'title' => 'A Wizard of Earthsea' })
229
+
230
+ Cuprum::Collections::Scopes::ConjunctionScope
231
+ .new(scopes: [wrapped])
232
+ end
233
+
234
+ it { expect(subject.not(original)).to be subject }
235
+ end
236
+
237
+ describe 'with a non-empty criteria scope' do
238
+ let(:original) do
239
+ Cuprum::Collections::Scope
240
+ .new({ 'title' => 'A Wizard of Earthsea' })
241
+ end
242
+
243
+ it { expect(subject.not(original)).to be subject }
244
+ end
245
+
246
+ describe 'with a non-empty disjunction scope' do
247
+ let(:original) do
248
+ wrapped =
249
+ Cuprum::Collections::Scope
250
+ .new({ 'title' => 'A Wizard of Earthsea' })
251
+
252
+ Cuprum::Collections::Scopes::DisjunctionScope
253
+ .new(scopes: [wrapped])
254
+ end
255
+
256
+ it { expect(subject.not(original)).to be subject }
257
+ end
258
+ end
259
+
260
+ describe '#or' do
261
+ it 'should define the method' do
262
+ expect(subject)
263
+ .to respond_to(:or)
264
+ .with(0..1).arguments
265
+ .and_a_block
266
+ end
267
+
268
+ describe 'with a block' do
269
+ let(:block) { -> { { 'title' => 'A Wizard of Earthsea' } } }
270
+ let(:expected) do
271
+ Cuprum::Collections::Scope.new(&block)
272
+ end
273
+
274
+ it { expect(subject.or(&block)).to be == expected }
275
+ end
276
+
277
+ describe 'with a hash' do
278
+ let(:value) { { 'title' => 'A Wizard of Earthsea' } }
279
+ let(:expected) do
280
+ Cuprum::Collections::Scope.new(value)
281
+ end
282
+
283
+ it { expect(subject.or(value)).to be == expected }
284
+ end
285
+
286
+ describe 'with an all scope' do
287
+ let(:original) do
288
+ Cuprum::Collections::Scopes::AllScope.new
289
+ end
290
+
291
+ it { expect(subject.or(original)).to be == original }
292
+ end
293
+
294
+ describe 'with a none scope' do
295
+ let(:original) do
296
+ Cuprum::Collections::Scopes::NoneScope.new
297
+ end
298
+
299
+ it { expect(subject.or(original)).to be == original }
300
+ end
301
+
302
+ describe 'with an empty conjunction scope' do
303
+ let(:original) do
304
+ Cuprum::Collections::Scopes::ConjunctionScope.new(scopes: [])
305
+ end
306
+
307
+ it { expect(subject.or(original)).to be subject }
308
+ end
309
+
310
+ describe 'with an empty criteria scope' do
311
+ let(:original) do
312
+ Cuprum::Collections::Scopes::CriteriaScope.new(criteria: [])
313
+ end
314
+
315
+ it { expect(subject.or(original)).to be subject }
316
+ end
317
+
318
+ describe 'with an empty disjunction scope' do
319
+ let(:original) do
320
+ Cuprum::Collections::Scopes::DisjunctionScope.new(scopes: [])
321
+ end
322
+
323
+ it { expect(subject.or(original)).to be subject }
324
+ end
325
+
326
+ describe 'with a non-empty conjunction scope' do
327
+ let(:original) do
328
+ wrapped =
329
+ Cuprum::Collections::Scope
330
+ .new({ 'title' => 'A Wizard of Earthsea' })
331
+
332
+ Cuprum::Collections::Scopes::ConjunctionScope
333
+ .new(scopes: [wrapped])
334
+ end
335
+
336
+ it { expect(subject.or(original)).to be == original }
337
+ end
338
+
339
+ describe 'with a non-empty criteria scope' do
340
+ let(:original) do
341
+ Cuprum::Collections::Scope
342
+ .new({ 'title' => 'A Wizard of Earthsea' })
343
+ end
344
+
345
+ it { expect(subject.or(original)).to be == original }
346
+ end
347
+
348
+ describe 'with a non-empty disjunction scope' do
349
+ let(:original) do
350
+ wrapped =
351
+ Cuprum::Collections::Scope
352
+ .new({ 'title' => 'A Wizard of Earthsea' })
353
+
354
+ Cuprum::Collections::Scopes::DisjunctionScope
355
+ .new(scopes: [wrapped])
356
+ end
357
+
358
+ it { expect(subject.or(original)).to be == original }
359
+ end
360
+ end
361
+ end
362
+
363
+ deferred_examples 'should match no data' do
364
+ describe '#call' do
365
+ shared_context 'with data' do
366
+ let(:data) do
367
+ Cuprum::Collections::RSpec::Fixtures::BOOKS_FIXTURES
368
+ end
369
+ end
370
+
371
+ describe 'with empty data' do
372
+ let(:data) { [] }
373
+
374
+ it { expect(filtered_data).to be == [] }
375
+ end
376
+
377
+ wrap_context 'with data' do
378
+ let(:expected) { [] }
379
+
380
+ it { expect(filtered_data).to match_array expected }
381
+ end
382
+ end
383
+ end
384
+ end
385
+ end