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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +73 -0
- data/README.md +5 -5
- data/lib/cuprum/collections/association.rb +9 -28
- data/lib/cuprum/collections/associations/belongs_to.rb +1 -8
- data/lib/cuprum/collections/associations/has_many.rb +1 -10
- data/lib/cuprum/collections/associations/has_one.rb +1 -10
- data/lib/cuprum/collections/basic/collection.rb +56 -49
- data/lib/cuprum/collections/basic/command.rb +22 -88
- data/lib/cuprum/collections/basic/commands/assign_one.rb +2 -6
- data/lib/cuprum/collections/basic/commands/build_one.rb +1 -4
- data/lib/cuprum/collections/basic/commands/destroy_one.rb +4 -8
- data/lib/cuprum/collections/basic/commands/find_many.rb +4 -24
- data/lib/cuprum/collections/basic/commands/find_matching.rb +5 -21
- data/lib/cuprum/collections/basic/commands/find_one.rb +3 -20
- data/lib/cuprum/collections/basic/commands/insert_one.rb +3 -6
- data/lib/cuprum/collections/basic/commands/update_one.rb +3 -6
- data/lib/cuprum/collections/basic/commands/validate_one.rb +13 -18
- data/lib/cuprum/collections/basic/query.rb +26 -40
- data/lib/cuprum/collections/basic/repository.rb +4 -3
- data/lib/cuprum/collections/basic/scopes/all_scope.rb +25 -0
- data/lib/cuprum/collections/basic/scopes/base.rb +32 -0
- data/lib/cuprum/collections/basic/scopes/builder.rb +39 -0
- data/lib/cuprum/collections/basic/scopes/conjunction_scope.rb +20 -0
- data/lib/cuprum/collections/basic/scopes/criteria_scope.rb +62 -0
- data/lib/cuprum/collections/basic/scopes/disjunction_scope.rb +20 -0
- data/lib/cuprum/collections/basic/scopes/none_scope.rb +33 -0
- data/lib/cuprum/collections/basic/scopes.rb +23 -0
- data/lib/cuprum/collections/basic.rb +1 -0
- data/lib/cuprum/collections/collection.rb +24 -82
- data/lib/cuprum/collections/collection_command.rb +116 -0
- data/lib/cuprum/collections/commands/abstract_find_many.rb +11 -21
- data/lib/cuprum/collections/commands/abstract_find_matching.rb +43 -24
- data/lib/cuprum/collections/commands/abstract_find_one.rb +7 -10
- data/lib/cuprum/collections/commands/associations/find_many.rb +3 -8
- data/lib/cuprum/collections/commands/associations/require_many.rb +5 -5
- data/lib/cuprum/collections/commands/create.rb +3 -3
- data/lib/cuprum/collections/commands/find_one_matching.rb +6 -6
- data/lib/cuprum/collections/commands/query_command.rb +19 -0
- data/lib/cuprum/collections/commands/update.rb +3 -3
- data/lib/cuprum/collections/commands/upsert.rb +10 -10
- data/lib/cuprum/collections/commands.rb +1 -0
- data/lib/cuprum/collections/constraints/ordering.rb +2 -2
- data/lib/cuprum/collections/errors/abstract_find_error.rb +25 -42
- data/lib/cuprum/collections/errors/extra_attributes.rb +3 -3
- data/lib/cuprum/collections/errors/failed_validation.rb +2 -2
- data/lib/cuprum/collections/errors/invalid_parameters.rb +2 -2
- data/lib/cuprum/collections/errors/invalid_query.rb +10 -16
- data/lib/cuprum/collections/errors/missing_default_contract.rb +1 -1
- data/lib/cuprum/collections/errors/unknown_operator.rb +1 -1
- data/lib/cuprum/collections/queries.rb +31 -0
- data/lib/cuprum/collections/query.rb +50 -62
- data/lib/cuprum/collections/relation.rb +5 -383
- data/lib/cuprum/collections/relations/cardinality.rb +66 -0
- data/lib/cuprum/collections/relations/options.rb +18 -0
- data/lib/cuprum/collections/relations/parameters.rb +217 -0
- data/lib/cuprum/collections/relations/primary_keys.rb +23 -0
- data/lib/cuprum/collections/relations/scope.rb +65 -0
- data/lib/cuprum/collections/relations.rb +14 -0
- data/lib/cuprum/collections/repository.rb +5 -5
- data/lib/cuprum/collections/resource.rb +10 -41
- data/lib/cuprum/collections/rspec/contracts/association_contracts.rb +80 -90
- data/lib/cuprum/collections/rspec/contracts/collection_contracts.rb +69 -111
- data/lib/cuprum/collections/rspec/contracts/command_contracts.rb +42 -1335
- data/lib/cuprum/collections/rspec/contracts/query_contracts.rb +352 -531
- data/lib/cuprum/collections/rspec/contracts/relation_contracts.rb +74 -191
- data/lib/cuprum/collections/rspec/contracts/repository_contracts.rb +13 -13
- data/lib/cuprum/collections/rspec/contracts/scope_contracts.rb +1029 -0
- data/lib/cuprum/collections/rspec/contracts/scopes/builder_contracts.rb +856 -0
- data/lib/cuprum/collections/rspec/contracts/scopes/composition_contracts.rb +1430 -0
- data/lib/cuprum/collections/rspec/contracts/scopes/criteria_contracts.rb +2217 -0
- data/lib/cuprum/collections/rspec/contracts/scopes/logical_contracts.rb +297 -0
- data/lib/cuprum/collections/rspec/contracts/scopes.rb +13 -0
- data/lib/cuprum/collections/rspec/contracts.rb +2 -0
- data/lib/cuprum/collections/rspec/deferred/association_examples.rb +2098 -0
- data/lib/cuprum/collections/rspec/deferred/collection_examples.rb +338 -0
- data/lib/cuprum/collections/rspec/deferred/command_examples.rb +160 -0
- data/lib/cuprum/collections/rspec/deferred/commands/assign_one_examples.rb +178 -0
- data/lib/cuprum/collections/rspec/deferred/commands/build_one_examples.rb +94 -0
- data/lib/cuprum/collections/rspec/deferred/commands/destroy_one_examples.rb +118 -0
- data/lib/cuprum/collections/rspec/deferred/commands/find_many_examples.rb +307 -0
- data/lib/cuprum/collections/rspec/deferred/commands/find_matching_examples.rb +143 -0
- data/lib/cuprum/collections/rspec/deferred/commands/find_one_examples.rb +116 -0
- data/lib/cuprum/collections/rspec/deferred/commands/insert_one_examples.rb +103 -0
- data/lib/cuprum/collections/rspec/deferred/commands/update_one_examples.rb +99 -0
- data/lib/cuprum/collections/rspec/deferred/commands/validate_one_examples.rb +117 -0
- data/lib/cuprum/collections/rspec/deferred/commands.rb +8 -0
- data/lib/cuprum/collections/rspec/deferred/relation_examples.rb +1437 -0
- data/lib/cuprum/collections/rspec/deferred/resource_examples.rb +26 -0
- data/lib/cuprum/collections/rspec/deferred.rb +8 -0
- data/lib/cuprum/collections/scope.rb +29 -0
- data/lib/cuprum/collections/scopes/all.rb +51 -0
- data/lib/cuprum/collections/scopes/all_scope.rb +18 -0
- data/lib/cuprum/collections/scopes/base.rb +79 -0
- data/lib/cuprum/collections/scopes/builder.rb +39 -0
- data/lib/cuprum/collections/scopes/building.rb +221 -0
- data/lib/cuprum/collections/scopes/composition.rb +162 -0
- data/lib/cuprum/collections/scopes/conjunction.rb +44 -0
- data/lib/cuprum/collections/scopes/conjunction_scope.rb +12 -0
- data/lib/cuprum/collections/scopes/container.rb +65 -0
- data/lib/cuprum/collections/scopes/criteria/parser.rb +241 -0
- data/lib/cuprum/collections/scopes/criteria.rb +206 -0
- data/lib/cuprum/collections/scopes/criteria_scope.rb +12 -0
- data/lib/cuprum/collections/scopes/disjunction.rb +45 -0
- data/lib/cuprum/collections/scopes/disjunction_scope.rb +12 -0
- data/lib/cuprum/collections/scopes/none.rb +62 -0
- data/lib/cuprum/collections/scopes/none_scope.rb +18 -0
- data/lib/cuprum/collections/scopes.rb +23 -0
- data/lib/cuprum/collections/version.rb +2 -2
- data/lib/cuprum/collections.rb +14 -9
- metadata +61 -15
- data/lib/cuprum/collections/basic/query_builder.rb +0 -69
- data/lib/cuprum/collections/command.rb +0 -26
- data/lib/cuprum/collections/queries/parse.rb +0 -22
- data/lib/cuprum/collections/queries/parse_block.rb +0 -206
- data/lib/cuprum/collections/queries/parse_strategy.rb +0 -91
- data/lib/cuprum/collections/query_builder.rb +0 -61
- data/lib/cuprum/collections/rspec/contracts/basic/command_contracts.rb +0 -484
@@ -0,0 +1,297 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cuprum/collections/rspec/contracts'
|
4
|
+
require 'cuprum/collections/rspec/contracts/scope_contracts'
|
5
|
+
require 'cuprum/collections/rspec/contracts/scopes/composition_contracts'
|
6
|
+
require 'cuprum/collections/rspec/fixtures'
|
7
|
+
|
8
|
+
module Cuprum::Collections::RSpec::Contracts::Scopes
|
9
|
+
# Contracts for asserting on logical scope objects.
|
10
|
+
module LogicalContracts
|
11
|
+
include Cuprum::Collections::RSpec::Contracts::ScopeContracts
|
12
|
+
include Cuprum::Collections::RSpec::Contracts::Scopes::CompositionContracts
|
13
|
+
|
14
|
+
# Contract validating the behavior of a logical AND scope implementation.
|
15
|
+
module ShouldBeAConjunctionScopeContract
|
16
|
+
extend RSpec::SleepingKingStudios::Contract
|
17
|
+
|
18
|
+
# @!method apply(example_group, abstract: false)
|
19
|
+
# Adds the contract to the example group.
|
20
|
+
#
|
21
|
+
# @param example_group [RSpec::Core::ExampleGroup] the example group to
|
22
|
+
# which the contract is applied.
|
23
|
+
# @param abstract [Boolean] if true, the scope is abstract and does not
|
24
|
+
# define a #call implementation. Defaults to false.
|
25
|
+
contract do |abstract: false|
|
26
|
+
include_contract 'should be a container scope', invertible: true
|
27
|
+
|
28
|
+
include_contract 'should compose scopes for conjunction'
|
29
|
+
|
30
|
+
describe '#as_json' do
|
31
|
+
let(:expected) do
|
32
|
+
{
|
33
|
+
'scopes' => subject.scopes.map(&:as_json),
|
34
|
+
'type' => subject.type
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
it { expect(subject.as_json).to be == expected }
|
39
|
+
|
40
|
+
wrap_context 'with scopes' do
|
41
|
+
it { expect(subject.as_json).to be == expected }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#call' do
|
46
|
+
next if abstract
|
47
|
+
|
48
|
+
include_contract 'should filter data by logical and'
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#invert' do
|
52
|
+
let(:expected) do
|
53
|
+
Cuprum::Collections::Scopes::DisjunctionScope.new(
|
54
|
+
scopes: subject.scopes.map(&:invert)
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
it { expect(subject.invert).to be == expected }
|
59
|
+
|
60
|
+
wrap_context 'with scopes' do
|
61
|
+
it { expect(subject.invert).to be == expected }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#type' do
|
66
|
+
include_examples 'should define reader', :type, :conjunction
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Contract validating the behavior of a logical OR scope implementation.
|
72
|
+
module ShouldBeADisjunctionScopeContract
|
73
|
+
extend RSpec::SleepingKingStudios::Contract
|
74
|
+
|
75
|
+
# @!method apply(example_group, abstract: false)
|
76
|
+
# Adds the contract to the example group.
|
77
|
+
#
|
78
|
+
# @param example_group [RSpec::Core::ExampleGroup] the example group to
|
79
|
+
# which the contract is applied.
|
80
|
+
# @param abstract [Boolean] if true, the scope is abstract and does not
|
81
|
+
# define a #call implementation. Defaults to false.
|
82
|
+
contract do |abstract: false|
|
83
|
+
include_contract 'should be a container scope', invertible: true
|
84
|
+
|
85
|
+
include_contract 'should compose scopes for disjunction'
|
86
|
+
|
87
|
+
describe '#as_json' do
|
88
|
+
let(:expected) do
|
89
|
+
{
|
90
|
+
'scopes' => subject.scopes.map(&:as_json),
|
91
|
+
'type' => subject.type
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
it { expect(subject.as_json).to be == expected }
|
96
|
+
|
97
|
+
wrap_context 'with scopes' do
|
98
|
+
it { expect(subject.as_json).to be == expected }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe '#call' do
|
103
|
+
next if abstract
|
104
|
+
|
105
|
+
include_contract 'should filter data by logical or'
|
106
|
+
end
|
107
|
+
|
108
|
+
describe '#invert' do
|
109
|
+
let(:expected) do
|
110
|
+
Cuprum::Collections::Scopes::ConjunctionScope.new(
|
111
|
+
scopes: subject.scopes.map(&:invert)
|
112
|
+
)
|
113
|
+
end
|
114
|
+
|
115
|
+
it { expect(subject.invert).to be == expected }
|
116
|
+
|
117
|
+
wrap_context 'with scopes' do
|
118
|
+
it { expect(subject.invert).to be == expected }
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe '#type' do
|
123
|
+
include_examples 'should define reader', :type, :disjunction
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# Contract validating the behavior of a Conjunction scope implementation.
|
129
|
+
module ShouldFilterDataByLogicalAndContract
|
130
|
+
extend RSpec::SleepingKingStudios::Contract
|
131
|
+
|
132
|
+
# @!method apply(example_group)
|
133
|
+
# Adds the contract to the example group.
|
134
|
+
#
|
135
|
+
# @param example_group [RSpec::Core::ExampleGroup] the example group to
|
136
|
+
# which the contract is applied.
|
137
|
+
contract do
|
138
|
+
shared_context 'with data' do
|
139
|
+
let(:data) do
|
140
|
+
Cuprum::Collections::RSpec::Fixtures::BOOKS_FIXTURES
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context 'when the scope has no child scopes' do
|
145
|
+
let(:scopes) { [] }
|
146
|
+
|
147
|
+
describe 'with empty data' do
|
148
|
+
let(:data) { [] }
|
149
|
+
|
150
|
+
it { expect(filtered_data).to be == [] }
|
151
|
+
end
|
152
|
+
|
153
|
+
wrap_context 'with data' do
|
154
|
+
let(:expected) { data }
|
155
|
+
|
156
|
+
it { expect(filtered_data).to match_array expected }
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context 'when the scope has one child scope' do
|
161
|
+
let(:scopes) do
|
162
|
+
[
|
163
|
+
build_scope({ 'author' => 'J.R.R. Tolkien' })
|
164
|
+
]
|
165
|
+
end
|
166
|
+
|
167
|
+
describe 'with empty data' do
|
168
|
+
let(:data) { [] }
|
169
|
+
|
170
|
+
it { expect(filtered_data).to be == [] }
|
171
|
+
end
|
172
|
+
|
173
|
+
wrap_context 'with data' do
|
174
|
+
let(:expected) do
|
175
|
+
data.select { |item| item['author'] == 'J.R.R. Tolkien' }
|
176
|
+
end
|
177
|
+
|
178
|
+
it { expect(filtered_data).to match_array expected }
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context 'when the scope has many child scopes' do
|
183
|
+
let(:scopes) do
|
184
|
+
[
|
185
|
+
build_scope({ 'author' => 'J.R.R. Tolkien' }),
|
186
|
+
build_scope({ 'series' => 'The Lord of the Rings' }),
|
187
|
+
build_scope do |scope|
|
188
|
+
{ 'published_at' => scope.less_than('1955-01-01') }
|
189
|
+
end
|
190
|
+
]
|
191
|
+
end
|
192
|
+
|
193
|
+
describe 'with empty data' do
|
194
|
+
let(:data) { [] }
|
195
|
+
|
196
|
+
it { expect(filtered_data).to be == [] }
|
197
|
+
end
|
198
|
+
|
199
|
+
wrap_context 'with data' do
|
200
|
+
let(:expected) do
|
201
|
+
data
|
202
|
+
.select { |item| item['author'] == 'J.R.R. Tolkien' }
|
203
|
+
.select { |item| item['series'] == 'The Lord of the Rings' }
|
204
|
+
.select { |item| item['published_at'] < '1955-01-01' }
|
205
|
+
end
|
206
|
+
|
207
|
+
it { expect(filtered_data).to match_array expected }
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# Contract validating the behavior of a Disjunction scope implementation.
|
214
|
+
module ShouldFilterDataByLogicalOrContract
|
215
|
+
extend RSpec::SleepingKingStudios::Contract
|
216
|
+
|
217
|
+
# @!method apply(example_group)
|
218
|
+
# Adds the contract to the example group.
|
219
|
+
#
|
220
|
+
# @param example_group [RSpec::Core::ExampleGroup] the example group to
|
221
|
+
# which the contract is applied.
|
222
|
+
contract do
|
223
|
+
shared_context 'with data' do
|
224
|
+
let(:data) do
|
225
|
+
Cuprum::Collections::RSpec::Fixtures::BOOKS_FIXTURES
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
context 'when the scope has no child scopes' do
|
230
|
+
let(:scopes) { [] }
|
231
|
+
|
232
|
+
describe 'with empty data' do
|
233
|
+
let(:data) { [] }
|
234
|
+
|
235
|
+
it { expect(filtered_data).to be == [] }
|
236
|
+
end
|
237
|
+
|
238
|
+
wrap_context 'with data' do
|
239
|
+
it { expect(filtered_data).to be == [] }
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
context 'when the scope has one child scope' do
|
244
|
+
let(:scopes) do
|
245
|
+
[
|
246
|
+
build_scope({ 'author' => 'J.R.R. Tolkien' })
|
247
|
+
]
|
248
|
+
end
|
249
|
+
|
250
|
+
describe 'with empty data' do
|
251
|
+
let(:data) { [] }
|
252
|
+
|
253
|
+
it { expect(filtered_data).to be == [] }
|
254
|
+
end
|
255
|
+
|
256
|
+
wrap_context 'with data' do
|
257
|
+
let(:expected) do
|
258
|
+
data.select { |item| item['author'] == 'J.R.R. Tolkien' }
|
259
|
+
end
|
260
|
+
|
261
|
+
it { expect(filtered_data).to match_array expected }
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
context 'when the scope has many child scopes' do
|
266
|
+
let(:scopes) do
|
267
|
+
[
|
268
|
+
build_scope({ 'author' => 'J.R.R. Tolkien' }),
|
269
|
+
build_scope({ 'series' => 'The Lord of the Rings' }),
|
270
|
+
build_scope do |scope|
|
271
|
+
{ 'published_at' => scope.less_than('1955-01-01') }
|
272
|
+
end
|
273
|
+
]
|
274
|
+
end
|
275
|
+
|
276
|
+
describe 'with empty data' do
|
277
|
+
let(:data) { [] }
|
278
|
+
|
279
|
+
it { expect(filtered_data).to be == [] }
|
280
|
+
end
|
281
|
+
|
282
|
+
wrap_context 'with data' do
|
283
|
+
let(:expected) do
|
284
|
+
data.select do |item|
|
285
|
+
item['author'] == 'J.R.R. Tolkien' ||
|
286
|
+
item['series'] == 'The Lord of the Rings' ||
|
287
|
+
item['published_at'] < '1955-01-01'
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
it { expect(filtered_data).to match_array expected }
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cuprum/collections/rspec/contracts'
|
4
|
+
|
5
|
+
module Cuprum::Collections::RSpec::Contracts
|
6
|
+
# Namespace for RSpec contracts validating the behavior of scopes.
|
7
|
+
module Scopes
|
8
|
+
autoload :CriteriaContracts,
|
9
|
+
'cuprum/collections/rspec/contracts/scopes/criteria_contracts'
|
10
|
+
autoload :LogicalContracts,
|
11
|
+
'cuprum/collections/rspec/contracts/scopes/logical_contracts'
|
12
|
+
end
|
13
|
+
end
|
@@ -19,5 +19,7 @@ module Cuprum::Collections::RSpec
|
|
19
19
|
'cuprum/collections/rspec/contracts/relation_contracts'
|
20
20
|
autoload :RepositoryContracts,
|
21
21
|
'cuprum/collections/rspec/contracts/repository_contracts'
|
22
|
+
autoload :Scopes,
|
23
|
+
'cuprum/collections/rspec/contracts/scopes'
|
22
24
|
end
|
23
25
|
end
|