cuprum-collections 0.3.0 → 0.4.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 +48 -0
- data/DEVELOPMENT.md +2 -2
- data/README.md +13 -11
- data/lib/cuprum/collections/association.rb +256 -0
- data/lib/cuprum/collections/associations/belongs_to.rb +32 -0
- data/lib/cuprum/collections/associations/has_many.rb +23 -0
- data/lib/cuprum/collections/associations/has_one.rb +23 -0
- data/lib/cuprum/collections/associations.rb +10 -0
- data/lib/cuprum/collections/basic/collection.rb +39 -74
- data/lib/cuprum/collections/basic/commands/find_many.rb +1 -1
- data/lib/cuprum/collections/basic/commands/find_matching.rb +1 -1
- data/lib/cuprum/collections/basic/repository.rb +9 -33
- data/lib/cuprum/collections/basic.rb +1 -0
- data/lib/cuprum/collections/collection.rb +154 -0
- data/lib/cuprum/collections/commands/associations/find_many.rb +161 -0
- data/lib/cuprum/collections/commands/associations/require_many.rb +48 -0
- data/lib/cuprum/collections/commands/associations.rb +13 -0
- data/lib/cuprum/collections/commands/find_one_matching.rb +1 -1
- data/lib/cuprum/collections/commands.rb +1 -0
- data/lib/cuprum/collections/errors/abstract_find_error.rb +1 -1
- data/lib/cuprum/collections/relation.rb +401 -0
- data/lib/cuprum/collections/repository.rb +71 -4
- data/lib/cuprum/collections/resource.rb +65 -0
- data/lib/cuprum/collections/rspec/contracts/association_contracts.rb +2137 -0
- data/lib/cuprum/collections/rspec/contracts/basic/command_contracts.rb +484 -0
- data/lib/cuprum/collections/rspec/contracts/basic.rb +11 -0
- data/lib/cuprum/collections/rspec/contracts/collection_contracts.rb +429 -0
- data/lib/cuprum/collections/rspec/contracts/command_contracts.rb +1462 -0
- data/lib/cuprum/collections/rspec/contracts/query_contracts.rb +1093 -0
- data/lib/cuprum/collections/rspec/contracts/relation_contracts.rb +1381 -0
- data/lib/cuprum/collections/rspec/contracts/repository_contracts.rb +605 -0
- data/lib/cuprum/collections/rspec/contracts.rb +23 -0
- data/lib/cuprum/collections/rspec/fixtures.rb +85 -82
- data/lib/cuprum/collections/rspec.rb +4 -1
- data/lib/cuprum/collections/version.rb +1 -1
- data/lib/cuprum/collections.rb +9 -4
- metadata +23 -19
- data/lib/cuprum/collections/base.rb +0 -11
- data/lib/cuprum/collections/basic/rspec/command_contract.rb +0 -392
- data/lib/cuprum/collections/rspec/assign_one_command_contract.rb +0 -168
- data/lib/cuprum/collections/rspec/build_one_command_contract.rb +0 -93
- data/lib/cuprum/collections/rspec/collection_contract.rb +0 -190
- data/lib/cuprum/collections/rspec/destroy_one_command_contract.rb +0 -108
- data/lib/cuprum/collections/rspec/find_many_command_contract.rb +0 -407
- data/lib/cuprum/collections/rspec/find_matching_command_contract.rb +0 -194
- data/lib/cuprum/collections/rspec/find_one_command_contract.rb +0 -157
- data/lib/cuprum/collections/rspec/insert_one_command_contract.rb +0 -84
- data/lib/cuprum/collections/rspec/query_builder_contract.rb +0 -92
- data/lib/cuprum/collections/rspec/query_contract.rb +0 -650
- data/lib/cuprum/collections/rspec/querying_contract.rb +0 -298
- data/lib/cuprum/collections/rspec/repository_contract.rb +0 -235
- data/lib/cuprum/collections/rspec/update_one_command_contract.rb +0 -80
- data/lib/cuprum/collections/rspec/validate_one_command_contract.rb +0 -96
@@ -1,298 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'cuprum/collections/queries'
|
4
|
-
require 'cuprum/collections/rspec'
|
5
|
-
|
6
|
-
module Cuprum::Collections::RSpec
|
7
|
-
OPERATORS = Cuprum::Collections::Queries::Operators
|
8
|
-
private_constant :OPERATORS
|
9
|
-
|
10
|
-
# Shared contexts for specs that define querying behavior.
|
11
|
-
QUERYING_CONTEXTS = lambda do
|
12
|
-
let(:filter) { nil }
|
13
|
-
let(:strategy) { nil }
|
14
|
-
let(:limit) { nil }
|
15
|
-
let(:offset) { nil }
|
16
|
-
let(:order) { nil }
|
17
|
-
|
18
|
-
shared_context 'when the query has limit: value' do
|
19
|
-
let(:limit) { 3 }
|
20
|
-
let(:matching_data) { super()[0...limit] }
|
21
|
-
end
|
22
|
-
|
23
|
-
shared_context 'when the query has offset: value' do
|
24
|
-
let(:offset) { 2 }
|
25
|
-
let(:matching_data) { super()[offset..] || [] }
|
26
|
-
end
|
27
|
-
|
28
|
-
shared_context 'when the query has order: a simple ordering' do
|
29
|
-
let(:order) { :title }
|
30
|
-
let(:matching_data) { super().sort_by { |item| item['title'] } }
|
31
|
-
end
|
32
|
-
|
33
|
-
shared_context 'when the query has order: a complex ordering' do
|
34
|
-
let(:order) do
|
35
|
-
{
|
36
|
-
author: :asc,
|
37
|
-
title: :desc
|
38
|
-
}
|
39
|
-
end
|
40
|
-
let(:matching_data) do
|
41
|
-
super().sort do |u, v|
|
42
|
-
cmp = u['author'] <=> v['author']
|
43
|
-
|
44
|
-
cmp.zero? ? (v['title'] <=> u['title']) : cmp
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
shared_context 'when the query has where: a simple block filter' do
|
50
|
-
let(:filter) { -> { { author: 'Ursula K. LeGuin' } } }
|
51
|
-
let(:matching_data) do
|
52
|
-
super().select { |item| item['author'] == 'Ursula K. LeGuin' }
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
shared_context 'when the query has where: a complex block filter' do
|
57
|
-
let(:filter) do
|
58
|
-
lambda do
|
59
|
-
{
|
60
|
-
author: equals('Ursula K. LeGuin'),
|
61
|
-
series: not_equal('Earthsea')
|
62
|
-
}
|
63
|
-
end
|
64
|
-
end
|
65
|
-
let(:matching_data) do
|
66
|
-
super()
|
67
|
-
.select { |item| item['author'] == 'Ursula K. LeGuin' }
|
68
|
-
.reject { |item| item['series'] == 'Earthsea' }
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
shared_context 'when the query has where: a greater_than filter' do
|
73
|
-
let(:filter) { -> { { published_at: greater_than('1970-12-01') } } }
|
74
|
-
let(:matching_data) do
|
75
|
-
super().select { |item| item['published_at'] > '1970-12-01' }
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
shared_context 'when the query has where: a greater_than_or_equal_to ' \
|
80
|
-
'filter' \
|
81
|
-
do
|
82
|
-
let(:filter) do
|
83
|
-
-> { { published_at: greater_than_or_equal_to('1970-12-01') } }
|
84
|
-
end
|
85
|
-
let(:matching_data) do
|
86
|
-
super().select { |item| item['published_at'] >= '1970-12-01' }
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
shared_context 'when the query has where: a less_than filter' do
|
91
|
-
let(:filter) { -> { { published_at: less_than('1970-12-01') } } }
|
92
|
-
let(:matching_data) do
|
93
|
-
super().select { |item| item['published_at'] < '1970-12-01' }
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
shared_context 'when the query has where: a less_than_or_equal_to filter' do
|
98
|
-
let(:filter) do
|
99
|
-
-> { { published_at: less_than_or_equal_to('1970-12-01') } }
|
100
|
-
end
|
101
|
-
let(:matching_data) do
|
102
|
-
super().select { |item| item['published_at'] <= '1970-12-01' }
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
shared_context 'when the query has where: an equal block filter' do
|
107
|
-
let(:filter) { -> { { author: equals('Ursula K. LeGuin') } } }
|
108
|
-
let(:matching_data) do
|
109
|
-
super().select { |item| item['author'] == 'Ursula K. LeGuin' }
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
shared_context 'when the query has where: a not_equal block filter' do
|
114
|
-
let(:filter) { -> { { author: not_equal('Ursula K. LeGuin') } } }
|
115
|
-
let(:matching_data) do
|
116
|
-
super().reject { |item| item['author'] == 'Ursula K. LeGuin' }
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
shared_context 'when the query has where: a not_one_of block filter' do
|
121
|
-
let(:filter) do
|
122
|
-
-> { { series: not_one_of(['Earthsea', 'The Lord of the Rings']) } }
|
123
|
-
end
|
124
|
-
let(:matching_data) do
|
125
|
-
super().reject do |item|
|
126
|
-
['Earthsea', 'The Lord of the Rings'].include?(item['series'])
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
shared_context 'when the query has where: a one_of block filter' do
|
132
|
-
let(:filter) do
|
133
|
-
-> { { series: one_of(['Earthsea', 'The Lord of the Rings']) } }
|
134
|
-
end
|
135
|
-
let(:matching_data) do
|
136
|
-
super().select do |item|
|
137
|
-
['Earthsea', 'The Lord of the Rings'].include?(item['series'])
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
shared_context 'when the query has multiple query options' do
|
143
|
-
let(:filter) { -> { { author: 'Ursula K. LeGuin' } } }
|
144
|
-
let(:strategy) { nil }
|
145
|
-
let(:order) { { title: :desc } }
|
146
|
-
let(:limit) { 2 }
|
147
|
-
let(:offset) { 1 }
|
148
|
-
let(:matching_data) do
|
149
|
-
super()
|
150
|
-
.select { |item| item['author'] == 'Ursula K. LeGuin' }
|
151
|
-
.sort { |u, v| v['title'] <=> u['title'] }
|
152
|
-
.slice(1, 2) || []
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
# Contract validating the behavior objects that perform queries.
|
158
|
-
QUERYING_CONTRACT = lambda do |block:, operators: OPERATORS.values|
|
159
|
-
wrap_context 'when the query has limit: value' do
|
160
|
-
instance_exec(&block)
|
161
|
-
end
|
162
|
-
|
163
|
-
wrap_context 'when the query has offset: value' do
|
164
|
-
instance_exec(&block)
|
165
|
-
end
|
166
|
-
|
167
|
-
wrap_context 'when the query has order: a simple ordering' do
|
168
|
-
instance_exec(&block)
|
169
|
-
end
|
170
|
-
|
171
|
-
wrap_context 'when the query has order: a complex ordering' do
|
172
|
-
instance_exec(&block)
|
173
|
-
end
|
174
|
-
|
175
|
-
context 'when the query has where: a block filter' do
|
176
|
-
context 'with a simple filter' do
|
177
|
-
include_context 'when the query has where: a simple block filter'
|
178
|
-
|
179
|
-
instance_exec(&block)
|
180
|
-
end
|
181
|
-
|
182
|
-
context 'with a complex filter' do
|
183
|
-
include_context 'when the query has where: a complex block filter'
|
184
|
-
|
185
|
-
if operators.include?(OPERATORS::EQUAL) &&
|
186
|
-
operators.include?(OPERATORS::NOT_EQUAL)
|
187
|
-
instance_exec(&block)
|
188
|
-
else
|
189
|
-
# :nocov:
|
190
|
-
pending
|
191
|
-
# :nocov:
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
context 'with an equals filter' do
|
196
|
-
include_context 'when the query has where: an equal block filter'
|
197
|
-
|
198
|
-
if operators.include?(OPERATORS::EQUAL)
|
199
|
-
instance_exec(&block)
|
200
|
-
else
|
201
|
-
# :nocov:
|
202
|
-
pending
|
203
|
-
# :nocov:
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
context 'with a greater_than filter' do
|
208
|
-
include_context 'when the query has where: a greater_than filter'
|
209
|
-
|
210
|
-
if operators.include?(OPERATORS::GREATER_THAN)
|
211
|
-
instance_exec(&block)
|
212
|
-
else
|
213
|
-
# :nocov:
|
214
|
-
pending
|
215
|
-
# :nocov:
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
context 'with a greater_than_or_equal_to filter' do
|
220
|
-
include_context \
|
221
|
-
'when the query has where: a greater_than_or_equal_to filter'
|
222
|
-
|
223
|
-
if operators.include?(OPERATORS::GREATER_THAN_OR_EQUAL_TO)
|
224
|
-
instance_exec(&block)
|
225
|
-
else
|
226
|
-
# :nocov:
|
227
|
-
pending
|
228
|
-
# :nocov:
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
context 'with a less_than filter' do
|
233
|
-
include_context 'when the query has where: a less_than filter'
|
234
|
-
|
235
|
-
if operators.include?(OPERATORS::LESS_THAN)
|
236
|
-
instance_exec(&block)
|
237
|
-
else
|
238
|
-
# :nocov:
|
239
|
-
pending
|
240
|
-
# :nocov:
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
context 'with a less_than_or_equal_to filter' do
|
245
|
-
include_context \
|
246
|
-
'when the query has where: a less_than_or_equal_to filter'
|
247
|
-
|
248
|
-
if operators.include?(OPERATORS::LESS_THAN_OR_EQUAL_TO)
|
249
|
-
instance_exec(&block)
|
250
|
-
else
|
251
|
-
# :nocov:
|
252
|
-
pending
|
253
|
-
# :nocov:
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
context 'with a not_equal filter' do
|
258
|
-
include_context 'when the query has where: a not_equal block filter'
|
259
|
-
|
260
|
-
if operators.include?(OPERATORS::NOT_EQUAL)
|
261
|
-
instance_exec(&block)
|
262
|
-
else
|
263
|
-
# :nocov:
|
264
|
-
pending
|
265
|
-
# :nocov:
|
266
|
-
end
|
267
|
-
end
|
268
|
-
|
269
|
-
context 'with a not_one_of filter' do
|
270
|
-
include_context 'when the query has where: a not_one_of block filter'
|
271
|
-
|
272
|
-
if operators.include?(OPERATORS::NOT_ONE_OF)
|
273
|
-
instance_exec(&block)
|
274
|
-
else
|
275
|
-
# :nocov:
|
276
|
-
pending
|
277
|
-
# :nocov:
|
278
|
-
end
|
279
|
-
end
|
280
|
-
|
281
|
-
context 'with a one_of filter' do
|
282
|
-
include_context 'when the query has where: a one_of block filter'
|
283
|
-
|
284
|
-
if operators.include?(OPERATORS::ONE_OF)
|
285
|
-
instance_exec(&block)
|
286
|
-
else
|
287
|
-
# :nocov:
|
288
|
-
pending
|
289
|
-
# :nocov:
|
290
|
-
end
|
291
|
-
end
|
292
|
-
end
|
293
|
-
|
294
|
-
wrap_context 'when the query has multiple query options' do
|
295
|
-
instance_exec(&block)
|
296
|
-
end
|
297
|
-
end
|
298
|
-
end
|
@@ -1,235 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rspec/sleeping_king_studios/contract'
|
4
|
-
|
5
|
-
require 'cuprum/collections/rspec'
|
6
|
-
|
7
|
-
module Cuprum::Collections::RSpec
|
8
|
-
# Contract validating the behavior of a Repository.
|
9
|
-
module RepositoryContract
|
10
|
-
extend RSpec::SleepingKingStudios::Contract
|
11
|
-
|
12
|
-
# @!method apply(example_group)
|
13
|
-
# Adds the contract to the example group.
|
14
|
-
#
|
15
|
-
# @param example_group [RSpec::Core::ExampleGroup] The example group to
|
16
|
-
# which the contract is applied.
|
17
|
-
contract do
|
18
|
-
describe '#[]' do
|
19
|
-
let(:error_class) do
|
20
|
-
described_class::UndefinedCollectionError
|
21
|
-
end
|
22
|
-
let(:error_message) do
|
23
|
-
"repository does not define collection #{collection_name.inspect}"
|
24
|
-
end
|
25
|
-
|
26
|
-
it { expect(repository).to respond_to(:[]).with(1).argument }
|
27
|
-
|
28
|
-
describe 'with nil' do
|
29
|
-
let(:collection_name) { nil }
|
30
|
-
|
31
|
-
it 'should raise an exception' do
|
32
|
-
expect { repository[collection_name] }
|
33
|
-
.to raise_error(error_class, error_message)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe 'with an object' do
|
38
|
-
let(:collection_name) { Object.new.freeze }
|
39
|
-
|
40
|
-
it 'should raise an exception' do
|
41
|
-
expect { repository[collection_name] }
|
42
|
-
.to raise_error(error_class, error_message)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
describe 'with an invalid string' do
|
47
|
-
let(:collection_name) { 'invalid_name' }
|
48
|
-
|
49
|
-
it 'should raise an exception' do
|
50
|
-
expect { repository[collection_name] }
|
51
|
-
.to raise_error(error_class, error_message)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
describe 'with an invalid symbol' do
|
56
|
-
let(:collection_name) { :invalid_name }
|
57
|
-
|
58
|
-
it 'should raise an exception' do
|
59
|
-
expect { repository[collection_name] }
|
60
|
-
.to raise_error(error_class, error_message)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
wrap_context 'when the repository has many collections' do
|
65
|
-
describe 'with an invalid string' do
|
66
|
-
let(:collection_name) { 'invalid_name' }
|
67
|
-
|
68
|
-
it 'should raise an exception' do
|
69
|
-
expect { repository[collection_name] }
|
70
|
-
.to raise_error(error_class, error_message)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
describe 'with an invalid symbol' do
|
75
|
-
let(:collection_name) { :invalid_name }
|
76
|
-
|
77
|
-
it 'should raise an exception' do
|
78
|
-
expect { repository[collection_name] }
|
79
|
-
.to raise_error(error_class, error_message)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
describe 'with a valid string' do
|
84
|
-
let(:collection) { collections.values.first }
|
85
|
-
let(:collection_name) { collections.keys.first }
|
86
|
-
|
87
|
-
it { expect(repository[collection_name]).to be collection }
|
88
|
-
end
|
89
|
-
|
90
|
-
describe 'with a valid symbol' do
|
91
|
-
let(:collection) { collections.values.first }
|
92
|
-
let(:collection_name) { collections.keys.first.intern }
|
93
|
-
|
94
|
-
it { expect(repository[collection_name]).to be collection }
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
describe '#add' do
|
100
|
-
let(:error_class) do
|
101
|
-
described_class::InvalidCollectionError
|
102
|
-
end
|
103
|
-
let(:error_message) do
|
104
|
-
"#{collection.inspect} is not a valid collection"
|
105
|
-
end
|
106
|
-
|
107
|
-
it 'should define the method' do
|
108
|
-
expect(repository)
|
109
|
-
.to respond_to(:add)
|
110
|
-
.with(1).argument
|
111
|
-
.and_keywords(:force)
|
112
|
-
end
|
113
|
-
|
114
|
-
it 'should alias #add as #<<' do
|
115
|
-
expect(repository.method(:<<)).to be == repository.method(:add)
|
116
|
-
end
|
117
|
-
|
118
|
-
describe 'with nil' do
|
119
|
-
let(:collection) { nil }
|
120
|
-
|
121
|
-
it 'should raise an exception' do
|
122
|
-
expect { repository.add(collection) }
|
123
|
-
.to raise_error(error_class, error_message)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
describe 'with an object' do
|
128
|
-
let(:collection) { Object.new.freeze }
|
129
|
-
|
130
|
-
it 'should raise an exception' do
|
131
|
-
expect { repository.add(collection) }
|
132
|
-
.to raise_error(error_class, error_message)
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
describe 'with a collection' do
|
137
|
-
it { expect(repository.add(example_collection)).to be repository }
|
138
|
-
|
139
|
-
it 'should add the collection to the repository' do
|
140
|
-
repository.add(example_collection)
|
141
|
-
|
142
|
-
expect(repository[example_collection.qualified_name])
|
143
|
-
.to be example_collection
|
144
|
-
end
|
145
|
-
|
146
|
-
describe 'with force: true' do
|
147
|
-
it 'should add the collection to the repository' do
|
148
|
-
repository.add(example_collection, force: true)
|
149
|
-
|
150
|
-
expect(repository[example_collection.qualified_name])
|
151
|
-
.to be example_collection
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
context 'when the collection already exists' do
|
156
|
-
let(:error_message) do
|
157
|
-
"collection #{example_collection.qualified_name} already exists"
|
158
|
-
end
|
159
|
-
|
160
|
-
before(:example) do
|
161
|
-
allow(repository)
|
162
|
-
.to receive(:key?)
|
163
|
-
.with(example_collection.qualified_name)
|
164
|
-
.and_return(true)
|
165
|
-
end
|
166
|
-
|
167
|
-
it 'should raise an exception' do
|
168
|
-
expect { repository.add(example_collection) }
|
169
|
-
.to raise_error(
|
170
|
-
described_class::DuplicateCollectionError,
|
171
|
-
error_message
|
172
|
-
)
|
173
|
-
end
|
174
|
-
|
175
|
-
it 'should not update the repository' do
|
176
|
-
begin
|
177
|
-
repository.add(example_collection)
|
178
|
-
rescue described_class::DuplicateCollectionError
|
179
|
-
# Do nothing.
|
180
|
-
end
|
181
|
-
|
182
|
-
expect { repository[example_collection.qualified_name] }
|
183
|
-
.to raise_error(
|
184
|
-
described_class::UndefinedCollectionError,
|
185
|
-
'repository does not define collection ' \
|
186
|
-
"#{example_collection.qualified_name.inspect}"
|
187
|
-
)
|
188
|
-
end
|
189
|
-
|
190
|
-
describe 'with force: true' do
|
191
|
-
it 'should add the collection to the repository' do
|
192
|
-
repository.add(example_collection, force: true)
|
193
|
-
|
194
|
-
expect(repository[example_collection.qualified_name])
|
195
|
-
.to be example_collection
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
describe '#key?' do
|
203
|
-
it { expect(repository).to respond_to(:key?).with(1).argument }
|
204
|
-
|
205
|
-
it { expect(repository.key? nil).to be false }
|
206
|
-
|
207
|
-
it { expect(repository.key? Object.new.freeze).to be false }
|
208
|
-
|
209
|
-
it { expect(repository.key? 'invalid_name').to be false }
|
210
|
-
|
211
|
-
it { expect(repository.key? :invalid_name).to be false }
|
212
|
-
|
213
|
-
wrap_context 'when the repository has many collections' do
|
214
|
-
it { expect(repository.key? 'invalid_name').to be false }
|
215
|
-
|
216
|
-
it { expect(repository.key? :invalid_name).to be false }
|
217
|
-
|
218
|
-
it { expect(repository.key? collections.keys.first).to be true }
|
219
|
-
|
220
|
-
it 'should include the key' do
|
221
|
-
expect(repository.key? collections.keys.first.intern).to be true
|
222
|
-
end
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
describe '#keys' do
|
227
|
-
include_examples 'should define reader', :keys, []
|
228
|
-
|
229
|
-
wrap_context 'when the repository has many collections' do
|
230
|
-
it { expect(repository.keys).to be == collections.keys }
|
231
|
-
end
|
232
|
-
end
|
233
|
-
end
|
234
|
-
end
|
235
|
-
end
|
@@ -1,80 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'cuprum/collections/rspec'
|
4
|
-
|
5
|
-
module Cuprum::Collections::RSpec
|
6
|
-
# Contract validating the behavior of an UpdateOne command implementation.
|
7
|
-
UPDATE_ONE_COMMAND_CONTRACT = lambda do
|
8
|
-
describe '#call' do
|
9
|
-
let(:mapped_data) do
|
10
|
-
defined?(super()) ? super() : data
|
11
|
-
end
|
12
|
-
let(:matching_data) { attributes }
|
13
|
-
let(:expected_data) do
|
14
|
-
defined?(super()) ? super() : matching_data
|
15
|
-
end
|
16
|
-
let(:primary_key_name) do
|
17
|
-
defined?(super()) ? super() : :id
|
18
|
-
end
|
19
|
-
let(:scoped) do
|
20
|
-
key = primary_key_name
|
21
|
-
value = entity[primary_key_name.to_s]
|
22
|
-
|
23
|
-
query.where { { key => value } }
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'should validate the :entity keyword' do
|
27
|
-
expect(command)
|
28
|
-
.to validate_parameter(:call, :entity)
|
29
|
-
.using_constraint(entity_type)
|
30
|
-
end
|
31
|
-
|
32
|
-
context 'when the item does not exist in the collection' do
|
33
|
-
let(:expected_error) do
|
34
|
-
Cuprum::Collections::Errors::NotFound.new(
|
35
|
-
attribute_name: primary_key_name,
|
36
|
-
attribute_value: attributes[primary_key_name],
|
37
|
-
collection_name: collection_name,
|
38
|
-
primary_key: true
|
39
|
-
)
|
40
|
-
end
|
41
|
-
let(:matching_data) { mapped_data.first }
|
42
|
-
|
43
|
-
it 'should return a failing result' do
|
44
|
-
expect(command.call(entity: entity))
|
45
|
-
.to be_a_failing_result
|
46
|
-
.with_error(expected_error)
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'should not append an item to the collection' do
|
50
|
-
expect { command.call(entity: entity) }
|
51
|
-
.not_to(change { query.reset.count })
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
context 'when the item exists in the collection' do
|
56
|
-
let(:data) { fixtures_data }
|
57
|
-
let(:matching_data) do
|
58
|
-
mapped_data.first.merge(super())
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'should return a passing result' do
|
62
|
-
expect(command.call(entity: entity))
|
63
|
-
.to be_a_passing_result
|
64
|
-
.with_value(be == expected_data)
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'should not append an item to the collection' do
|
68
|
-
expect { command.call(entity: entity) }
|
69
|
-
.not_to(change { query.reset.count })
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'should set the attributes' do
|
73
|
-
command.call(entity: entity)
|
74
|
-
|
75
|
-
expect(scoped.to_a.first).to be == expected_data
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
@@ -1,96 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'cuprum/collections/rspec'
|
4
|
-
|
5
|
-
module Cuprum::Collections::RSpec
|
6
|
-
# Contract validating the behavior of a ValidateOne command implementation.
|
7
|
-
VALIDATE_ONE_COMMAND_CONTRACT = lambda do |default_contract:|
|
8
|
-
describe '#call' do
|
9
|
-
it 'should validate the :contract keyword' do
|
10
|
-
expect(command)
|
11
|
-
.to validate_parameter(:call, :contract)
|
12
|
-
.with_value(Object.new.freeze)
|
13
|
-
.using_constraint(Stannum::Constraints::Base, optional: true)
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'should validate the :entity keyword' do
|
17
|
-
expect(command)
|
18
|
-
.to validate_parameter(:call, :entity)
|
19
|
-
.with_value(Object.new.freeze)
|
20
|
-
.using_constraint(entity_type)
|
21
|
-
end
|
22
|
-
|
23
|
-
describe 'with contract: nil' do
|
24
|
-
if default_contract
|
25
|
-
context 'when the entity does not match the default contract' do
|
26
|
-
let(:attributes) { invalid_default_attributes }
|
27
|
-
let(:expected_error) do
|
28
|
-
Cuprum::Collections::Errors::FailedValidation.new(
|
29
|
-
entity_class: entity.class,
|
30
|
-
errors: expected_errors
|
31
|
-
)
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'should return a failing result' do
|
35
|
-
expect(command.call(entity: entity))
|
36
|
-
.to be_a_failing_result
|
37
|
-
.with_error(expected_error)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
context 'when the entity matches the default contract' do
|
42
|
-
let(:attributes) { valid_default_attributes }
|
43
|
-
|
44
|
-
it 'should return a passing result' do
|
45
|
-
expect(command.call(entity: entity))
|
46
|
-
.to be_a_passing_result
|
47
|
-
.with_value(entity)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
else
|
51
|
-
let(:attributes) { valid_attributes }
|
52
|
-
let(:expected_error) do
|
53
|
-
Cuprum::Collections::Errors::MissingDefaultContract.new(
|
54
|
-
entity_class: entity.class
|
55
|
-
)
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'should return a failing result' do
|
59
|
-
expect(command.call(entity: entity))
|
60
|
-
.to be_a_failing_result
|
61
|
-
.with_error(expected_error)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
describe 'with contract: value' do
|
67
|
-
context 'when the entity does not match the contract' do
|
68
|
-
let(:attributes) { invalid_attributes }
|
69
|
-
let(:errors) { contract.errors_for(entity) }
|
70
|
-
let(:expected_error) do
|
71
|
-
Cuprum::Collections::Errors::FailedValidation.new(
|
72
|
-
entity_class: entity.class,
|
73
|
-
errors: errors
|
74
|
-
)
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'should return a failing result' do
|
78
|
-
expect(command.call(contract: contract, entity: entity))
|
79
|
-
.to be_a_failing_result
|
80
|
-
.with_error(expected_error)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
context 'when the entity matches the contract' do
|
85
|
-
let(:attributes) { valid_attributes }
|
86
|
-
|
87
|
-
it 'should return a passing result' do
|
88
|
-
expect(command.call(contract: contract, entity: entity))
|
89
|
-
.to be_a_passing_result
|
90
|
-
.with_value(entity)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|