cuprum-collections 0.4.0 → 0.5.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 (118) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +73 -0
  3. data/README.md +5 -5
  4. data/lib/cuprum/collections/association.rb +9 -28
  5. data/lib/cuprum/collections/associations/belongs_to.rb +1 -8
  6. data/lib/cuprum/collections/associations/has_many.rb +1 -10
  7. data/lib/cuprum/collections/associations/has_one.rb +1 -10
  8. data/lib/cuprum/collections/basic/collection.rb +56 -49
  9. data/lib/cuprum/collections/basic/command.rb +22 -88
  10. data/lib/cuprum/collections/basic/commands/assign_one.rb +2 -6
  11. data/lib/cuprum/collections/basic/commands/build_one.rb +1 -4
  12. data/lib/cuprum/collections/basic/commands/destroy_one.rb +4 -8
  13. data/lib/cuprum/collections/basic/commands/find_many.rb +4 -24
  14. data/lib/cuprum/collections/basic/commands/find_matching.rb +5 -21
  15. data/lib/cuprum/collections/basic/commands/find_one.rb +3 -20
  16. data/lib/cuprum/collections/basic/commands/insert_one.rb +3 -6
  17. data/lib/cuprum/collections/basic/commands/update_one.rb +3 -6
  18. data/lib/cuprum/collections/basic/commands/validate_one.rb +13 -18
  19. data/lib/cuprum/collections/basic/query.rb +26 -40
  20. data/lib/cuprum/collections/basic/repository.rb +4 -3
  21. data/lib/cuprum/collections/basic/scopes/all_scope.rb +25 -0
  22. data/lib/cuprum/collections/basic/scopes/base.rb +32 -0
  23. data/lib/cuprum/collections/basic/scopes/builder.rb +39 -0
  24. data/lib/cuprum/collections/basic/scopes/conjunction_scope.rb +20 -0
  25. data/lib/cuprum/collections/basic/scopes/criteria_scope.rb +62 -0
  26. data/lib/cuprum/collections/basic/scopes/disjunction_scope.rb +20 -0
  27. data/lib/cuprum/collections/basic/scopes/none_scope.rb +33 -0
  28. data/lib/cuprum/collections/basic/scopes.rb +23 -0
  29. data/lib/cuprum/collections/basic.rb +1 -0
  30. data/lib/cuprum/collections/collection.rb +24 -82
  31. data/lib/cuprum/collections/collection_command.rb +116 -0
  32. data/lib/cuprum/collections/commands/abstract_find_many.rb +11 -21
  33. data/lib/cuprum/collections/commands/abstract_find_matching.rb +43 -24
  34. data/lib/cuprum/collections/commands/abstract_find_one.rb +7 -10
  35. data/lib/cuprum/collections/commands/associations/find_many.rb +3 -8
  36. data/lib/cuprum/collections/commands/associations/require_many.rb +5 -5
  37. data/lib/cuprum/collections/commands/create.rb +3 -3
  38. data/lib/cuprum/collections/commands/find_one_matching.rb +6 -6
  39. data/lib/cuprum/collections/commands/query_command.rb +19 -0
  40. data/lib/cuprum/collections/commands/update.rb +3 -3
  41. data/lib/cuprum/collections/commands/upsert.rb +10 -10
  42. data/lib/cuprum/collections/commands.rb +1 -0
  43. data/lib/cuprum/collections/constraints/ordering.rb +2 -2
  44. data/lib/cuprum/collections/errors/abstract_find_error.rb +25 -42
  45. data/lib/cuprum/collections/errors/extra_attributes.rb +3 -3
  46. data/lib/cuprum/collections/errors/failed_validation.rb +2 -2
  47. data/lib/cuprum/collections/errors/invalid_parameters.rb +2 -2
  48. data/lib/cuprum/collections/errors/invalid_query.rb +10 -16
  49. data/lib/cuprum/collections/errors/missing_default_contract.rb +1 -1
  50. data/lib/cuprum/collections/errors/unknown_operator.rb +1 -1
  51. data/lib/cuprum/collections/queries.rb +31 -0
  52. data/lib/cuprum/collections/query.rb +50 -62
  53. data/lib/cuprum/collections/relation.rb +5 -383
  54. data/lib/cuprum/collections/relations/cardinality.rb +66 -0
  55. data/lib/cuprum/collections/relations/options.rb +18 -0
  56. data/lib/cuprum/collections/relations/parameters.rb +217 -0
  57. data/lib/cuprum/collections/relations/primary_keys.rb +23 -0
  58. data/lib/cuprum/collections/relations/scope.rb +65 -0
  59. data/lib/cuprum/collections/relations.rb +14 -0
  60. data/lib/cuprum/collections/repository.rb +5 -5
  61. data/lib/cuprum/collections/resource.rb +10 -41
  62. data/lib/cuprum/collections/rspec/contracts/association_contracts.rb +80 -90
  63. data/lib/cuprum/collections/rspec/contracts/collection_contracts.rb +69 -111
  64. data/lib/cuprum/collections/rspec/contracts/command_contracts.rb +42 -1335
  65. data/lib/cuprum/collections/rspec/contracts/query_contracts.rb +352 -531
  66. data/lib/cuprum/collections/rspec/contracts/relation_contracts.rb +74 -191
  67. data/lib/cuprum/collections/rspec/contracts/repository_contracts.rb +13 -13
  68. data/lib/cuprum/collections/rspec/contracts/scope_contracts.rb +1029 -0
  69. data/lib/cuprum/collections/rspec/contracts/scopes/builder_contracts.rb +856 -0
  70. data/lib/cuprum/collections/rspec/contracts/scopes/composition_contracts.rb +1430 -0
  71. data/lib/cuprum/collections/rspec/contracts/scopes/criteria_contracts.rb +2217 -0
  72. data/lib/cuprum/collections/rspec/contracts/scopes/logical_contracts.rb +297 -0
  73. data/lib/cuprum/collections/rspec/contracts/scopes.rb +13 -0
  74. data/lib/cuprum/collections/rspec/contracts.rb +2 -0
  75. data/lib/cuprum/collections/rspec/deferred/association_examples.rb +2098 -0
  76. data/lib/cuprum/collections/rspec/deferred/collection_examples.rb +338 -0
  77. data/lib/cuprum/collections/rspec/deferred/command_examples.rb +160 -0
  78. data/lib/cuprum/collections/rspec/deferred/commands/assign_one_examples.rb +178 -0
  79. data/lib/cuprum/collections/rspec/deferred/commands/build_one_examples.rb +94 -0
  80. data/lib/cuprum/collections/rspec/deferred/commands/destroy_one_examples.rb +118 -0
  81. data/lib/cuprum/collections/rspec/deferred/commands/find_many_examples.rb +307 -0
  82. data/lib/cuprum/collections/rspec/deferred/commands/find_matching_examples.rb +143 -0
  83. data/lib/cuprum/collections/rspec/deferred/commands/find_one_examples.rb +116 -0
  84. data/lib/cuprum/collections/rspec/deferred/commands/insert_one_examples.rb +103 -0
  85. data/lib/cuprum/collections/rspec/deferred/commands/update_one_examples.rb +99 -0
  86. data/lib/cuprum/collections/rspec/deferred/commands/validate_one_examples.rb +117 -0
  87. data/lib/cuprum/collections/rspec/deferred/commands.rb +8 -0
  88. data/lib/cuprum/collections/rspec/deferred/relation_examples.rb +1437 -0
  89. data/lib/cuprum/collections/rspec/deferred/resource_examples.rb +26 -0
  90. data/lib/cuprum/collections/rspec/deferred.rb +8 -0
  91. data/lib/cuprum/collections/scope.rb +29 -0
  92. data/lib/cuprum/collections/scopes/all.rb +51 -0
  93. data/lib/cuprum/collections/scopes/all_scope.rb +18 -0
  94. data/lib/cuprum/collections/scopes/base.rb +79 -0
  95. data/lib/cuprum/collections/scopes/builder.rb +39 -0
  96. data/lib/cuprum/collections/scopes/building.rb +221 -0
  97. data/lib/cuprum/collections/scopes/composition.rb +162 -0
  98. data/lib/cuprum/collections/scopes/conjunction.rb +44 -0
  99. data/lib/cuprum/collections/scopes/conjunction_scope.rb +12 -0
  100. data/lib/cuprum/collections/scopes/container.rb +65 -0
  101. data/lib/cuprum/collections/scopes/criteria/parser.rb +241 -0
  102. data/lib/cuprum/collections/scopes/criteria.rb +206 -0
  103. data/lib/cuprum/collections/scopes/criteria_scope.rb +12 -0
  104. data/lib/cuprum/collections/scopes/disjunction.rb +45 -0
  105. data/lib/cuprum/collections/scopes/disjunction_scope.rb +12 -0
  106. data/lib/cuprum/collections/scopes/none.rb +62 -0
  107. data/lib/cuprum/collections/scopes/none_scope.rb +18 -0
  108. data/lib/cuprum/collections/scopes.rb +23 -0
  109. data/lib/cuprum/collections/version.rb +2 -2
  110. data/lib/cuprum/collections.rb +14 -9
  111. metadata +61 -15
  112. data/lib/cuprum/collections/basic/query_builder.rb +0 -69
  113. data/lib/cuprum/collections/command.rb +0 -26
  114. data/lib/cuprum/collections/queries/parse.rb +0 -22
  115. data/lib/cuprum/collections/queries/parse_block.rb +0 -206
  116. data/lib/cuprum/collections/queries/parse_strategy.rb +0 -91
  117. data/lib/cuprum/collections/query_builder.rb +0 -61
  118. data/lib/cuprum/collections/rspec/contracts/basic/command_contracts.rb +0 -484
@@ -5,6 +5,9 @@ require 'cuprum/collections/rspec/contracts/relation_contracts'
5
5
 
6
6
  module Cuprum::Collections::RSpec::Contracts
7
7
  # Contracts for asserting on Collection objects.
8
+ #
9
+ # @deprecated 0.5.0 Collection contracts are deprecated. Use
10
+ # Deferred::CollectionExamples instead.
8
11
  module CollectionContracts
9
12
  include Cuprum::Collections::RSpec::Contracts::RelationContracts
10
13
 
@@ -25,88 +28,36 @@ module Cuprum::Collections::RSpec::Contracts
25
28
  # for the collection, if any.
26
29
 
27
30
  contract do |**options|
31
+ shared_context 'when initialized with a scope' do
32
+ let(:initial_scope) do
33
+ Cuprum::Collections::Scope.new({ 'ok' => true })
34
+ end
35
+ let(:constructor_options) do
36
+ super().merge(scope: initial_scope)
37
+ end
38
+ end
39
+
28
40
  shared_examples 'should define the command' \
29
41
  do |command_name, command_class_name = nil|
30
42
  next if options[:abstract]
31
43
 
32
- tools = SleepingKingStudios::Tools::Toolbelt.instance
33
- class_name = tools.str.camelize(command_name)
34
- command_options = %i[
35
- collection_name
36
- member_name
37
- primary_key_name
38
- primary_key_type
39
- ] + options.fetch(:command_options, []).map(&:intern)
44
+ tools = SleepingKingStudios::Tools::Toolbelt.instance
45
+ class_name = tools.str.camelize(command_name)
40
46
 
41
- describe "::#{class_name}" do
47
+ describe "##{command_name}" do
42
48
  let(:constructor_options) { defined?(super()) ? super() : {} }
49
+ let(:command) { build_command(collection) }
43
50
  let(:command_class) do
44
- command_class_name ||
51
+ (
52
+ command_class_name ||
45
53
  "#{options[:commands_namespace]}::#{class_name}"
46
- .then { |str| Object.const_get(str) }
47
- end
48
- let(:command) do
49
- collection.const_get(class_name).new(**constructor_options)
50
- end
51
- let(:expected_options) do
52
- Hash
53
- .new { |_, key| collection.send(key) }
54
- .merge(
55
- collection_name: collection.name,
56
- member_name: collection.singular_name
57
- )
58
- end
59
-
60
- it { expect(collection).to define_constant(class_name) }
61
-
62
- it { expect(collection.const_get(class_name)).to be_a Class }
63
-
64
- it 'should be an instance of the command class' do
65
- expect(collection.const_get(class_name)).to be < command_class
66
- end
67
-
68
- it { expect(command.options).to be >= {} }
69
-
70
- command_options.each do |option_name|
71
- it "should set the ##{option_name}" do
72
- expect(command.send(option_name))
73
- .to be == expected_options[option_name]
74
- end
75
- end
76
-
77
- describe 'with options' do
78
- let(:constructor_options) do
79
- super().merge(
80
- custom_option: 'value',
81
- singular_name: 'tome'
82
- )
83
- end
84
-
85
- it { expect(command.options).to be >= { custom_option: 'value' } }
86
-
87
- command_options.each do |option_name|
88
- it "should set the ##{option_name}" do
89
- expect(command.send(option_name)).to(
90
- be == expected_options[option_name]
91
- )
92
- end
93
- end
54
+ )
55
+ .then { |str| Object.const_get(str) }
94
56
  end
95
- end
96
57
 
97
- describe "##{command_name}" do
98
- let(:constructor_options) { defined?(super()) ? super() : {} }
99
- let(:command) do
58
+ define_method(:build_command) do |collection|
100
59
  collection.send(command_name, **constructor_options)
101
60
  end
102
- let(:expected_options) do
103
- Hash
104
- .new { |_, key| collection.send(key) }
105
- .merge(
106
- collection_name: collection.name,
107
- member_name: collection.singular_name
108
- )
109
- end
110
61
 
111
62
  it 'should define the command' do
112
63
  expect(collection)
@@ -115,33 +66,9 @@ module Cuprum::Collections::RSpec::Contracts
115
66
  .and_any_keywords
116
67
  end
117
68
 
118
- it { expect(command).to be_a collection.const_get(class_name) }
69
+ it { expect(command).to be_a command_class }
119
70
 
120
- command_options.each do |option_name|
121
- it "should set the ##{option_name}" do
122
- expect(command.send(option_name))
123
- .to be == expected_options[option_name]
124
- end
125
- end
126
-
127
- describe 'with options' do
128
- let(:constructor_options) do
129
- super().merge(
130
- custom_option: 'value',
131
- singular_name: 'tome'
132
- )
133
- end
134
-
135
- it { expect(command.options).to be >= { custom_option: 'value' } }
136
-
137
- command_options.each do |option_name|
138
- it "should set the ##{option_name}" do
139
- expect(command.send(option_name)).to(
140
- be == expected_options[option_name]
141
- )
142
- end
143
- end
144
- end
71
+ it { expect(command.collection).to be subject }
145
72
  end
146
73
  end
147
74
 
@@ -149,14 +76,6 @@ module Cuprum::Collections::RSpec::Contracts
149
76
  constructor: false,
150
77
  default_entity_class: options[:default_entity_class]
151
78
 
152
- include_contract 'should disambiguate parameter',
153
- :name,
154
- as: :collection_name
155
-
156
- include_contract 'should disambiguate parameter',
157
- :singular_name,
158
- as: :member_name
159
-
160
79
  include_contract 'should define primary keys'
161
80
 
162
81
  include_examples 'should define the command', :assign_one
@@ -178,7 +97,7 @@ module Cuprum::Collections::RSpec::Contracts
178
97
  include_examples 'should define the command', :validate_one
179
98
 
180
99
  describe '#==' do
181
- let(:other_options) { { name: name } }
100
+ let(:other_options) { { name: } }
182
101
  let(:other_collection) { described_class.new(**other_options) }
183
102
 
184
103
  describe 'with nil' do
@@ -314,7 +233,7 @@ module Cuprum::Collections::RSpec::Contracts
314
233
  describe 'with partially-matching options' do
315
234
  let(:other_options) do
316
235
  {
317
- name: name,
236
+ name:,
318
237
  singular_name: 'grimoire'
319
238
  }
320
239
  end
@@ -343,7 +262,7 @@ module Cuprum::Collections::RSpec::Contracts
343
262
  end
344
263
 
345
264
  describe 'with matching name' do
346
- let(:other_options) { { collection_name: name } }
265
+ let(:other_options) { { name: } }
347
266
 
348
267
  it { expect(collection.matches?(**other_options)).to be true }
349
268
  end
@@ -377,7 +296,7 @@ module Cuprum::Collections::RSpec::Contracts
377
296
  describe 'with multiple matching options' do
378
297
  let(:other_options) do
379
298
  {
380
- collection_name: name,
299
+ name:,
381
300
  primary_key_name: 'id',
382
301
  qualified_name: name
383
302
  }
@@ -390,7 +309,7 @@ module Cuprum::Collections::RSpec::Contracts
390
309
  describe '#query' do
391
310
  let(:error_message) do
392
311
  "#{described_class.name} is an abstract class. Define a " \
393
- 'repository subclass and implement the #query method.'
312
+ 'collection subclass and implement the #query method.'
394
313
  end
395
314
  let(:default_order) { defined?(super()) ? super() : {} }
396
315
  let(:query) { collection.query }
@@ -414,13 +333,52 @@ module Cuprum::Collections::RSpec::Contracts
414
333
  end
415
334
  end
416
335
 
417
- it { expect(query.criteria).to be == [] }
418
-
419
336
  it { expect(query.limit).to be nil }
420
337
 
421
338
  it { expect(query.offset).to be nil }
422
339
 
423
340
  it { expect(query.order).to be == default_order }
341
+
342
+ it { expect(query.scope).to be == subject.scope }
343
+
344
+ wrap_context 'when initialized with a scope' do
345
+ it { expect(query.scope).to be == subject.scope }
346
+ end
347
+ end
348
+ end
349
+
350
+ describe '#scope' do
351
+ let(:expected) do
352
+ Cuprum::Collections::Scopes::AllScope.new
353
+ end
354
+
355
+ include_examples 'should define reader', :scope, -> { be == expected }
356
+
357
+ wrap_context 'when initialized with a scope' do
358
+ it { expect(subject.scope).to be == initial_scope }
359
+ end
360
+ end
361
+
362
+ describe '#with_scope' do
363
+ let(:other_scope) do
364
+ Cuprum::Collections::Scope.new({ 'secret' => '12345' })
365
+ end
366
+ let(:copy) { subject.with_scope(other_scope) }
367
+
368
+ it { expect(subject).to respond_to(:with_scope).with(1).argument }
369
+
370
+ it { expect(copy).to be_a described_class }
371
+
372
+ it { expect(copy).not_to be subject }
373
+
374
+ it { expect(copy.scope).to be == other_scope }
375
+
376
+ wrap_context 'when initialized with a scope' do
377
+ let(:expected) do
378
+ initial_scope.and(other_scope)
379
+ end
380
+
381
+ it { expect(copy.scope).to be == expected }
424
382
  end
425
383
  end
426
384
  end