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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +47 -0
- data/lib/cuprum/collections/adaptable/collection.rb +18 -0
- data/lib/cuprum/collections/adaptable/command.rb +22 -0
- data/lib/cuprum/collections/adaptable/commands/abstract_assign_one.rb +27 -0
- data/lib/cuprum/collections/adaptable/commands/abstract_build_one.rb +25 -0
- data/lib/cuprum/collections/adaptable/commands/abstract_validate_one.rb +35 -0
- data/lib/cuprum/collections/adaptable/commands.rb +15 -0
- data/lib/cuprum/collections/adaptable/query.rb +64 -0
- data/lib/cuprum/collections/adaptable.rb +13 -0
- data/lib/cuprum/collections/adapter.rb +300 -0
- data/lib/cuprum/collections/adapters/data_adapter.rb +82 -0
- data/lib/cuprum/collections/adapters/entity_adapter.rb +76 -0
- data/lib/cuprum/collections/adapters/hash_adapter.rb +48 -0
- data/lib/cuprum/collections/adapters.rb +14 -0
- data/lib/cuprum/collections/basic/collection.rb +2 -20
- data/lib/cuprum/collections/basic/commands/destroy_one.rb +1 -1
- data/lib/cuprum/collections/basic/commands/find_many.rb +0 -31
- data/lib/cuprum/collections/basic/commands/find_matching.rb +0 -94
- data/lib/cuprum/collections/basic/commands/find_one.rb +0 -18
- data/lib/cuprum/collections/basic/commands/insert_one.rb +1 -1
- data/lib/cuprum/collections/basic/commands/update_one.rb +1 -1
- data/lib/cuprum/collections/basic/scopes/criteria_scope.rb +36 -21
- data/lib/cuprum/collections/basic.rb +6 -5
- data/lib/cuprum/collections/collection.rb +6 -0
- data/lib/cuprum/collections/collection_command.rb +1 -1
- data/lib/cuprum/collections/commands/abstract_find_many.rb +40 -3
- data/lib/cuprum/collections/commands/abstract_find_matching.rb +102 -0
- data/lib/cuprum/collections/commands/abstract_find_one.rb +23 -1
- data/lib/cuprum/collections/commands/associations/find_many.rb +1 -3
- data/lib/cuprum/collections/commands/associations/require_many.rb +1 -1
- data/lib/cuprum/collections/commands/find_one_matching.rb +10 -10
- data/lib/cuprum/collections/commands/query_command.rb +6 -4
- data/lib/cuprum/collections/commands/upsert.rb +0 -2
- data/lib/cuprum/collections/constraints/order/attributes_array.rb +5 -4
- data/lib/cuprum/collections/constraints/order/attributes_hash.rb +5 -4
- data/lib/cuprum/collections/constraints/order/sort_direction.rb +2 -2
- data/lib/cuprum/collections/constraints/ordering.rb +11 -9
- data/lib/cuprum/collections/constraints/query_hash.rb +2 -2
- data/lib/cuprum/collections/errors/abstract_find_error.rb +101 -23
- data/lib/cuprum/collections/errors/extra_attributes.rb +3 -3
- data/lib/cuprum/collections/errors/failed_validation.rb +3 -3
- data/lib/cuprum/collections/errors/missing_default_contract.rb +12 -4
- data/lib/cuprum/collections/queries.rb +4 -0
- data/lib/cuprum/collections/relation.rb +0 -2
- data/lib/cuprum/collections/relations/parameters.rb +120 -68
- data/lib/cuprum/collections/repository.rb +71 -6
- data/lib/cuprum/collections/rspec/contracts/query_contracts.rb +23 -4
- data/lib/cuprum/collections/rspec/contracts/repository_contracts.rb +18 -0
- data/lib/cuprum/collections/rspec/contracts/scope_contracts.rb +51 -0
- data/lib/cuprum/collections/rspec/contracts/scopes/builder_contracts.rb +10 -0
- data/lib/cuprum/collections/rspec/contracts/scopes/composition_contracts.rb +8 -0
- data/lib/cuprum/collections/rspec/contracts/scopes/criteria_contracts.rb +18 -366
- data/lib/cuprum/collections/rspec/contracts/scopes/logical_contracts.rb +30 -0
- data/lib/cuprum/collections/rspec/contracts/scopes.rb +2 -0
- data/lib/cuprum/collections/rspec/contracts.rb +2 -10
- data/lib/cuprum/collections/rspec/deferred/adapter_examples.rb +1077 -0
- data/lib/cuprum/collections/rspec/deferred/collection_examples.rb +27 -7
- data/lib/cuprum/collections/rspec/deferred/commands/assign_one_examples.rb +4 -4
- data/lib/cuprum/collections/rspec/deferred/commands/build_one_examples.rb +2 -2
- data/lib/cuprum/collections/rspec/deferred/commands/destroy_one_examples.rb +2 -2
- data/lib/cuprum/collections/rspec/deferred/commands/find_many_examples.rb +5 -5
- data/lib/cuprum/collections/rspec/deferred/commands/find_matching_examples.rb +45 -12
- data/lib/cuprum/collections/rspec/deferred/commands/find_one_examples.rb +2 -2
- data/lib/cuprum/collections/rspec/deferred/commands/insert_one_examples.rb +1 -1
- data/lib/cuprum/collections/rspec/deferred/commands/update_one_examples.rb +1 -1
- data/lib/cuprum/collections/rspec/deferred/query_examples.rb +930 -0
- data/lib/cuprum/collections/rspec/deferred/relation_examples.rb +48 -17
- data/lib/cuprum/collections/rspec/deferred/repository_examples.rb +961 -0
- data/lib/cuprum/collections/rspec/deferred/scope_examples.rb +598 -0
- data/lib/cuprum/collections/rspec/deferred/scopes/all_examples.rb +391 -0
- data/lib/cuprum/collections/rspec/deferred/scopes/builder_examples.rb +857 -0
- data/lib/cuprum/collections/rspec/deferred/scopes/composition_examples.rb +93 -0
- data/lib/cuprum/collections/rspec/deferred/scopes/conjunction_examples.rb +438 -0
- data/lib/cuprum/collections/rspec/deferred/scopes/criteria_examples.rb +1941 -0
- data/lib/cuprum/collections/rspec/deferred/scopes/disjunction_examples.rb +415 -0
- data/lib/cuprum/collections/rspec/deferred/scopes/none_examples.rb +385 -0
- data/lib/cuprum/collections/rspec/deferred/scopes/parser_examples.rb +740 -0
- data/lib/cuprum/collections/rspec/deferred/scopes.rb +8 -0
- data/lib/cuprum/collections/scope.rb +2 -2
- data/lib/cuprum/collections/scopes/container.rb +5 -4
- data/lib/cuprum/collections/scopes/criteria/parser.rb +24 -48
- data/lib/cuprum/collections/scopes/criteria.rb +7 -6
- data/lib/cuprum/collections/version.rb +4 -4
- data/lib/cuprum/collections.rb +5 -1
- metadata +47 -11
- data/lib/cuprum/collections/rspec/contracts/association_contracts.rb +0 -2127
- data/lib/cuprum/collections/rspec/contracts/basic.rb +0 -11
- data/lib/cuprum/collections/rspec/contracts/collection_contracts.rb +0 -387
- data/lib/cuprum/collections/rspec/contracts/command_contracts.rb +0 -169
- data/lib/cuprum/collections/rspec/contracts/relation_contracts.rb +0 -1264
|
@@ -0,0 +1,1077 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rspec/sleeping_king_studios/deferred/provider'
|
|
4
|
+
|
|
5
|
+
require 'cuprum/collections/rspec/deferred'
|
|
6
|
+
|
|
7
|
+
module Cuprum::Collections::RSpec::Deferred
|
|
8
|
+
# Deferred examples for testing collection adapters.
|
|
9
|
+
module AdapterExamples
|
|
10
|
+
include RSpec::SleepingKingStudios::Deferred::Provider
|
|
11
|
+
|
|
12
|
+
deferred_context 'when initialized with attribute names' do
|
|
13
|
+
let(:configured_attribute_names) do
|
|
14
|
+
next valid_attribute_names if defined?(valid_attribute_names)
|
|
15
|
+
|
|
16
|
+
%w[title author series]
|
|
17
|
+
end
|
|
18
|
+
let(:constructor_options) do
|
|
19
|
+
super().merge(attribute_names: configured_attribute_names)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
deferred_context 'with parameters for verifying adapters' do
|
|
24
|
+
let(:configured_invalid_attribute_names) do
|
|
25
|
+
next invalid_attribute_names if defined?(invalid_attribute_names)
|
|
26
|
+
|
|
27
|
+
%w[invalid_attribute other_invalid_attribute]
|
|
28
|
+
end
|
|
29
|
+
let(:configured_invalid_attributes) do
|
|
30
|
+
next invalid_attributes if defined?(invalid_attributes)
|
|
31
|
+
|
|
32
|
+
{}
|
|
33
|
+
end
|
|
34
|
+
let(:configured_partial_attributes) do
|
|
35
|
+
next partial_attributes if defined?(partial_attributes)
|
|
36
|
+
|
|
37
|
+
{ series: 'The Locked Tomb' }
|
|
38
|
+
end
|
|
39
|
+
let(:configured_valid_attributes) do
|
|
40
|
+
next valid_attributes if defined?(valid_attributes)
|
|
41
|
+
|
|
42
|
+
{
|
|
43
|
+
title: 'Gideon the Ninth',
|
|
44
|
+
author: 'Tamsyn Muir'
|
|
45
|
+
}
|
|
46
|
+
end
|
|
47
|
+
let(:configured_invalid_entity) do
|
|
48
|
+
next invalid_entity if defined?(invalid_entity)
|
|
49
|
+
|
|
50
|
+
build_entity(configured_invalid_attributes)
|
|
51
|
+
end
|
|
52
|
+
let(:configured_valid_entity) do
|
|
53
|
+
next valid_entity if defined?(valid_entity)
|
|
54
|
+
|
|
55
|
+
build_entity(configured_valid_attributes)
|
|
56
|
+
end
|
|
57
|
+
let(:configured_contract) do
|
|
58
|
+
next contract if defined?(contract)
|
|
59
|
+
|
|
60
|
+
type = 'spec.example_constraint'
|
|
61
|
+
message = 'is not a valid data object'
|
|
62
|
+
|
|
63
|
+
Stannum::Constraint.new(message:, type:) do |entity|
|
|
64
|
+
value =
|
|
65
|
+
if entity.respond_to?(:title)
|
|
66
|
+
entity.title
|
|
67
|
+
elsif entity.respond_to?(:[])
|
|
68
|
+
entity[:title] || entity['title']
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
value.is_a?(String) && !value.empty?
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
deferred_examples 'should implement the Adapter interface' do
|
|
77
|
+
describe '#allow_extra_attributes?' do
|
|
78
|
+
include_examples 'should define predicate', :allow_extra_attributes?
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
describe '#attribute_names' do
|
|
82
|
+
include_examples 'should define reader',
|
|
83
|
+
:attribute_names,
|
|
84
|
+
lambda {
|
|
85
|
+
be_a(Set)
|
|
86
|
+
.and(satisfy { |set| set.all? { |item| item.is_a?(String) } })
|
|
87
|
+
}
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
describe '#build' do
|
|
91
|
+
let(:attributes) { configured_valid_attributes }
|
|
92
|
+
|
|
93
|
+
define_method :call_adapter_method do
|
|
94
|
+
subject.build(attributes:)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
include_deferred 'with parameters for verifying adapters'
|
|
98
|
+
|
|
99
|
+
it 'should define the method' do
|
|
100
|
+
expect(subject)
|
|
101
|
+
.to respond_to(:build)
|
|
102
|
+
.with(0).arguments
|
|
103
|
+
.and_keywords(:attributes)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it 'should return a result' do
|
|
107
|
+
expect(call_adapter_method).to be_a_result
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
describe 'with attributes: nil' do
|
|
111
|
+
let(:attributes) { nil }
|
|
112
|
+
|
|
113
|
+
include_deferred 'should validate the attributes parameter'
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
describe 'with attributes: an Object' do
|
|
117
|
+
let(:attributes) { Object.new.freeze }
|
|
118
|
+
|
|
119
|
+
include_deferred 'should validate the attributes parameter'
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
describe 'with attributes: a Hash with invalid keys' do
|
|
123
|
+
let(:attributes) do
|
|
124
|
+
super().merge({
|
|
125
|
+
nil => 'null',
|
|
126
|
+
'' => 'blank',
|
|
127
|
+
10_000 => 'km'
|
|
128
|
+
})
|
|
129
|
+
end
|
|
130
|
+
let(:expected_failures) do
|
|
131
|
+
[
|
|
132
|
+
"attributes[nil] key can't be blank",
|
|
133
|
+
"attributes[\"\"] key can't be blank",
|
|
134
|
+
'attributes[10000] key is not a String or a Symbol'
|
|
135
|
+
]
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
include_deferred 'should validate the attributes parameter'
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
describe '#default_contract' do
|
|
143
|
+
include_examples 'should define reader', :default_contract
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
describe '#entity_class' do
|
|
147
|
+
include_examples 'should define reader', :entity_class
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
describe '#merge' do
|
|
151
|
+
let(:attributes) { configured_partial_attributes }
|
|
152
|
+
let(:entity) { configured_valid_entity }
|
|
153
|
+
|
|
154
|
+
define_method :call_adapter_method do
|
|
155
|
+
subject.merge(attributes:, entity:)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
include_deferred 'with parameters for verifying adapters'
|
|
159
|
+
|
|
160
|
+
it 'should define the method' do
|
|
161
|
+
expect(subject)
|
|
162
|
+
.to respond_to(:merge)
|
|
163
|
+
.with(0).arguments
|
|
164
|
+
.and_keywords(:attributes, :entity)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it 'should return a result' do
|
|
168
|
+
expect(call_adapter_method).to be_a_result
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
describe 'with attributes: nil' do
|
|
172
|
+
let(:attributes) { nil }
|
|
173
|
+
|
|
174
|
+
include_deferred 'should validate the attributes parameter'
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
describe 'with attributes: an Object' do
|
|
178
|
+
let(:attributes) { Object.new.freeze }
|
|
179
|
+
|
|
180
|
+
include_deferred 'should validate the attributes parameter'
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
describe 'with attributes: a Hash with invalid keys' do
|
|
184
|
+
let(:attributes) do
|
|
185
|
+
super().merge({
|
|
186
|
+
nil => 'null',
|
|
187
|
+
'' => 'blank',
|
|
188
|
+
10_000 => 'km'
|
|
189
|
+
})
|
|
190
|
+
end
|
|
191
|
+
let(:expected_failures) do
|
|
192
|
+
[
|
|
193
|
+
"attributes[nil] key can't be blank",
|
|
194
|
+
"attributes[\"\"] key can't be blank",
|
|
195
|
+
'attributes[10000] key is not a String or a Symbol'
|
|
196
|
+
]
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
include_deferred 'should validate the attributes parameter'
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
describe '#serialize' do
|
|
204
|
+
let(:entity) { configured_valid_entity }
|
|
205
|
+
|
|
206
|
+
define_method :call_adapter_method do
|
|
207
|
+
subject.serialize(entity:)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
include_deferred 'with parameters for verifying adapters'
|
|
211
|
+
|
|
212
|
+
it 'should define the method' do
|
|
213
|
+
expect(subject)
|
|
214
|
+
.to respond_to(:serialize)
|
|
215
|
+
.with(0).arguments
|
|
216
|
+
.and_keywords(:entity)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
it 'should return a result' do
|
|
220
|
+
expect(call_adapter_method).to be_a_result
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
describe '#validate' do
|
|
225
|
+
let(:entity) { configured_valid_entity }
|
|
226
|
+
let(:options) { {} }
|
|
227
|
+
|
|
228
|
+
define_method :call_adapter_method do
|
|
229
|
+
subject.validate(entity:, **options)
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
include_deferred 'with parameters for verifying adapters'
|
|
233
|
+
|
|
234
|
+
it 'should define the method' do
|
|
235
|
+
expect(subject)
|
|
236
|
+
.to respond_to(:validate)
|
|
237
|
+
.with(0).arguments
|
|
238
|
+
.and_keywords(:contract, :entity)
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
it 'should return a result' do
|
|
242
|
+
expect(call_adapter_method).to be_a_result
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
describe '#validate_attributes_parameter' do
|
|
247
|
+
it 'should define the method' do
|
|
248
|
+
expect(subject)
|
|
249
|
+
.to respond_to(:validate_attributes_parameter)
|
|
250
|
+
.with(1).argument
|
|
251
|
+
.and_keywords(:as)
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
describe '#validate_entity_parameter' do
|
|
256
|
+
it 'should define the method' do
|
|
257
|
+
expect(subject)
|
|
258
|
+
.to respond_to(:validate_entity_parameter)
|
|
259
|
+
.with(1).argument
|
|
260
|
+
.and_keywords(:as)
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
deferred_examples 'should implement the Adapter methods' do
|
|
266
|
+
describe '#build' do
|
|
267
|
+
let(:attributes) { configured_valid_attributes }
|
|
268
|
+
let(:expected_value) { build_entity(attributes) }
|
|
269
|
+
|
|
270
|
+
define_method :call_adapter_method do
|
|
271
|
+
subject.build(attributes:)
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
include_deferred 'with parameters for verifying adapters'
|
|
275
|
+
|
|
276
|
+
describe 'with an empty Hash' do
|
|
277
|
+
let(:attributes) { {} }
|
|
278
|
+
|
|
279
|
+
it 'should return a passing result' do
|
|
280
|
+
expect(call_adapter_method)
|
|
281
|
+
.to be_a_passing_result
|
|
282
|
+
.with_value(expected_value)
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
describe 'with a Hash with String keys' do
|
|
287
|
+
let(:attributes) { super().transform_keys(&:to_s) }
|
|
288
|
+
|
|
289
|
+
it 'should return a passing result' do
|
|
290
|
+
expect(call_adapter_method)
|
|
291
|
+
.to be_a_passing_result
|
|
292
|
+
.with_value(expected_value)
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
describe 'with a Hash with Symbol keys' do
|
|
297
|
+
let(:attributes) { super().transform_keys(&:to_sym) }
|
|
298
|
+
|
|
299
|
+
it 'should return a passing result' do
|
|
300
|
+
expect(call_adapter_method)
|
|
301
|
+
.to be_a_passing_result
|
|
302
|
+
.with_value(expected_value)
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
describe '#merge' do
|
|
308
|
+
let(:attributes) { configured_partial_attributes }
|
|
309
|
+
let(:entity) { configured_valid_entity }
|
|
310
|
+
let(:expected_attributes) do
|
|
311
|
+
configured_valid_attributes.merge(attributes)
|
|
312
|
+
end
|
|
313
|
+
let(:expected_value) { build_entity(expected_attributes) }
|
|
314
|
+
|
|
315
|
+
define_method :call_adapter_method do
|
|
316
|
+
subject.merge(attributes:, entity:)
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
include_deferred 'with parameters for verifying adapters'
|
|
320
|
+
|
|
321
|
+
describe 'with an empty Hash' do
|
|
322
|
+
let(:attributes) { {} }
|
|
323
|
+
|
|
324
|
+
it 'should return a passing result' do
|
|
325
|
+
expect(call_adapter_method)
|
|
326
|
+
.to be_a_passing_result
|
|
327
|
+
.with_value(expected_value)
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
describe 'with a Hash with String keys' do
|
|
332
|
+
let(:attributes) { super().transform_keys(&:to_s) }
|
|
333
|
+
|
|
334
|
+
it 'should return a passing result' do
|
|
335
|
+
expect(call_adapter_method)
|
|
336
|
+
.to be_a_passing_result
|
|
337
|
+
.with_value(expected_value)
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
describe 'with a Hash with Symbol keys' do
|
|
342
|
+
let(:attributes) { super().transform_keys(&:to_sym) }
|
|
343
|
+
|
|
344
|
+
it 'should return a passing result' do
|
|
345
|
+
expect(call_adapter_method)
|
|
346
|
+
.to be_a_passing_result
|
|
347
|
+
.with_value(expected_value)
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
describe '#serialize' do
|
|
353
|
+
let(:entity) { configured_valid_entity }
|
|
354
|
+
let(:expected_value) { serialize_entity(entity).transform_keys(&:to_s) }
|
|
355
|
+
|
|
356
|
+
define_method :call_adapter_method do
|
|
357
|
+
subject.serialize(entity:)
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
include_deferred 'with parameters for verifying adapters'
|
|
361
|
+
|
|
362
|
+
it 'should return a passing result' do
|
|
363
|
+
expect(call_adapter_method)
|
|
364
|
+
.to be_a_passing_result
|
|
365
|
+
.with_value(expected_value)
|
|
366
|
+
end
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
describe '#validate_attributes_parameter' do
|
|
370
|
+
describe 'with nil' do
|
|
371
|
+
let(:error_message) do
|
|
372
|
+
SleepingKingStudios::Tools::Toolbelt
|
|
373
|
+
.instance
|
|
374
|
+
.assertions
|
|
375
|
+
.error_message_for(
|
|
376
|
+
'sleeping_king_studios.tools.assertions.instance_of',
|
|
377
|
+
as: 'attributes',
|
|
378
|
+
expected: Hash
|
|
379
|
+
)
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
it 'should return the error message' do
|
|
383
|
+
expect(adapter.validate_attributes_parameter(nil))
|
|
384
|
+
.to be == error_message
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
describe 'with an Object' do
|
|
389
|
+
let(:error_message) do
|
|
390
|
+
SleepingKingStudios::Tools::Toolbelt
|
|
391
|
+
.instance
|
|
392
|
+
.assertions
|
|
393
|
+
.error_message_for(
|
|
394
|
+
'sleeping_king_studios.tools.assertions.instance_of',
|
|
395
|
+
as: 'attributes',
|
|
396
|
+
expected: Hash
|
|
397
|
+
)
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
it 'should return the error message' do
|
|
401
|
+
expect(adapter.validate_attributes_parameter(Object.new.freeze))
|
|
402
|
+
.to be == error_message
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
describe 'with an attributes Hash with invalid keys' do
|
|
407
|
+
let(:attributes) do
|
|
408
|
+
{
|
|
409
|
+
nil => 'null',
|
|
410
|
+
'' => 'blank',
|
|
411
|
+
10_000 => 'km'
|
|
412
|
+
}
|
|
413
|
+
end
|
|
414
|
+
let(:error_messages) do
|
|
415
|
+
[
|
|
416
|
+
"attributes[nil] key can't be blank",
|
|
417
|
+
"attributes[\"\"] key can't be blank",
|
|
418
|
+
'attributes[10000] key is not a String or a Symbol'
|
|
419
|
+
]
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
it 'should return the error message' do
|
|
423
|
+
expect(adapter.validate_attributes_parameter(attributes))
|
|
424
|
+
.to be == error_messages
|
|
425
|
+
end
|
|
426
|
+
end
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
deferred_examples 'should validate the attributes parameter' do
|
|
431
|
+
let(:configured_failures) do
|
|
432
|
+
next expected_failures if defined?(expected_failures)
|
|
433
|
+
|
|
434
|
+
message =
|
|
435
|
+
SleepingKingStudios::Tools::Toolbelt
|
|
436
|
+
.instance
|
|
437
|
+
.assertions
|
|
438
|
+
.error_message_for(
|
|
439
|
+
'sleeping_king_studios.tools.assertions.instance_of',
|
|
440
|
+
as: 'attributes',
|
|
441
|
+
expected: Hash
|
|
442
|
+
)
|
|
443
|
+
|
|
444
|
+
[message]
|
|
445
|
+
end
|
|
446
|
+
let(:expected_error) do
|
|
447
|
+
Cuprum::Errors::InvalidParameters.new(
|
|
448
|
+
command_class: described_class,
|
|
449
|
+
failures: configured_failures
|
|
450
|
+
)
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
it 'should return a failing result' do
|
|
454
|
+
expect(call_adapter_method)
|
|
455
|
+
.to be_a_failing_result
|
|
456
|
+
.with_error(expected_error)
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
deferred_examples 'should validate the attribute names' do
|
|
461
|
+
let(:expected_error) do
|
|
462
|
+
Cuprum::Collections::Errors::ExtraAttributes.new(
|
|
463
|
+
entity_class: adapter.entity_class,
|
|
464
|
+
extra_attributes: attributes.keys,
|
|
465
|
+
valid_attributes: adapter.attribute_names.to_a
|
|
466
|
+
)
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
it 'should return a failing result' do
|
|
470
|
+
expect(call_adapter_method)
|
|
471
|
+
.to be_a_failing_result
|
|
472
|
+
.with_error(expected_error)
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
deferred_examples 'should validate the attribute names by entity class' do
|
|
477
|
+
describe '#build' do
|
|
478
|
+
let(:attributes) do
|
|
479
|
+
configured_invalid_attribute_names.to_h { |key| [key, 'value'] }
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
define_method :call_adapter_method do
|
|
483
|
+
subject.build(attributes:)
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
include_deferred 'with parameters for verifying adapters'
|
|
487
|
+
|
|
488
|
+
describe 'with an attributes Hash with extra Strings' do
|
|
489
|
+
let(:attributes) { super().transform_keys(&:to_s) }
|
|
490
|
+
|
|
491
|
+
include_deferred 'should validate the attribute names'
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
describe 'with an attributes Hash with extra Symbols' do
|
|
495
|
+
let(:attributes) { super().transform_keys(&:to_sym) }
|
|
496
|
+
|
|
497
|
+
include_deferred 'should validate the attribute names'
|
|
498
|
+
end
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
describe '#merge' do
|
|
502
|
+
let(:attributes) do
|
|
503
|
+
configured_invalid_attribute_names.to_h { |key| [key, 'value'] }
|
|
504
|
+
end
|
|
505
|
+
let(:entity) { configured_valid_entity }
|
|
506
|
+
|
|
507
|
+
define_method :call_adapter_method do
|
|
508
|
+
subject.merge(attributes:, entity:)
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
include_deferred 'with parameters for verifying adapters'
|
|
512
|
+
|
|
513
|
+
describe 'with an attributes Hash with extra Strings' do
|
|
514
|
+
let(:attributes) { super().transform_keys(&:to_s) }
|
|
515
|
+
|
|
516
|
+
include_deferred 'should validate the attribute names'
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
describe 'with an attributes Hash with extra Symbols' do
|
|
520
|
+
let(:attributes) { super().transform_keys(&:to_sym) }
|
|
521
|
+
|
|
522
|
+
include_deferred 'should validate the attribute names'
|
|
523
|
+
end
|
|
524
|
+
end
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
deferred_examples 'should validate the attribute names by parameter' do
|
|
528
|
+
describe '#build' do
|
|
529
|
+
let(:attributes) do
|
|
530
|
+
configured_invalid_attribute_names.to_h { |key| [key, 'value'] }
|
|
531
|
+
end
|
|
532
|
+
|
|
533
|
+
define_method :call_adapter_method do
|
|
534
|
+
subject.build(attributes:)
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
include_deferred 'with parameters for verifying adapters'
|
|
538
|
+
|
|
539
|
+
wrap_deferred 'when initialized with attribute names' do
|
|
540
|
+
describe 'with an attributes Hash with extra Strings' do
|
|
541
|
+
let(:attributes) { super().transform_keys(&:to_s) }
|
|
542
|
+
|
|
543
|
+
include_deferred 'should validate the attribute names'
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
describe 'with an attributes Hash with extra Symbols' do
|
|
547
|
+
let(:attributes) { super().transform_keys(&:to_sym) }
|
|
548
|
+
|
|
549
|
+
include_deferred 'should validate the attribute names'
|
|
550
|
+
end
|
|
551
|
+
end
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
describe '#merge' do
|
|
555
|
+
let(:attributes) do
|
|
556
|
+
configured_invalid_attribute_names.to_h { |key| [key, 'value'] }
|
|
557
|
+
end
|
|
558
|
+
let(:entity) { configured_valid_entity }
|
|
559
|
+
|
|
560
|
+
define_method :call_adapter_method do
|
|
561
|
+
subject.merge(attributes:, entity:)
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
include_deferred 'with parameters for verifying adapters'
|
|
565
|
+
|
|
566
|
+
wrap_deferred 'when initialized with attribute names' do
|
|
567
|
+
describe 'with an attributes Hash with extra Strings' do
|
|
568
|
+
let(:attributes) { super().transform_keys(&:to_s) }
|
|
569
|
+
|
|
570
|
+
include_deferred 'should validate the attribute names'
|
|
571
|
+
end
|
|
572
|
+
|
|
573
|
+
describe 'with an attributes Hash with extra Symbols' do
|
|
574
|
+
let(:attributes) { super().transform_keys(&:to_sym) }
|
|
575
|
+
|
|
576
|
+
include_deferred 'should validate the attribute names'
|
|
577
|
+
end
|
|
578
|
+
end
|
|
579
|
+
end
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
deferred_examples 'should validate the entity parameter' do
|
|
583
|
+
let(:configured_failures) do
|
|
584
|
+
next expected_failures if defined?(expected_failures)
|
|
585
|
+
|
|
586
|
+
message =
|
|
587
|
+
SleepingKingStudios::Tools::Toolbelt
|
|
588
|
+
.instance
|
|
589
|
+
.assertions
|
|
590
|
+
.error_message_for(
|
|
591
|
+
'sleeping_king_studios.tools.assertions.instance_of',
|
|
592
|
+
as: 'entity',
|
|
593
|
+
expected: adapter.entity_class
|
|
594
|
+
)
|
|
595
|
+
|
|
596
|
+
[message]
|
|
597
|
+
end
|
|
598
|
+
let(:expected_error) do
|
|
599
|
+
failures = configured_failures
|
|
600
|
+
|
|
601
|
+
Cuprum::Errors::InvalidParameters.new(
|
|
602
|
+
command_class: described_class,
|
|
603
|
+
failures:
|
|
604
|
+
)
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
it 'should return a failing result' do
|
|
608
|
+
expect(call_adapter_method)
|
|
609
|
+
.to be_a_failing_result
|
|
610
|
+
.with_error(expected_error)
|
|
611
|
+
end
|
|
612
|
+
end
|
|
613
|
+
|
|
614
|
+
deferred_examples 'should validate the entity by fixed class' do
|
|
615
|
+
describe '#merge' do
|
|
616
|
+
let(:attributes) { configured_partial_attributes }
|
|
617
|
+
let(:entity) { configured_valid_entity }
|
|
618
|
+
|
|
619
|
+
define_method :call_adapter_method do
|
|
620
|
+
subject.merge(attributes:, entity:)
|
|
621
|
+
end
|
|
622
|
+
|
|
623
|
+
include_deferred 'with parameters for verifying adapters'
|
|
624
|
+
|
|
625
|
+
describe 'with entity: nil' do
|
|
626
|
+
let(:entity) { nil }
|
|
627
|
+
|
|
628
|
+
include_deferred 'should validate the entity parameter'
|
|
629
|
+
end
|
|
630
|
+
|
|
631
|
+
describe 'with entity: an Object' do
|
|
632
|
+
let(:entity) { Object.new.freeze }
|
|
633
|
+
|
|
634
|
+
include_deferred 'should validate the entity parameter'
|
|
635
|
+
end
|
|
636
|
+
end
|
|
637
|
+
|
|
638
|
+
describe '#serialize' do
|
|
639
|
+
let(:entity) { configured_valid_entity }
|
|
640
|
+
|
|
641
|
+
define_method :call_adapter_method do
|
|
642
|
+
subject.serialize(entity:)
|
|
643
|
+
end
|
|
644
|
+
|
|
645
|
+
include_deferred 'with parameters for verifying adapters'
|
|
646
|
+
|
|
647
|
+
describe 'with entity: nil' do
|
|
648
|
+
let(:entity) { nil }
|
|
649
|
+
|
|
650
|
+
include_deferred 'should validate the entity parameter'
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
describe 'with entity: an Object' do
|
|
654
|
+
let(:entity) { Object.new.freeze }
|
|
655
|
+
|
|
656
|
+
include_deferred 'should validate the entity parameter'
|
|
657
|
+
end
|
|
658
|
+
end
|
|
659
|
+
|
|
660
|
+
describe '#validate' do
|
|
661
|
+
let(:entity) { configured_valid_entity }
|
|
662
|
+
let(:options) { {} }
|
|
663
|
+
|
|
664
|
+
define_method :call_adapter_method do
|
|
665
|
+
subject.validate(entity:, **options)
|
|
666
|
+
end
|
|
667
|
+
|
|
668
|
+
include_deferred 'with parameters for verifying adapters'
|
|
669
|
+
|
|
670
|
+
describe 'with entity: nil' do
|
|
671
|
+
let(:entity) { nil }
|
|
672
|
+
|
|
673
|
+
include_deferred 'should validate the entity parameter'
|
|
674
|
+
end
|
|
675
|
+
|
|
676
|
+
describe 'with entity: an Object' do
|
|
677
|
+
let(:entity) { Object.new.freeze }
|
|
678
|
+
|
|
679
|
+
include_deferred 'should validate the entity parameter'
|
|
680
|
+
end
|
|
681
|
+
end
|
|
682
|
+
|
|
683
|
+
describe '#validate_entity_parameter' do
|
|
684
|
+
let(:configured_failures) do
|
|
685
|
+
next expected_failures if defined?(expected_failures)
|
|
686
|
+
|
|
687
|
+
message =
|
|
688
|
+
SleepingKingStudios::Tools::Toolbelt
|
|
689
|
+
.instance
|
|
690
|
+
.assertions
|
|
691
|
+
.error_message_for(
|
|
692
|
+
'sleeping_king_studios.tools.assertions.instance_of',
|
|
693
|
+
as: 'entity',
|
|
694
|
+
expected: adapter.entity_class
|
|
695
|
+
)
|
|
696
|
+
|
|
697
|
+
[message]
|
|
698
|
+
end
|
|
699
|
+
|
|
700
|
+
include_deferred 'with parameters for verifying adapters'
|
|
701
|
+
|
|
702
|
+
describe 'with entity: nil' do
|
|
703
|
+
let(:entity) { nil }
|
|
704
|
+
|
|
705
|
+
it 'should return the failure message' do
|
|
706
|
+
expect(adapter.validate_entity_parameter(entity))
|
|
707
|
+
.to be == configured_failures.join(', ')
|
|
708
|
+
end
|
|
709
|
+
end
|
|
710
|
+
|
|
711
|
+
describe 'with entity: an Object' do
|
|
712
|
+
let(:entity) { Object.new.freeze }
|
|
713
|
+
|
|
714
|
+
it 'should return the failure message' do
|
|
715
|
+
expect(adapter.validate_entity_parameter(entity))
|
|
716
|
+
.to be == configured_failures.join(', ')
|
|
717
|
+
end
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
describe 'with entity: a valid entity' do
|
|
721
|
+
let(:entity) { configured_valid_entity }
|
|
722
|
+
|
|
723
|
+
it { expect(adapter.validate_entity_parameter(entity)).to be nil }
|
|
724
|
+
end
|
|
725
|
+
end
|
|
726
|
+
end
|
|
727
|
+
|
|
728
|
+
deferred_examples 'should validate the entity by optional parameter' do
|
|
729
|
+
describe '#merge' do
|
|
730
|
+
let(:attributes) { configured_partial_attributes }
|
|
731
|
+
let(:entity) { configured_valid_entity }
|
|
732
|
+
|
|
733
|
+
define_method :call_adapter_method do
|
|
734
|
+
subject.merge(attributes:, entity:)
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
include_deferred 'with parameters for verifying adapters'
|
|
738
|
+
|
|
739
|
+
wrap_deferred 'when initialized with an entity class' do
|
|
740
|
+
describe 'with entity: nil' do
|
|
741
|
+
let(:entity) { nil }
|
|
742
|
+
|
|
743
|
+
include_deferred 'should validate the entity parameter'
|
|
744
|
+
end
|
|
745
|
+
|
|
746
|
+
describe 'with entity: an Object' do
|
|
747
|
+
let(:entity) { Object.new.freeze }
|
|
748
|
+
|
|
749
|
+
include_deferred 'should validate the entity parameter'
|
|
750
|
+
end
|
|
751
|
+
end
|
|
752
|
+
end
|
|
753
|
+
|
|
754
|
+
describe '#serialize' do
|
|
755
|
+
let(:entity) { configured_valid_entity }
|
|
756
|
+
|
|
757
|
+
define_method :call_adapter_method do
|
|
758
|
+
subject.serialize(entity:)
|
|
759
|
+
end
|
|
760
|
+
|
|
761
|
+
include_deferred 'with parameters for verifying adapters'
|
|
762
|
+
|
|
763
|
+
wrap_deferred 'when initialized with an entity class' do
|
|
764
|
+
describe 'with entity: nil' do
|
|
765
|
+
let(:entity) { nil }
|
|
766
|
+
|
|
767
|
+
include_deferred 'should validate the entity parameter'
|
|
768
|
+
end
|
|
769
|
+
|
|
770
|
+
describe 'with entity: an Object' do
|
|
771
|
+
let(:entity) { Object.new.freeze }
|
|
772
|
+
|
|
773
|
+
include_deferred 'should validate the entity parameter'
|
|
774
|
+
end
|
|
775
|
+
end
|
|
776
|
+
end
|
|
777
|
+
|
|
778
|
+
describe '#validate' do
|
|
779
|
+
let(:entity) { configured_valid_entity }
|
|
780
|
+
let(:options) { {} }
|
|
781
|
+
|
|
782
|
+
define_method :call_adapter_method do
|
|
783
|
+
subject.validate(entity:, **options)
|
|
784
|
+
end
|
|
785
|
+
|
|
786
|
+
include_deferred 'with parameters for verifying adapters'
|
|
787
|
+
|
|
788
|
+
wrap_deferred 'when initialized with an entity class' do
|
|
789
|
+
describe 'with entity: nil' do
|
|
790
|
+
let(:entity) { nil }
|
|
791
|
+
|
|
792
|
+
include_deferred 'should validate the entity parameter'
|
|
793
|
+
end
|
|
794
|
+
|
|
795
|
+
describe 'with entity: an Object' do
|
|
796
|
+
let(:entity) { Object.new.freeze }
|
|
797
|
+
|
|
798
|
+
include_deferred 'should validate the entity parameter'
|
|
799
|
+
end
|
|
800
|
+
end
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
describe '#validate_entity_parameter' do
|
|
804
|
+
let(:configured_failures) do
|
|
805
|
+
next expected_failures if defined?(expected_failures)
|
|
806
|
+
|
|
807
|
+
message =
|
|
808
|
+
SleepingKingStudios::Tools::Toolbelt
|
|
809
|
+
.instance
|
|
810
|
+
.assertions
|
|
811
|
+
.error_message_for(
|
|
812
|
+
'sleeping_king_studios.tools.assertions.instance_of',
|
|
813
|
+
as: 'entity',
|
|
814
|
+
expected: adapter.entity_class
|
|
815
|
+
)
|
|
816
|
+
|
|
817
|
+
[message]
|
|
818
|
+
end
|
|
819
|
+
|
|
820
|
+
include_deferred 'with parameters for verifying adapters'
|
|
821
|
+
|
|
822
|
+
wrap_deferred 'when initialized with an entity class' do
|
|
823
|
+
describe 'with entity: nil' do
|
|
824
|
+
let(:entity) { nil }
|
|
825
|
+
|
|
826
|
+
it 'should return the failure message' do
|
|
827
|
+
expect(adapter.validate_entity_parameter(entity))
|
|
828
|
+
.to be == configured_failures.join(', ')
|
|
829
|
+
end
|
|
830
|
+
end
|
|
831
|
+
|
|
832
|
+
describe 'with entity: an Object' do
|
|
833
|
+
let(:entity) { Object.new.freeze }
|
|
834
|
+
|
|
835
|
+
it 'should return the failure message' do
|
|
836
|
+
expect(adapter.validate_entity_parameter(entity))
|
|
837
|
+
.to be == configured_failures.join(', ')
|
|
838
|
+
end
|
|
839
|
+
end
|
|
840
|
+
|
|
841
|
+
describe 'with entity: a valid entity' do
|
|
842
|
+
let(:entity) { configured_valid_entity }
|
|
843
|
+
|
|
844
|
+
it { expect(adapter.validate_entity_parameter(entity)).to be nil }
|
|
845
|
+
end
|
|
846
|
+
end
|
|
847
|
+
end
|
|
848
|
+
end
|
|
849
|
+
|
|
850
|
+
deferred_examples 'should validate the entity by required parameter' do
|
|
851
|
+
describe '#merge' do
|
|
852
|
+
let(:attributes) { configured_partial_attributes }
|
|
853
|
+
let(:entity) { configured_valid_entity }
|
|
854
|
+
|
|
855
|
+
define_method :call_adapter_method do
|
|
856
|
+
subject.merge(attributes:, entity:)
|
|
857
|
+
end
|
|
858
|
+
|
|
859
|
+
include_deferred 'with parameters for verifying adapters'
|
|
860
|
+
|
|
861
|
+
describe 'with entity: nil' do
|
|
862
|
+
let(:entity) { nil }
|
|
863
|
+
|
|
864
|
+
include_deferred 'should validate the entity parameter'
|
|
865
|
+
end
|
|
866
|
+
|
|
867
|
+
describe 'with entity: an Object' do
|
|
868
|
+
let(:entity) { Object.new.freeze }
|
|
869
|
+
|
|
870
|
+
include_deferred 'should validate the entity parameter'
|
|
871
|
+
end
|
|
872
|
+
end
|
|
873
|
+
|
|
874
|
+
describe '#serialize' do
|
|
875
|
+
let(:entity) { configured_valid_entity }
|
|
876
|
+
|
|
877
|
+
define_method :call_adapter_method do
|
|
878
|
+
subject.serialize(entity:)
|
|
879
|
+
end
|
|
880
|
+
|
|
881
|
+
include_deferred 'with parameters for verifying adapters'
|
|
882
|
+
|
|
883
|
+
describe 'with entity: nil' do
|
|
884
|
+
let(:entity) { nil }
|
|
885
|
+
|
|
886
|
+
include_deferred 'should validate the entity parameter'
|
|
887
|
+
end
|
|
888
|
+
|
|
889
|
+
describe 'with entity: an Object' do
|
|
890
|
+
let(:entity) { Object.new.freeze }
|
|
891
|
+
|
|
892
|
+
include_deferred 'should validate the entity parameter'
|
|
893
|
+
end
|
|
894
|
+
end
|
|
895
|
+
|
|
896
|
+
describe '#validate' do
|
|
897
|
+
let(:entity) { configured_valid_entity }
|
|
898
|
+
let(:options) { {} }
|
|
899
|
+
|
|
900
|
+
define_method :call_adapter_method do
|
|
901
|
+
subject.validate(entity:, **options)
|
|
902
|
+
end
|
|
903
|
+
|
|
904
|
+
include_deferred 'with parameters for verifying adapters'
|
|
905
|
+
|
|
906
|
+
describe 'with entity: nil' do
|
|
907
|
+
let(:entity) { nil }
|
|
908
|
+
|
|
909
|
+
include_deferred 'should validate the entity parameter'
|
|
910
|
+
end
|
|
911
|
+
|
|
912
|
+
describe 'with entity: an Object' do
|
|
913
|
+
let(:entity) { Object.new.freeze }
|
|
914
|
+
|
|
915
|
+
include_deferred 'should validate the entity parameter'
|
|
916
|
+
end
|
|
917
|
+
end
|
|
918
|
+
|
|
919
|
+
describe '#validate_entity_parameter' do
|
|
920
|
+
let(:configured_failures) do
|
|
921
|
+
next expected_failures if defined?(expected_failures)
|
|
922
|
+
|
|
923
|
+
message =
|
|
924
|
+
SleepingKingStudios::Tools::Toolbelt
|
|
925
|
+
.instance
|
|
926
|
+
.assertions
|
|
927
|
+
.error_message_for(
|
|
928
|
+
'sleeping_king_studios.tools.assertions.instance_of',
|
|
929
|
+
as: 'entity',
|
|
930
|
+
expected: adapter.entity_class
|
|
931
|
+
)
|
|
932
|
+
|
|
933
|
+
[message]
|
|
934
|
+
end
|
|
935
|
+
|
|
936
|
+
include_deferred 'with parameters for verifying adapters'
|
|
937
|
+
|
|
938
|
+
describe 'with entity: nil' do
|
|
939
|
+
let(:entity) { nil }
|
|
940
|
+
|
|
941
|
+
it 'should return the failure message' do
|
|
942
|
+
expect(adapter.validate_entity_parameter(entity))
|
|
943
|
+
.to be == configured_failures.join(', ')
|
|
944
|
+
end
|
|
945
|
+
end
|
|
946
|
+
|
|
947
|
+
describe 'with entity: an Object' do
|
|
948
|
+
let(:entity) { Object.new.freeze }
|
|
949
|
+
|
|
950
|
+
it 'should return the failure message' do
|
|
951
|
+
expect(adapter.validate_entity_parameter(entity))
|
|
952
|
+
.to be == configured_failures.join(', ')
|
|
953
|
+
end
|
|
954
|
+
end
|
|
955
|
+
|
|
956
|
+
describe 'with entity: a valid entity' do
|
|
957
|
+
let(:entity) { configured_valid_entity }
|
|
958
|
+
|
|
959
|
+
it { expect(adapter.validate_entity_parameter(entity)).to be nil }
|
|
960
|
+
end
|
|
961
|
+
end
|
|
962
|
+
end
|
|
963
|
+
|
|
964
|
+
deferred_examples 'should validate the entity using the default contract' \
|
|
965
|
+
do |**deferred_options|
|
|
966
|
+
describe '#validate' do
|
|
967
|
+
let(:entity) { configured_valid_entity }
|
|
968
|
+
let(:options) { {} }
|
|
969
|
+
let(:expected_error) do
|
|
970
|
+
Cuprum::Collections::Errors::MissingDefaultContract
|
|
971
|
+
.new(entity_class: adapter.entity_class)
|
|
972
|
+
end
|
|
973
|
+
|
|
974
|
+
define_method :call_adapter_method do
|
|
975
|
+
subject.validate(entity:, **options)
|
|
976
|
+
end
|
|
977
|
+
|
|
978
|
+
include_deferred 'with parameters for verifying adapters'
|
|
979
|
+
|
|
980
|
+
if deferred_options.fetch(:require_default_contract, true)
|
|
981
|
+
it 'should return a failing result' do
|
|
982
|
+
expect(call_adapter_method)
|
|
983
|
+
.to be_a_failing_result
|
|
984
|
+
.with_error(expected_error)
|
|
985
|
+
end
|
|
986
|
+
end
|
|
987
|
+
|
|
988
|
+
describe 'with contract: value' do
|
|
989
|
+
let(:options) { super().merge(contract: configured_contract) }
|
|
990
|
+
|
|
991
|
+
describe 'when the entity does not match the contract' do
|
|
992
|
+
let(:entity) { configured_invalid_entity }
|
|
993
|
+
let(:expected_error) do
|
|
994
|
+
errors = configured_contract.errors_for(entity)
|
|
995
|
+
|
|
996
|
+
Cuprum::Collections::Errors::FailedValidation.new(
|
|
997
|
+
entity_class: adapter.entity_class,
|
|
998
|
+
errors:
|
|
999
|
+
)
|
|
1000
|
+
end
|
|
1001
|
+
|
|
1002
|
+
it 'should return a failing result' do
|
|
1003
|
+
expect(call_adapter_method)
|
|
1004
|
+
.to be_a_failing_result
|
|
1005
|
+
.with_error(expected_error)
|
|
1006
|
+
end
|
|
1007
|
+
end
|
|
1008
|
+
|
|
1009
|
+
describe 'when the entity matches the contract' do
|
|
1010
|
+
let(:entity) { configured_valid_entity }
|
|
1011
|
+
|
|
1012
|
+
it 'should return a passing result' do
|
|
1013
|
+
expect(call_adapter_method)
|
|
1014
|
+
.to be_a_passing_result
|
|
1015
|
+
.with_value(entity)
|
|
1016
|
+
end
|
|
1017
|
+
end
|
|
1018
|
+
end
|
|
1019
|
+
|
|
1020
|
+
context 'when initialized with a default contract' do
|
|
1021
|
+
let(:constructor_options) do
|
|
1022
|
+
super().merge(default_contract: configured_contract)
|
|
1023
|
+
end
|
|
1024
|
+
|
|
1025
|
+
describe 'when the entity does not match the contract' do
|
|
1026
|
+
let(:entity) { configured_invalid_entity }
|
|
1027
|
+
let(:expected_error) do
|
|
1028
|
+
errors = configured_contract.errors_for(entity)
|
|
1029
|
+
|
|
1030
|
+
Cuprum::Collections::Errors::FailedValidation.new(
|
|
1031
|
+
entity_class: adapter.entity_class,
|
|
1032
|
+
errors:
|
|
1033
|
+
)
|
|
1034
|
+
end
|
|
1035
|
+
|
|
1036
|
+
it 'should return a failing result' do
|
|
1037
|
+
expect(call_adapter_method)
|
|
1038
|
+
.to be_a_failing_result
|
|
1039
|
+
.with_error(expected_error)
|
|
1040
|
+
end
|
|
1041
|
+
end
|
|
1042
|
+
|
|
1043
|
+
describe 'when the entity matches the contract' do
|
|
1044
|
+
let(:entity) { configured_valid_entity }
|
|
1045
|
+
|
|
1046
|
+
it 'should return a passing result' do
|
|
1047
|
+
expect(call_adapter_method)
|
|
1048
|
+
.to be_a_passing_result
|
|
1049
|
+
.with_value(entity)
|
|
1050
|
+
end
|
|
1051
|
+
end
|
|
1052
|
+
|
|
1053
|
+
describe 'with contract: value' do
|
|
1054
|
+
let(:options) do
|
|
1055
|
+
super().merge(contract: Stannum::Constraints::Nothing.new)
|
|
1056
|
+
end
|
|
1057
|
+
let(:entity) { configured_valid_entity }
|
|
1058
|
+
let(:expected_error) do
|
|
1059
|
+
errors = options[:contract].errors_for(entity)
|
|
1060
|
+
|
|
1061
|
+
Cuprum::Collections::Errors::FailedValidation.new(
|
|
1062
|
+
entity_class: adapter.entity_class,
|
|
1063
|
+
errors:
|
|
1064
|
+
)
|
|
1065
|
+
end
|
|
1066
|
+
|
|
1067
|
+
it 'should return a failing result' do
|
|
1068
|
+
expect(call_adapter_method)
|
|
1069
|
+
.to be_a_failing_result
|
|
1070
|
+
.with_error(expected_error)
|
|
1071
|
+
end
|
|
1072
|
+
end
|
|
1073
|
+
end
|
|
1074
|
+
end
|
|
1075
|
+
end
|
|
1076
|
+
end
|
|
1077
|
+
end
|