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,392 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'cuprum/collections/basic/rspec'
|
4
|
-
|
5
|
-
module Cuprum::Collections::Basic::RSpec
|
6
|
-
# Contract validating the behavior of a basic command implementation.
|
7
|
-
COMMAND_CONTRACT = lambda do
|
8
|
-
describe '.subclass' do
|
9
|
-
let(:subclass) { described_class.subclass }
|
10
|
-
let(:constructor_options) do
|
11
|
-
{
|
12
|
-
collection_name: 'books',
|
13
|
-
data: data,
|
14
|
-
optional_key: 'optional value'
|
15
|
-
}
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'should define the class method' do
|
19
|
-
expect(described_class)
|
20
|
-
.to respond_to(:subclass)
|
21
|
-
.with(0).arguments
|
22
|
-
.and_any_keywords
|
23
|
-
end
|
24
|
-
|
25
|
-
it { expect(subclass).to be_a Class }
|
26
|
-
|
27
|
-
it { expect(subclass).to be < described_class }
|
28
|
-
|
29
|
-
it 'should define the constructor' do
|
30
|
-
expect(subclass)
|
31
|
-
.to respond_to(:new)
|
32
|
-
.with(0).arguments
|
33
|
-
.and_any_keywords
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'should return the collection name' do
|
37
|
-
expect(subclass.new(**constructor_options).collection_name)
|
38
|
-
.to be collection_name
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'should return the data' do
|
42
|
-
expect(subclass.new(**constructor_options).data)
|
43
|
-
.to be data
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'should return the options' do
|
47
|
-
expect(subclass.new(**constructor_options).options)
|
48
|
-
.to be == { optional_key: 'optional value' }
|
49
|
-
end
|
50
|
-
|
51
|
-
describe 'with options' do
|
52
|
-
let(:default_options) do
|
53
|
-
{
|
54
|
-
collection_name: 'books',
|
55
|
-
custom_key: 'custom value'
|
56
|
-
}
|
57
|
-
end
|
58
|
-
let(:constructor_options) do
|
59
|
-
{
|
60
|
-
data: data,
|
61
|
-
optional_key: 'optional value'
|
62
|
-
}
|
63
|
-
end
|
64
|
-
let(:subclass) { described_class.subclass(**default_options) }
|
65
|
-
|
66
|
-
it { expect(subclass).to be_a Class }
|
67
|
-
|
68
|
-
it { expect(subclass).to be < described_class }
|
69
|
-
|
70
|
-
it 'should define the constructor' do
|
71
|
-
expect(subclass)
|
72
|
-
.to respond_to(:new)
|
73
|
-
.with(0).arguments
|
74
|
-
.and_any_keywords
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'should return the collection name' do
|
78
|
-
expect(subclass.new(**constructor_options).collection_name)
|
79
|
-
.to be collection_name
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'should return the data' do
|
83
|
-
expect(subclass.new(**constructor_options).data)
|
84
|
-
.to be data
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'should return the options' do
|
88
|
-
expect(subclass.new(**constructor_options).options)
|
89
|
-
.to be == {
|
90
|
-
custom_key: 'custom value',
|
91
|
-
optional_key: 'optional value'
|
92
|
-
}
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
describe '#collection_name' do
|
98
|
-
include_examples 'should have reader',
|
99
|
-
:collection_name,
|
100
|
-
-> { collection_name }
|
101
|
-
|
102
|
-
context 'when initialized with collection_name: symbol' do
|
103
|
-
let(:collection_name) { :books }
|
104
|
-
|
105
|
-
it { expect(command.collection_name).to be == collection_name.to_s }
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
describe '#data' do
|
110
|
-
include_examples 'should define reader', :data, -> { data }
|
111
|
-
end
|
112
|
-
|
113
|
-
describe '#default_contract' do
|
114
|
-
include_examples 'should define reader', :default_contract, nil
|
115
|
-
|
116
|
-
context 'when initialized with a default contract' do
|
117
|
-
let(:default_contract) { Stannum::Contract.new }
|
118
|
-
let(:constructor_options) do
|
119
|
-
super().merge(default_contract: default_contract)
|
120
|
-
end
|
121
|
-
|
122
|
-
it { expect(command.default_contract).to be default_contract }
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
describe '#member_name' do
|
127
|
-
def tools
|
128
|
-
SleepingKingStudios::Tools::Toolbelt.instance
|
129
|
-
end
|
130
|
-
|
131
|
-
include_examples 'should have reader',
|
132
|
-
:member_name,
|
133
|
-
-> { tools.str.singularize(collection_name) }
|
134
|
-
|
135
|
-
context 'when initialized with collection_name: value' do
|
136
|
-
let(:collection_name) { :books }
|
137
|
-
|
138
|
-
it 'should return the singular collection name' do
|
139
|
-
expect(command.member_name)
|
140
|
-
.to be == tools.str.singularize(collection_name.to_s)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
context 'when initialized with member_name: string' do
|
145
|
-
let(:member_name) { 'tome' }
|
146
|
-
let(:constructor_options) { super().merge(member_name: member_name) }
|
147
|
-
|
148
|
-
it 'should return the singular collection name' do
|
149
|
-
expect(command.member_name).to be member_name
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
context 'when initialized with member_name: symbol' do
|
154
|
-
let(:member_name) { :tome }
|
155
|
-
let(:constructor_options) { super().merge(member_name: member_name) }
|
156
|
-
|
157
|
-
it 'should return the singular collection name' do
|
158
|
-
expect(command.member_name).to be == member_name.to_s
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
describe '#options' do
|
164
|
-
let(:expected_options) do
|
165
|
-
defined?(super()) ? super() : constructor_options
|
166
|
-
end
|
167
|
-
|
168
|
-
include_examples 'should define reader',
|
169
|
-
:options,
|
170
|
-
-> { be == expected_options }
|
171
|
-
|
172
|
-
context 'when initialized with options' do
|
173
|
-
let(:constructor_options) { super().merge({ key: 'value' }) }
|
174
|
-
let(:expected_options) { super().merge({ key: 'value' }) }
|
175
|
-
|
176
|
-
it { expect(command.options).to be == expected_options }
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
describe '#primary_key_name' do
|
181
|
-
include_examples 'should define reader', :primary_key_name, :id
|
182
|
-
|
183
|
-
context 'when initialized with a primary key name' do
|
184
|
-
let(:primary_key_name) { :uuid }
|
185
|
-
let(:constructor_options) do
|
186
|
-
super().merge({ primary_key_name: primary_key_name })
|
187
|
-
end
|
188
|
-
|
189
|
-
it { expect(command.primary_key_name).to be == primary_key_name }
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
describe '#primary_key_type' do
|
194
|
-
include_examples 'should define reader', :primary_key_type, Integer
|
195
|
-
|
196
|
-
context 'when initialized with a primary key type' do
|
197
|
-
let(:primary_key_type) { String }
|
198
|
-
let(:constructor_options) do
|
199
|
-
super().merge({ primary_key_type: primary_key_type })
|
200
|
-
end
|
201
|
-
|
202
|
-
it { expect(command.primary_key_type).to be == primary_key_type }
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
describe '#validate_primary_key' do
|
207
|
-
let(:primary_key_type) { Integer }
|
208
|
-
let(:expected_error) do
|
209
|
-
type = primary_key_type
|
210
|
-
contract = Stannum::Contracts::ParametersContract.new do
|
211
|
-
keyword :primary_key, type
|
212
|
-
end
|
213
|
-
errors = contract.errors_for(
|
214
|
-
{
|
215
|
-
arguments: [],
|
216
|
-
block: nil,
|
217
|
-
keywords: { primary_key: nil }
|
218
|
-
}
|
219
|
-
)
|
220
|
-
|
221
|
-
Cuprum::Collections::Errors::InvalidParameters.new(
|
222
|
-
command: command,
|
223
|
-
errors: errors
|
224
|
-
)
|
225
|
-
end
|
226
|
-
|
227
|
-
it 'should define the private method' do
|
228
|
-
expect(command)
|
229
|
-
.to respond_to(:validate_primary_key, true)
|
230
|
-
.with(1).argument
|
231
|
-
end
|
232
|
-
|
233
|
-
describe 'with nil' do
|
234
|
-
it 'should return a failing result' do
|
235
|
-
expect(command.send(:validate_primary_key, nil))
|
236
|
-
.to be_a_failing_result
|
237
|
-
.with_error(expected_error)
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
describe 'with an Object' do
|
242
|
-
it 'should return a failing result' do
|
243
|
-
expect(command.send(:validate_primary_key, Object.new.freeze))
|
244
|
-
.to be_a_failing_result
|
245
|
-
.with_error(expected_error)
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
describe 'with a String' do
|
250
|
-
it 'should return a failing result' do
|
251
|
-
expect(command.send(:validate_primary_key, '12345'))
|
252
|
-
.to be_a_failing_result
|
253
|
-
.with_error(expected_error)
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
describe 'with an Integer' do
|
258
|
-
it 'should not return a result' do
|
259
|
-
expect(command.send(:validate_primary_key, 12_345)).not_to be_a_result
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
context 'when initialized with a primary key type' do
|
264
|
-
let(:primary_key_type) { String }
|
265
|
-
let(:constructor_options) do
|
266
|
-
super().merge({ primary_key_type: primary_key_type })
|
267
|
-
end
|
268
|
-
|
269
|
-
describe 'with an Integer' do
|
270
|
-
it 'should return a failing result' do
|
271
|
-
expect(command.send(:validate_primary_key, 12_345))
|
272
|
-
.to be_a_failing_result
|
273
|
-
.with_error(expected_error)
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
describe 'with a String' do
|
278
|
-
it 'should not return a result' do
|
279
|
-
expect(command.send(:validate_primary_key, '12345'))
|
280
|
-
.not_to be_a_result
|
281
|
-
end
|
282
|
-
end
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
|
-
describe '#validate_primary_keys' do
|
287
|
-
let(:primary_keys) { nil }
|
288
|
-
let(:primary_key_type) { Integer }
|
289
|
-
let(:expected_error) do
|
290
|
-
type = primary_key_type
|
291
|
-
contract = Stannum::Contracts::ParametersContract.new do
|
292
|
-
keyword :primary_keys,
|
293
|
-
Stannum::Constraints::Types::ArrayType.new(item_type: type)
|
294
|
-
end
|
295
|
-
errors = contract.errors_for(
|
296
|
-
{
|
297
|
-
arguments: [],
|
298
|
-
block: nil,
|
299
|
-
keywords: { primary_keys: primary_keys }
|
300
|
-
}
|
301
|
-
)
|
302
|
-
|
303
|
-
Cuprum::Collections::Errors::InvalidParameters.new(
|
304
|
-
command: command,
|
305
|
-
errors: errors
|
306
|
-
)
|
307
|
-
end
|
308
|
-
|
309
|
-
it 'should define the private method' do
|
310
|
-
expect(command)
|
311
|
-
.to respond_to(:validate_primary_keys, true)
|
312
|
-
.with(1).argument
|
313
|
-
end
|
314
|
-
|
315
|
-
describe 'with nil' do
|
316
|
-
it 'should return a failing result' do
|
317
|
-
expect(command.send(:validate_primary_keys, nil))
|
318
|
-
.to be_a_failing_result
|
319
|
-
.with_error(expected_error)
|
320
|
-
end
|
321
|
-
end
|
322
|
-
|
323
|
-
describe 'with an Object' do
|
324
|
-
it 'should return a failing result' do
|
325
|
-
expect(command.send(:validate_primary_keys, Object.new.freeze))
|
326
|
-
.to be_a_failing_result
|
327
|
-
.with_error(expected_error)
|
328
|
-
end
|
329
|
-
end
|
330
|
-
|
331
|
-
describe 'with a String' do
|
332
|
-
it 'should return a failing result' do
|
333
|
-
expect(command.send(:validate_primary_keys, '12345'))
|
334
|
-
.to be_a_failing_result
|
335
|
-
.with_error(expected_error)
|
336
|
-
end
|
337
|
-
end
|
338
|
-
|
339
|
-
describe 'with an Integer' do
|
340
|
-
it 'should return a failing result' do
|
341
|
-
expect(command.send(:validate_primary_keys, 12_345))
|
342
|
-
.to be_a_failing_result
|
343
|
-
.with_error(expected_error)
|
344
|
-
end
|
345
|
-
end
|
346
|
-
|
347
|
-
describe 'with an empty Array' do
|
348
|
-
it 'should not return a result' do
|
349
|
-
expect(command.send(:validate_primary_keys, []))
|
350
|
-
.not_to be_a_result
|
351
|
-
end
|
352
|
-
end
|
353
|
-
|
354
|
-
describe 'with an Array with nil values' do
|
355
|
-
let(:primary_keys) { Array.new(3, nil) }
|
356
|
-
|
357
|
-
it 'should return a failing result' do
|
358
|
-
expect(command.send(:validate_primary_keys, primary_keys))
|
359
|
-
.to be_a_failing_result
|
360
|
-
.with_error(expected_error)
|
361
|
-
end
|
362
|
-
end
|
363
|
-
|
364
|
-
describe 'with an Array with Object values' do
|
365
|
-
let(:primary_keys) { Array.new(3) { Object.new.freeze } }
|
366
|
-
|
367
|
-
it 'should return a failing result' do
|
368
|
-
expect(command.send(:validate_primary_keys, primary_keys))
|
369
|
-
.to be_a_failing_result
|
370
|
-
.with_error(expected_error)
|
371
|
-
end
|
372
|
-
end
|
373
|
-
|
374
|
-
describe 'with an Array with String values' do
|
375
|
-
let(:primary_keys) { %w[ichi ni san] }
|
376
|
-
|
377
|
-
it 'should return a failing result' do
|
378
|
-
expect(command.send(:validate_primary_keys, primary_keys))
|
379
|
-
.to be_a_failing_result
|
380
|
-
.with_error(expected_error)
|
381
|
-
end
|
382
|
-
end
|
383
|
-
|
384
|
-
describe 'with an Array with Integer values' do
|
385
|
-
it 'should not return a result' do
|
386
|
-
expect(command.send(:validate_primary_keys, [0, 1, 2]))
|
387
|
-
.not_to be_a_result
|
388
|
-
end
|
389
|
-
end
|
390
|
-
end
|
391
|
-
end
|
392
|
-
end
|
@@ -1,168 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'stannum/constraints/presence'
|
4
|
-
require 'stannum/constraints/types/hash_with_indifferent_keys'
|
5
|
-
require 'stannum/rspec/validate_parameter'
|
6
|
-
|
7
|
-
require 'cuprum/collections/rspec'
|
8
|
-
|
9
|
-
module Cuprum::Collections::RSpec
|
10
|
-
# Contract validating the behavior of an Assign command implementation.
|
11
|
-
ASSIGN_ONE_COMMAND_CONTRACT = lambda do |allow_extra_attributes:|
|
12
|
-
describe '#call' do
|
13
|
-
shared_examples 'should assign the attributes' do
|
14
|
-
it { expect(result).to be_a_passing_result }
|
15
|
-
|
16
|
-
it { expect(result.value).to be_a entity.class }
|
17
|
-
|
18
|
-
it { expect(result.value).to be == expected_value }
|
19
|
-
end
|
20
|
-
|
21
|
-
let(:attributes) { {} }
|
22
|
-
let(:result) { command.call(attributes: attributes, entity: entity) }
|
23
|
-
let(:expected_attributes) do
|
24
|
-
initial_attributes.merge(attributes)
|
25
|
-
end
|
26
|
-
let(:expected_value) do
|
27
|
-
defined?(super()) ? super() : expected_attributes
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'should validate the :attributes keyword' do
|
31
|
-
expect(command)
|
32
|
-
.to validate_parameter(:call, :attributes)
|
33
|
-
.using_constraint(
|
34
|
-
Stannum::Constraints::Types::HashWithIndifferentKeys.new
|
35
|
-
)
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'should validate the :entity keyword' do
|
39
|
-
expect(command)
|
40
|
-
.to validate_parameter(:call, :entity)
|
41
|
-
.using_constraint(entity_type)
|
42
|
-
.with_parameters(attributes: {}, entity: nil)
|
43
|
-
end
|
44
|
-
|
45
|
-
describe 'with an empty attributes hash' do
|
46
|
-
let(:attributes) { {} }
|
47
|
-
|
48
|
-
include_examples 'should assign the attributes'
|
49
|
-
end
|
50
|
-
|
51
|
-
describe 'with an attributes hash with partial attributes' do
|
52
|
-
let(:attributes) { { title: 'Gideon the Ninth' } }
|
53
|
-
|
54
|
-
include_examples 'should assign the attributes'
|
55
|
-
end
|
56
|
-
|
57
|
-
describe 'with an attributes hash with full attributes' do
|
58
|
-
let(:attributes) do
|
59
|
-
{
|
60
|
-
title: 'Gideon the Ninth',
|
61
|
-
author: 'Tamsyn Muir',
|
62
|
-
series: 'The Locked Tomb',
|
63
|
-
category: 'Horror'
|
64
|
-
}
|
65
|
-
end
|
66
|
-
|
67
|
-
include_examples 'should assign the attributes'
|
68
|
-
end
|
69
|
-
|
70
|
-
describe 'with an attributes hash with extra attributes' do
|
71
|
-
let(:attributes) do
|
72
|
-
{
|
73
|
-
title: 'The Book of Lost Tales',
|
74
|
-
audiobook: true
|
75
|
-
}
|
76
|
-
end
|
77
|
-
|
78
|
-
if allow_extra_attributes
|
79
|
-
include_examples 'should assign the attributes'
|
80
|
-
else
|
81
|
-
# :nocov:
|
82
|
-
let(:valid_attributes) do
|
83
|
-
defined?(super()) ? super() : expected_attributes.keys
|
84
|
-
end
|
85
|
-
let(:expected_error) do
|
86
|
-
Cuprum::Collections::Errors::ExtraAttributes.new(
|
87
|
-
entity_class: entity.class,
|
88
|
-
extra_attributes: %w[audiobook],
|
89
|
-
valid_attributes: valid_attributes
|
90
|
-
)
|
91
|
-
end
|
92
|
-
|
93
|
-
it 'should return a failing result' do
|
94
|
-
expect(result).to be_a_failing_result.with_error(expected_error)
|
95
|
-
end
|
96
|
-
# :nocov:
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
context 'when the entity has existing attributes' do
|
101
|
-
let(:initial_attributes) do
|
102
|
-
# :nocov:
|
103
|
-
if defined?(super())
|
104
|
-
super().merge(fixtures_data.first)
|
105
|
-
else
|
106
|
-
fixtures_data.first
|
107
|
-
end
|
108
|
-
# :nocov:
|
109
|
-
end
|
110
|
-
|
111
|
-
describe 'with an empty attributes hash' do
|
112
|
-
let(:attributes) { {} }
|
113
|
-
|
114
|
-
include_examples 'should assign the attributes'
|
115
|
-
end
|
116
|
-
|
117
|
-
describe 'with an attributes hash with partial attributes' do
|
118
|
-
let(:attributes) { { title: 'Gideon the Ninth' } }
|
119
|
-
|
120
|
-
include_examples 'should assign the attributes'
|
121
|
-
end
|
122
|
-
|
123
|
-
describe 'with an attributes hash with full attributes' do
|
124
|
-
let(:attributes) do
|
125
|
-
{
|
126
|
-
title: 'Gideon the Ninth',
|
127
|
-
author: 'Tamsyn Muir',
|
128
|
-
series: 'The Locked Tomb',
|
129
|
-
category: 'Horror'
|
130
|
-
}
|
131
|
-
end
|
132
|
-
|
133
|
-
include_examples 'should assign the attributes'
|
134
|
-
end
|
135
|
-
|
136
|
-
describe 'with an attributes hash with extra attributes' do
|
137
|
-
let(:attributes) do
|
138
|
-
{
|
139
|
-
title: 'The Book of Lost Tales',
|
140
|
-
audiobook: true
|
141
|
-
}
|
142
|
-
end
|
143
|
-
|
144
|
-
if allow_extra_attributes
|
145
|
-
include_examples 'should assign the attributes'
|
146
|
-
else
|
147
|
-
# :nocov:
|
148
|
-
let(:valid_attributes) do
|
149
|
-
defined?(super()) ? super() : expected_attributes.keys
|
150
|
-
end
|
151
|
-
let(:expected_error) do
|
152
|
-
Cuprum::Collections::Errors::ExtraAttributes.new(
|
153
|
-
entity_class: entity.class,
|
154
|
-
extra_attributes: %w[audiobook],
|
155
|
-
valid_attributes: valid_attributes
|
156
|
-
)
|
157
|
-
end
|
158
|
-
|
159
|
-
it 'should return a failing result' do
|
160
|
-
expect(result).to be_a_failing_result.with_error(expected_error)
|
161
|
-
end
|
162
|
-
# :nocov:
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
@@ -1,93 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'stannum/constraints/types/hash_with_indifferent_keys'
|
4
|
-
require 'stannum/rspec/validate_parameter'
|
5
|
-
|
6
|
-
require 'cuprum/collections/rspec'
|
7
|
-
|
8
|
-
module Cuprum::Collections::RSpec
|
9
|
-
# Contract validating the behavior of a Build command implementation.
|
10
|
-
BUILD_ONE_COMMAND_CONTRACT = lambda do |allow_extra_attributes:|
|
11
|
-
include Stannum::RSpec::Matchers
|
12
|
-
|
13
|
-
describe '#call' do
|
14
|
-
shared_examples 'should build the entity' do
|
15
|
-
it { expect(result).to be_a_passing_result }
|
16
|
-
|
17
|
-
it { expect(result.value).to be == expected_value }
|
18
|
-
end
|
19
|
-
|
20
|
-
let(:attributes) { {} }
|
21
|
-
let(:result) { command.call(attributes: attributes) }
|
22
|
-
let(:expected_attributes) do
|
23
|
-
attributes
|
24
|
-
end
|
25
|
-
let(:expected_value) do
|
26
|
-
defined?(super()) ? super() : attributes
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'should validate the :attributes keyword' do
|
30
|
-
expect(command)
|
31
|
-
.to validate_parameter(:call, :attributes)
|
32
|
-
.using_constraint(
|
33
|
-
Stannum::Constraints::Types::HashWithIndifferentKeys.new
|
34
|
-
)
|
35
|
-
end
|
36
|
-
|
37
|
-
describe 'with an empty attributes hash' do
|
38
|
-
let(:attributes) { {} }
|
39
|
-
|
40
|
-
include_examples 'should build the entity'
|
41
|
-
end
|
42
|
-
|
43
|
-
describe 'with an attributes hash with partial attributes' do
|
44
|
-
let(:attributes) { { title: 'Gideon the Ninth' } }
|
45
|
-
|
46
|
-
include_examples 'should build the entity'
|
47
|
-
end
|
48
|
-
|
49
|
-
describe 'with an attributes hash with full attributes' do
|
50
|
-
let(:attributes) do
|
51
|
-
{
|
52
|
-
title: 'Gideon the Ninth',
|
53
|
-
author: 'Tamsyn Muir',
|
54
|
-
series: 'The Locked Tomb',
|
55
|
-
category: 'Horror'
|
56
|
-
}
|
57
|
-
end
|
58
|
-
|
59
|
-
include_examples 'should build the entity'
|
60
|
-
end
|
61
|
-
|
62
|
-
describe 'with an attributes hash with extra attributes' do
|
63
|
-
let(:attributes) do
|
64
|
-
{
|
65
|
-
title: 'The Book of Lost Tales',
|
66
|
-
audiobook: true
|
67
|
-
}
|
68
|
-
end
|
69
|
-
|
70
|
-
if allow_extra_attributes
|
71
|
-
include_examples 'should build the entity'
|
72
|
-
else
|
73
|
-
# :nocov:
|
74
|
-
let(:valid_attributes) do
|
75
|
-
defined?(super()) ? super() : expected_attributes.keys
|
76
|
-
end
|
77
|
-
let(:expected_error) do
|
78
|
-
Cuprum::Collections::Errors::ExtraAttributes.new(
|
79
|
-
entity_class: entity_type,
|
80
|
-
extra_attributes: %w[audiobook],
|
81
|
-
valid_attributes: valid_attributes
|
82
|
-
)
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'should return a failing result' do
|
86
|
-
expect(result).to be_a_failing_result.with_error(expected_error)
|
87
|
-
end
|
88
|
-
# :nocov:
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|