cuprum-collections 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +73 -0
- data/README.md +5 -5
- data/lib/cuprum/collections/association.rb +9 -28
- data/lib/cuprum/collections/associations/belongs_to.rb +1 -8
- data/lib/cuprum/collections/associations/has_many.rb +1 -10
- data/lib/cuprum/collections/associations/has_one.rb +1 -10
- data/lib/cuprum/collections/basic/collection.rb +56 -49
- data/lib/cuprum/collections/basic/command.rb +22 -88
- data/lib/cuprum/collections/basic/commands/assign_one.rb +2 -6
- data/lib/cuprum/collections/basic/commands/build_one.rb +1 -4
- data/lib/cuprum/collections/basic/commands/destroy_one.rb +4 -8
- data/lib/cuprum/collections/basic/commands/find_many.rb +4 -24
- data/lib/cuprum/collections/basic/commands/find_matching.rb +5 -21
- data/lib/cuprum/collections/basic/commands/find_one.rb +3 -20
- data/lib/cuprum/collections/basic/commands/insert_one.rb +3 -6
- data/lib/cuprum/collections/basic/commands/update_one.rb +3 -6
- data/lib/cuprum/collections/basic/commands/validate_one.rb +13 -18
- data/lib/cuprum/collections/basic/query.rb +26 -40
- data/lib/cuprum/collections/basic/repository.rb +4 -3
- data/lib/cuprum/collections/basic/scopes/all_scope.rb +25 -0
- data/lib/cuprum/collections/basic/scopes/base.rb +32 -0
- data/lib/cuprum/collections/basic/scopes/builder.rb +39 -0
- data/lib/cuprum/collections/basic/scopes/conjunction_scope.rb +20 -0
- data/lib/cuprum/collections/basic/scopes/criteria_scope.rb +62 -0
- data/lib/cuprum/collections/basic/scopes/disjunction_scope.rb +20 -0
- data/lib/cuprum/collections/basic/scopes/none_scope.rb +33 -0
- data/lib/cuprum/collections/basic/scopes.rb +23 -0
- data/lib/cuprum/collections/basic.rb +1 -0
- data/lib/cuprum/collections/collection.rb +24 -82
- data/lib/cuprum/collections/collection_command.rb +116 -0
- data/lib/cuprum/collections/commands/abstract_find_many.rb +11 -21
- data/lib/cuprum/collections/commands/abstract_find_matching.rb +43 -24
- data/lib/cuprum/collections/commands/abstract_find_one.rb +7 -10
- data/lib/cuprum/collections/commands/associations/find_many.rb +3 -8
- data/lib/cuprum/collections/commands/associations/require_many.rb +5 -5
- data/lib/cuprum/collections/commands/create.rb +3 -3
- data/lib/cuprum/collections/commands/find_one_matching.rb +6 -6
- data/lib/cuprum/collections/commands/query_command.rb +19 -0
- data/lib/cuprum/collections/commands/update.rb +3 -3
- data/lib/cuprum/collections/commands/upsert.rb +10 -10
- data/lib/cuprum/collections/commands.rb +1 -0
- data/lib/cuprum/collections/constraints/ordering.rb +2 -2
- data/lib/cuprum/collections/errors/abstract_find_error.rb +25 -42
- data/lib/cuprum/collections/errors/extra_attributes.rb +3 -3
- data/lib/cuprum/collections/errors/failed_validation.rb +2 -2
- data/lib/cuprum/collections/errors/invalid_parameters.rb +2 -2
- data/lib/cuprum/collections/errors/invalid_query.rb +10 -16
- data/lib/cuprum/collections/errors/missing_default_contract.rb +1 -1
- data/lib/cuprum/collections/errors/unknown_operator.rb +1 -1
- data/lib/cuprum/collections/queries.rb +31 -0
- data/lib/cuprum/collections/query.rb +50 -62
- data/lib/cuprum/collections/relation.rb +5 -383
- data/lib/cuprum/collections/relations/cardinality.rb +66 -0
- data/lib/cuprum/collections/relations/options.rb +18 -0
- data/lib/cuprum/collections/relations/parameters.rb +217 -0
- data/lib/cuprum/collections/relations/primary_keys.rb +23 -0
- data/lib/cuprum/collections/relations/scope.rb +65 -0
- data/lib/cuprum/collections/relations.rb +14 -0
- data/lib/cuprum/collections/repository.rb +5 -5
- data/lib/cuprum/collections/resource.rb +10 -41
- data/lib/cuprum/collections/rspec/contracts/association_contracts.rb +80 -90
- data/lib/cuprum/collections/rspec/contracts/collection_contracts.rb +69 -111
- data/lib/cuprum/collections/rspec/contracts/command_contracts.rb +42 -1335
- data/lib/cuprum/collections/rspec/contracts/query_contracts.rb +352 -531
- data/lib/cuprum/collections/rspec/contracts/relation_contracts.rb +74 -191
- data/lib/cuprum/collections/rspec/contracts/repository_contracts.rb +13 -13
- data/lib/cuprum/collections/rspec/contracts/scope_contracts.rb +1029 -0
- data/lib/cuprum/collections/rspec/contracts/scopes/builder_contracts.rb +856 -0
- data/lib/cuprum/collections/rspec/contracts/scopes/composition_contracts.rb +1430 -0
- data/lib/cuprum/collections/rspec/contracts/scopes/criteria_contracts.rb +2217 -0
- data/lib/cuprum/collections/rspec/contracts/scopes/logical_contracts.rb +297 -0
- data/lib/cuprum/collections/rspec/contracts/scopes.rb +13 -0
- data/lib/cuprum/collections/rspec/contracts.rb +2 -0
- data/lib/cuprum/collections/rspec/deferred/association_examples.rb +2098 -0
- data/lib/cuprum/collections/rspec/deferred/collection_examples.rb +338 -0
- data/lib/cuprum/collections/rspec/deferred/command_examples.rb +160 -0
- data/lib/cuprum/collections/rspec/deferred/commands/assign_one_examples.rb +178 -0
- data/lib/cuprum/collections/rspec/deferred/commands/build_one_examples.rb +94 -0
- data/lib/cuprum/collections/rspec/deferred/commands/destroy_one_examples.rb +118 -0
- data/lib/cuprum/collections/rspec/deferred/commands/find_many_examples.rb +307 -0
- data/lib/cuprum/collections/rspec/deferred/commands/find_matching_examples.rb +143 -0
- data/lib/cuprum/collections/rspec/deferred/commands/find_one_examples.rb +116 -0
- data/lib/cuprum/collections/rspec/deferred/commands/insert_one_examples.rb +103 -0
- data/lib/cuprum/collections/rspec/deferred/commands/update_one_examples.rb +99 -0
- data/lib/cuprum/collections/rspec/deferred/commands/validate_one_examples.rb +117 -0
- data/lib/cuprum/collections/rspec/deferred/commands.rb +8 -0
- data/lib/cuprum/collections/rspec/deferred/relation_examples.rb +1437 -0
- data/lib/cuprum/collections/rspec/deferred/resource_examples.rb +26 -0
- data/lib/cuprum/collections/rspec/deferred.rb +8 -0
- data/lib/cuprum/collections/scope.rb +29 -0
- data/lib/cuprum/collections/scopes/all.rb +51 -0
- data/lib/cuprum/collections/scopes/all_scope.rb +18 -0
- data/lib/cuprum/collections/scopes/base.rb +79 -0
- data/lib/cuprum/collections/scopes/builder.rb +39 -0
- data/lib/cuprum/collections/scopes/building.rb +221 -0
- data/lib/cuprum/collections/scopes/composition.rb +162 -0
- data/lib/cuprum/collections/scopes/conjunction.rb +44 -0
- data/lib/cuprum/collections/scopes/conjunction_scope.rb +12 -0
- data/lib/cuprum/collections/scopes/container.rb +65 -0
- data/lib/cuprum/collections/scopes/criteria/parser.rb +241 -0
- data/lib/cuprum/collections/scopes/criteria.rb +206 -0
- data/lib/cuprum/collections/scopes/criteria_scope.rb +12 -0
- data/lib/cuprum/collections/scopes/disjunction.rb +45 -0
- data/lib/cuprum/collections/scopes/disjunction_scope.rb +12 -0
- data/lib/cuprum/collections/scopes/none.rb +62 -0
- data/lib/cuprum/collections/scopes/none_scope.rb +18 -0
- data/lib/cuprum/collections/scopes.rb +23 -0
- data/lib/cuprum/collections/version.rb +2 -2
- data/lib/cuprum/collections.rb +14 -9
- metadata +61 -15
- data/lib/cuprum/collections/basic/query_builder.rb +0 -69
- data/lib/cuprum/collections/command.rb +0 -26
- data/lib/cuprum/collections/queries/parse.rb +0 -22
- data/lib/cuprum/collections/queries/parse_block.rb +0 -206
- data/lib/cuprum/collections/queries/parse_strategy.rb +0 -91
- data/lib/cuprum/collections/query_builder.rb +0 -61
- data/lib/cuprum/collections/rspec/contracts/basic/command_contracts.rb +0 -484
@@ -0,0 +1,1029 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cuprum/collections/rspec/contracts'
|
4
|
+
require 'cuprum/collections/rspec/fixtures'
|
5
|
+
require 'cuprum/collections/scope'
|
6
|
+
|
7
|
+
module Cuprum::Collections::RSpec::Contracts
|
8
|
+
# Contracts for asserting on scope objects.
|
9
|
+
module ScopeContracts
|
10
|
+
# Contract validating the behavior of a scope implementation.
|
11
|
+
module ShouldBeAScopeContract
|
12
|
+
extend RSpec::SleepingKingStudios::Contract
|
13
|
+
|
14
|
+
# @!method apply(example_group, invertible: false)
|
15
|
+
# Adds the contract to the example group.
|
16
|
+
#
|
17
|
+
# @param example_group [RSpec::Core::ExampleGroup] the example group to
|
18
|
+
# which the contract is applied.
|
19
|
+
# @param invertible [Boolean] if true, the scope defines an
|
20
|
+
# implementation of the #invert method. Defaults to false.
|
21
|
+
contract do |invertible: false|
|
22
|
+
describe '#==' do
|
23
|
+
it { expect(subject == nil).to be false } # rubocop:disable Style/NilComparison
|
24
|
+
|
25
|
+
it { expect(subject == Object.new.freeze).to be false }
|
26
|
+
|
27
|
+
describe 'with a scope of different type' do
|
28
|
+
let(:other) { Spec::OtherScope.new }
|
29
|
+
|
30
|
+
example_class 'Spec::OtherScope',
|
31
|
+
Cuprum::Collections::Scopes::Base \
|
32
|
+
do |klass|
|
33
|
+
klass.define_method(:type) { :invalid }
|
34
|
+
end
|
35
|
+
|
36
|
+
it { expect(subject == other).to be false }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#as_json' do
|
41
|
+
it { expect(subject).to respond_to(:as_json).with(0).arguments }
|
42
|
+
|
43
|
+
it { expect(subject.as_json).to be_a Hash }
|
44
|
+
|
45
|
+
it { expect(subject.as_json['type']).to be subject.type }
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#empty?' do
|
49
|
+
include_examples 'should define predicate', :empty?, -> { be_boolean }
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#invert' do
|
53
|
+
let(:error_class) do
|
54
|
+
Cuprum::Collections::Scopes::Base::UninvertibleScopeException
|
55
|
+
end
|
56
|
+
let(:error_message) do
|
57
|
+
"Scope class #{described_class} does not implement #invert"
|
58
|
+
end
|
59
|
+
|
60
|
+
it { expect(subject).to respond_to(:invert).with(0).arguments }
|
61
|
+
|
62
|
+
next if invertible
|
63
|
+
|
64
|
+
it 'should raise an exception' do
|
65
|
+
expect { subject.invert }.to raise_error error_class, error_message
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '#type' do
|
70
|
+
include_examples 'should define reader', :type, -> { be_a(Symbol) }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Contract validating the behavior of a Container scope implementation.
|
76
|
+
module ShouldBeAContainerScopeContract
|
77
|
+
extend RSpec::SleepingKingStudios::Contract
|
78
|
+
|
79
|
+
# @!method apply(example_group, invertible: false)
|
80
|
+
# Adds the contract to the example group.
|
81
|
+
#
|
82
|
+
# @param example_group [RSpec::Core::ExampleGroup] the example group to
|
83
|
+
# which the contract is applied.
|
84
|
+
# @param invertible [Boolean] if true, the scope defines an
|
85
|
+
# implementation of the #invert method. Defaults to false.
|
86
|
+
contract do |invertible: false|
|
87
|
+
shared_context 'with scopes' do
|
88
|
+
let(:scopes) do
|
89
|
+
[
|
90
|
+
build_scope({ 'title' => 'J.R.R. Tolkien' }),
|
91
|
+
build_scope({ 'series' => 'The Lord of the Rings' }),
|
92
|
+
build_scope({ 'category' => 'Science Fiction and Fantasy' })
|
93
|
+
]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe '.new' do
|
98
|
+
it 'should define the constructor' do
|
99
|
+
expect(described_class)
|
100
|
+
.to be_constructible
|
101
|
+
.with(0).arguments
|
102
|
+
.and_keywords(:scopes)
|
103
|
+
.and_any_keywords
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
include_contract('should be a scope', invertible:)
|
108
|
+
|
109
|
+
describe '#==' do
|
110
|
+
describe 'with a scope with the same class' do
|
111
|
+
let(:other) { described_class.new(scopes: other_scopes) }
|
112
|
+
|
113
|
+
describe 'with empty scopes' do
|
114
|
+
let(:other_scopes) { [] }
|
115
|
+
|
116
|
+
it { expect(subject == other).to be true }
|
117
|
+
end
|
118
|
+
|
119
|
+
describe 'with non-matching scopes' do
|
120
|
+
let(:other_scopes) do
|
121
|
+
Array.new(3) do
|
122
|
+
Cuprum::Collections::Scope.new({ 'ok' => true })
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
it { expect(subject == other).to be false }
|
127
|
+
end
|
128
|
+
|
129
|
+
wrap_context 'with scopes' do
|
130
|
+
describe 'with empty scopes' do
|
131
|
+
let(:other_scopes) { [] }
|
132
|
+
|
133
|
+
it { expect(subject == other).to be false }
|
134
|
+
end
|
135
|
+
|
136
|
+
describe 'with non-matching scopes' do
|
137
|
+
let(:other_scopes) do
|
138
|
+
Array.new(3) do
|
139
|
+
Cuprum::Collections::Scope.new({ 'ok' => true })
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
it { expect(subject == other).to be false }
|
144
|
+
end
|
145
|
+
|
146
|
+
describe 'with matching scopes' do
|
147
|
+
let(:other_scopes) { subject.scopes }
|
148
|
+
|
149
|
+
it { expect(subject == other).to be true }
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe 'with a scope with the same type' do
|
155
|
+
let(:other) { Spec::CustomScope.new(scopes: other_scopes) }
|
156
|
+
|
157
|
+
example_class 'Spec::CustomScope',
|
158
|
+
Cuprum::Collections::Scopes::Base \
|
159
|
+
do |klass|
|
160
|
+
klass.include Cuprum::Collections::Scopes::Container
|
161
|
+
end
|
162
|
+
|
163
|
+
before(:example) do
|
164
|
+
allow(other).to receive(:type).and_return(scope.type)
|
165
|
+
end
|
166
|
+
|
167
|
+
describe 'with empty scopes' do
|
168
|
+
let(:other_scopes) { [] }
|
169
|
+
|
170
|
+
it { expect(subject == other).to be true }
|
171
|
+
end
|
172
|
+
|
173
|
+
describe 'with non-matching scopes' do
|
174
|
+
let(:other_scopes) do
|
175
|
+
Array.new(3) do
|
176
|
+
Cuprum::Collections::Scope.new({ 'ok' => true })
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
it { expect(subject == other).to be false }
|
181
|
+
end
|
182
|
+
|
183
|
+
wrap_context 'with scopes' do
|
184
|
+
describe 'with empty scopes' do
|
185
|
+
let(:other_scopes) { [] }
|
186
|
+
|
187
|
+
it { expect(subject == other).to be false }
|
188
|
+
end
|
189
|
+
|
190
|
+
describe 'with non-matching scopes' do
|
191
|
+
let(:other_scopes) do
|
192
|
+
Array.new(3) do
|
193
|
+
Cuprum::Collections::Scope.new({ 'ok' => true })
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
it { expect(subject == other).to be false }
|
198
|
+
end
|
199
|
+
|
200
|
+
describe 'with matching scopes' do
|
201
|
+
let(:other_scopes) { subject.scopes }
|
202
|
+
|
203
|
+
it { expect(subject == other).to be true }
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
describe '#as_json' do
|
210
|
+
it { expect(subject.as_json['scopes']).to be == [] }
|
211
|
+
|
212
|
+
wrap_context 'with scopes' do
|
213
|
+
let(:expected) { subject.scopes.map(&:as_json) }
|
214
|
+
|
215
|
+
it { expect(subject.as_json['scopes']).to be == expected }
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe '#empty?' do
|
220
|
+
it { expect(subject.empty?).to be true }
|
221
|
+
|
222
|
+
wrap_context 'with scopes' do
|
223
|
+
it { expect(subject.empty?).to be false }
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
describe '#scopes' do
|
228
|
+
include_examples 'should define reader', :scopes, -> { scopes }
|
229
|
+
|
230
|
+
wrap_context 'with scopes' do
|
231
|
+
it { expect(subject.scopes).to be == scopes }
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
describe '#with_scopes' do
|
236
|
+
let(:new_scopes) do
|
237
|
+
[
|
238
|
+
described_class.new(scopes: []),
|
239
|
+
described_class.new(scopes: [])
|
240
|
+
]
|
241
|
+
end
|
242
|
+
|
243
|
+
it { expect(subject).to respond_to(:with_scopes).with(1).arguments }
|
244
|
+
|
245
|
+
it 'should return a scope' do
|
246
|
+
expect(subject.with_scopes(new_scopes)).to be_a described_class
|
247
|
+
end
|
248
|
+
|
249
|
+
it "should not change the original scope's child scopes" do
|
250
|
+
expect { subject.with_scopes(new_scopes) }
|
251
|
+
.not_to change(subject, :scopes)
|
252
|
+
end
|
253
|
+
|
254
|
+
it "should set the copied scope's child scopes" do
|
255
|
+
expect(subject.with_scopes(new_scopes).scopes)
|
256
|
+
.to be == new_scopes
|
257
|
+
end
|
258
|
+
|
259
|
+
wrap_context 'with scopes' do
|
260
|
+
it "should not change the original scope's child scopes" do
|
261
|
+
expect { subject.with_scopes(new_scopes) }
|
262
|
+
.not_to change(subject, :scopes)
|
263
|
+
end
|
264
|
+
|
265
|
+
it "should set the copied scope's child scopes" do
|
266
|
+
expect(subject.with_scopes(new_scopes).scopes)
|
267
|
+
.to be == new_scopes
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
# Contract validating the behavior of an All scope implementation.
|
275
|
+
module ShouldBeAnAllScopeContract
|
276
|
+
extend RSpec::SleepingKingStudios::Contract
|
277
|
+
|
278
|
+
# @!method apply(example_group, abstract: false)
|
279
|
+
# Adds the contract to the example group.
|
280
|
+
#
|
281
|
+
# @param example_group [RSpec::Core::ExampleGroup] the example group to
|
282
|
+
# which the contract is applied.
|
283
|
+
# @param abstract [Boolean] if true, the scope is abstract and does not
|
284
|
+
# define a #call implementation. Defaults to false.
|
285
|
+
contract do |abstract: false|
|
286
|
+
include_contract 'should be a scope', invertible: true
|
287
|
+
|
288
|
+
describe '#==' do
|
289
|
+
describe 'with a scope with the same class' do
|
290
|
+
let(:other) { described_class.new }
|
291
|
+
|
292
|
+
it { expect(subject == other).to be true }
|
293
|
+
end
|
294
|
+
|
295
|
+
describe 'with a scope with the same type' do
|
296
|
+
let(:other) { Spec::CustomScope.new }
|
297
|
+
|
298
|
+
example_class 'Spec::CustomScope',
|
299
|
+
Cuprum::Collections::Scopes::Base \
|
300
|
+
do |klass|
|
301
|
+
klass.define_method(:type) { :all }
|
302
|
+
end
|
303
|
+
|
304
|
+
it { expect(subject == other).to be true }
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
describe '#and' do
|
309
|
+
it 'should define the method' do
|
310
|
+
expect(subject)
|
311
|
+
.to respond_to(:and)
|
312
|
+
.with(0..1).arguments
|
313
|
+
.and_a_block
|
314
|
+
end
|
315
|
+
|
316
|
+
it { expect(subject).to have_aliased_method(:and).as(:where) }
|
317
|
+
|
318
|
+
describe 'with a block' do
|
319
|
+
let(:block) { -> { { 'title' => 'A Wizard of Earthsea' } } }
|
320
|
+
let(:expected) do
|
321
|
+
Cuprum::Collections::Scope.new(&block)
|
322
|
+
end
|
323
|
+
|
324
|
+
it { expect(subject.and(&block)).to be == expected }
|
325
|
+
end
|
326
|
+
|
327
|
+
describe 'with a hash' do
|
328
|
+
let(:value) { { 'title' => 'A Wizard of Earthsea' } }
|
329
|
+
let(:expected) do
|
330
|
+
Cuprum::Collections::Scope.new(value)
|
331
|
+
end
|
332
|
+
|
333
|
+
it { expect(subject.and(value)).to be == expected }
|
334
|
+
end
|
335
|
+
|
336
|
+
describe 'with an all scope' do
|
337
|
+
let(:original) do
|
338
|
+
Cuprum::Collections::Scopes::AllScope.new
|
339
|
+
end
|
340
|
+
|
341
|
+
it { expect(subject.and(original)).to be == original }
|
342
|
+
end
|
343
|
+
|
344
|
+
describe 'with a none scope' do
|
345
|
+
let(:original) do
|
346
|
+
Cuprum::Collections::Scopes::NoneScope.new
|
347
|
+
end
|
348
|
+
|
349
|
+
it { expect(subject.and(original)).to be == original }
|
350
|
+
end
|
351
|
+
|
352
|
+
describe 'with an empty conjunction scope' do
|
353
|
+
let(:original) do
|
354
|
+
Cuprum::Collections::Scopes::ConjunctionScope.new(scopes: [])
|
355
|
+
end
|
356
|
+
|
357
|
+
it { expect(subject.and(original)).to be subject }
|
358
|
+
end
|
359
|
+
|
360
|
+
describe 'with an empty criteria scope' do
|
361
|
+
let(:original) do
|
362
|
+
Cuprum::Collections::Scopes::CriteriaScope.new(criteria: [])
|
363
|
+
end
|
364
|
+
|
365
|
+
it { expect(subject.and(original)).to be subject }
|
366
|
+
end
|
367
|
+
|
368
|
+
describe 'with an empty disjunction scope' do
|
369
|
+
let(:original) do
|
370
|
+
Cuprum::Collections::Scopes::DisjunctionScope.new(scopes: [])
|
371
|
+
end
|
372
|
+
|
373
|
+
it { expect(subject.and(original)).to be subject }
|
374
|
+
end
|
375
|
+
|
376
|
+
describe 'with a non-empty conjunction scope' do
|
377
|
+
let(:original) do
|
378
|
+
wrapped =
|
379
|
+
Cuprum::Collections::Scope
|
380
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
381
|
+
|
382
|
+
Cuprum::Collections::Scopes::ConjunctionScope
|
383
|
+
.new(scopes: [wrapped])
|
384
|
+
end
|
385
|
+
|
386
|
+
it { expect(subject.and(original)).to be == original }
|
387
|
+
end
|
388
|
+
|
389
|
+
describe 'with a non-empty criteria scope' do
|
390
|
+
let(:original) do
|
391
|
+
Cuprum::Collections::Scope
|
392
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
393
|
+
end
|
394
|
+
|
395
|
+
it { expect(subject.and(original)).to be == original }
|
396
|
+
end
|
397
|
+
|
398
|
+
describe 'with a non-empty disjunction scope' do
|
399
|
+
let(:original) do
|
400
|
+
wrapped =
|
401
|
+
Cuprum::Collections::Scope
|
402
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
403
|
+
|
404
|
+
Cuprum::Collections::Scopes::DisjunctionScope
|
405
|
+
.new(scopes: [wrapped])
|
406
|
+
end
|
407
|
+
|
408
|
+
it { expect(subject.and(original)).to be == original }
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
describe '#as_json' do
|
413
|
+
let(:expected) { { 'type' => subject.type } }
|
414
|
+
|
415
|
+
it { expect(subject.as_json).to be == expected }
|
416
|
+
end
|
417
|
+
|
418
|
+
describe '#call' do
|
419
|
+
shared_context 'with data' do
|
420
|
+
let(:data) do
|
421
|
+
Cuprum::Collections::RSpec::Fixtures::BOOKS_FIXTURES
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
next if abstract
|
426
|
+
|
427
|
+
describe 'with empty data' do
|
428
|
+
let(:data) { [] }
|
429
|
+
|
430
|
+
it { expect(filtered_data).to be == [] }
|
431
|
+
end
|
432
|
+
|
433
|
+
wrap_context 'with data' do
|
434
|
+
let(:expected) { data }
|
435
|
+
|
436
|
+
it { expect(filtered_data).to match_array expected }
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
describe '#empty?' do
|
441
|
+
it { expect(subject.empty?).to be false }
|
442
|
+
end
|
443
|
+
|
444
|
+
describe '#invert' do
|
445
|
+
let(:expected) { Cuprum::Collections::Scopes::NoneScope.new }
|
446
|
+
|
447
|
+
it { expect(subject.invert).to be == expected }
|
448
|
+
end
|
449
|
+
|
450
|
+
describe '#not' do
|
451
|
+
it 'should define the method' do
|
452
|
+
expect(subject)
|
453
|
+
.to respond_to(:not)
|
454
|
+
.with(0..1).arguments
|
455
|
+
.and_a_block
|
456
|
+
end
|
457
|
+
|
458
|
+
describe 'with a block' do
|
459
|
+
let(:block) { -> { { 'title' => 'A Wizard of Earthsea' } } }
|
460
|
+
let(:expected) do
|
461
|
+
Cuprum::Collections::Scope.new(&block).invert
|
462
|
+
end
|
463
|
+
|
464
|
+
it { expect(subject.not(&block)).to be == expected }
|
465
|
+
end
|
466
|
+
|
467
|
+
describe 'with a hash' do
|
468
|
+
let(:value) { { 'title' => 'A Wizard of Earthsea' } }
|
469
|
+
let(:expected) do
|
470
|
+
Cuprum::Collections::Scope.new(value).invert
|
471
|
+
end
|
472
|
+
|
473
|
+
it { expect(subject.not(value)).to be == expected }
|
474
|
+
end
|
475
|
+
|
476
|
+
describe 'with an all scope' do
|
477
|
+
let(:original) do
|
478
|
+
Cuprum::Collections::Scopes::AllScope.new
|
479
|
+
end
|
480
|
+
let(:expected) do
|
481
|
+
Cuprum::Collections::Scopes::NoneScope.new
|
482
|
+
end
|
483
|
+
|
484
|
+
it { expect(subject.not(original)).to be == expected }
|
485
|
+
end
|
486
|
+
|
487
|
+
describe 'with a none scope' do
|
488
|
+
let(:original) do
|
489
|
+
Cuprum::Collections::Scopes::NoneScope.new
|
490
|
+
end
|
491
|
+
|
492
|
+
it { expect(subject.not(original)).to be == subject }
|
493
|
+
end
|
494
|
+
|
495
|
+
describe 'with an empty conjunction scope' do
|
496
|
+
let(:original) do
|
497
|
+
Cuprum::Collections::Scopes::ConjunctionScope.new(scopes: [])
|
498
|
+
end
|
499
|
+
|
500
|
+
it { expect(subject.not(original)).to be subject }
|
501
|
+
end
|
502
|
+
|
503
|
+
describe 'with an empty criteria scope' do
|
504
|
+
let(:original) do
|
505
|
+
Cuprum::Collections::Scopes::CriteriaScope.new(criteria: [])
|
506
|
+
end
|
507
|
+
|
508
|
+
it { expect(subject.not(original)).to be subject }
|
509
|
+
end
|
510
|
+
|
511
|
+
describe 'with an empty disjunction scope' do
|
512
|
+
let(:original) do
|
513
|
+
Cuprum::Collections::Scopes::DisjunctionScope.new(scopes: [])
|
514
|
+
end
|
515
|
+
|
516
|
+
it { expect(subject.not(original)).to be subject }
|
517
|
+
end
|
518
|
+
|
519
|
+
describe 'with a non-empty conjunction scope' do
|
520
|
+
let(:original) do
|
521
|
+
wrapped =
|
522
|
+
Cuprum::Collections::Scope
|
523
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
524
|
+
|
525
|
+
Cuprum::Collections::Scopes::ConjunctionScope
|
526
|
+
.new(scopes: [wrapped])
|
527
|
+
end
|
528
|
+
|
529
|
+
it { expect(subject.not(original)).to be == original.invert }
|
530
|
+
end
|
531
|
+
|
532
|
+
describe 'with a non-empty criteria scope' do
|
533
|
+
let(:original) do
|
534
|
+
Cuprum::Collections::Scope
|
535
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
536
|
+
end
|
537
|
+
|
538
|
+
it { expect(subject.not(original)).to be == original.invert }
|
539
|
+
end
|
540
|
+
|
541
|
+
describe 'with a non-empty disjunction scope' do
|
542
|
+
let(:original) do
|
543
|
+
wrapped =
|
544
|
+
Cuprum::Collections::Scope
|
545
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
546
|
+
|
547
|
+
Cuprum::Collections::Scopes::DisjunctionScope
|
548
|
+
.new(scopes: [wrapped])
|
549
|
+
end
|
550
|
+
|
551
|
+
it { expect(subject.not(original)).to be == original.invert }
|
552
|
+
end
|
553
|
+
end
|
554
|
+
|
555
|
+
describe '#or' do
|
556
|
+
it 'should define the method' do
|
557
|
+
expect(subject)
|
558
|
+
.to respond_to(:or)
|
559
|
+
.with(0..1).arguments
|
560
|
+
.and_a_block
|
561
|
+
end
|
562
|
+
|
563
|
+
describe 'with a block' do
|
564
|
+
let(:block) { -> { { 'title' => 'A Wizard of Earthsea' } } }
|
565
|
+
let(:expected) do
|
566
|
+
Cuprum::Collections::Scope.new(&block)
|
567
|
+
end
|
568
|
+
|
569
|
+
it { expect(subject.or(&block)).to be == expected }
|
570
|
+
end
|
571
|
+
|
572
|
+
describe 'with a hash' do
|
573
|
+
let(:value) { { 'title' => 'A Wizard of Earthsea' } }
|
574
|
+
let(:expected) do
|
575
|
+
Cuprum::Collections::Scope.new(value)
|
576
|
+
end
|
577
|
+
|
578
|
+
it { expect(subject.or(value)).to be == expected }
|
579
|
+
end
|
580
|
+
|
581
|
+
describe 'with an all scope' do
|
582
|
+
let(:original) do
|
583
|
+
Cuprum::Collections::Scopes::AllScope.new
|
584
|
+
end
|
585
|
+
|
586
|
+
it { expect(subject.and(original)).to be == original }
|
587
|
+
end
|
588
|
+
|
589
|
+
describe 'with an empty conjunction scope' do
|
590
|
+
let(:original) do
|
591
|
+
Cuprum::Collections::Scopes::ConjunctionScope.new(scopes: [])
|
592
|
+
end
|
593
|
+
|
594
|
+
it { expect(subject.or(original)).to be subject }
|
595
|
+
end
|
596
|
+
|
597
|
+
describe 'with an empty criteria scope' do
|
598
|
+
let(:original) do
|
599
|
+
Cuprum::Collections::Scopes::CriteriaScope.new(criteria: [])
|
600
|
+
end
|
601
|
+
|
602
|
+
it { expect(subject.or(original)).to be subject }
|
603
|
+
end
|
604
|
+
|
605
|
+
describe 'with an empty disjunction scope' do
|
606
|
+
let(:original) do
|
607
|
+
Cuprum::Collections::Scopes::DisjunctionScope.new(scopes: [])
|
608
|
+
end
|
609
|
+
|
610
|
+
it { expect(subject.or(original)).to be subject }
|
611
|
+
end
|
612
|
+
|
613
|
+
describe 'with a non-empty conjunction scope' do
|
614
|
+
let(:original) do
|
615
|
+
wrapped =
|
616
|
+
Cuprum::Collections::Scope
|
617
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
618
|
+
|
619
|
+
Cuprum::Collections::Scopes::ConjunctionScope
|
620
|
+
.new(scopes: [wrapped])
|
621
|
+
end
|
622
|
+
|
623
|
+
it { expect(subject.or(original)).to be == original }
|
624
|
+
end
|
625
|
+
|
626
|
+
describe 'with a non-empty criteria scope' do
|
627
|
+
let(:original) do
|
628
|
+
Cuprum::Collections::Scope
|
629
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
630
|
+
end
|
631
|
+
|
632
|
+
it { expect(subject.or(original)).to be == original }
|
633
|
+
end
|
634
|
+
|
635
|
+
describe 'with a non-empty disjunction scope' do
|
636
|
+
let(:original) do
|
637
|
+
wrapped =
|
638
|
+
Cuprum::Collections::Scope
|
639
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
640
|
+
|
641
|
+
Cuprum::Collections::Scopes::DisjunctionScope
|
642
|
+
.new(scopes: [wrapped])
|
643
|
+
end
|
644
|
+
|
645
|
+
it { expect(subject.or(original)).to be == original }
|
646
|
+
end
|
647
|
+
end
|
648
|
+
|
649
|
+
describe '#type' do
|
650
|
+
it { expect(subject.type).to be :all }
|
651
|
+
end
|
652
|
+
end
|
653
|
+
end
|
654
|
+
|
655
|
+
# Contract validating the behavior of a None scope implementation.
|
656
|
+
module ShouldBeANoneScopeContract
|
657
|
+
extend RSpec::SleepingKingStudios::Contract
|
658
|
+
|
659
|
+
# @!method apply(example_group, abstract: false)
|
660
|
+
# Adds the contract to the example group.
|
661
|
+
#
|
662
|
+
# @param example_group [RSpec::Core::ExampleGroup] the example group to
|
663
|
+
# which the contract is applied.
|
664
|
+
# @param abstract [Boolean] if true, the scope is abstract and does not
|
665
|
+
# define a #call implementation. Defaults to false.
|
666
|
+
contract do |abstract: false|
|
667
|
+
include_contract 'should be a scope', invertible: true
|
668
|
+
|
669
|
+
describe '#==' do
|
670
|
+
describe 'with a scope with the same class' do
|
671
|
+
let(:other) { described_class.new }
|
672
|
+
|
673
|
+
it { expect(subject == other).to be true }
|
674
|
+
end
|
675
|
+
|
676
|
+
describe 'with a scope with the same type' do
|
677
|
+
let(:other) { Spec::CustomScope.new }
|
678
|
+
|
679
|
+
example_class 'Spec::CustomScope',
|
680
|
+
Cuprum::Collections::Scopes::Base \
|
681
|
+
do |klass|
|
682
|
+
klass.define_method(:type) { :none }
|
683
|
+
end
|
684
|
+
|
685
|
+
it { expect(subject == other).to be true }
|
686
|
+
end
|
687
|
+
end
|
688
|
+
|
689
|
+
describe '#and' do
|
690
|
+
it 'should define the method' do
|
691
|
+
expect(subject)
|
692
|
+
.to respond_to(:and)
|
693
|
+
.with(0..1).arguments
|
694
|
+
.and_a_block
|
695
|
+
end
|
696
|
+
|
697
|
+
it { expect(subject).to have_aliased_method(:and).as(:where) }
|
698
|
+
|
699
|
+
describe 'with a block' do
|
700
|
+
let(:block) { -> { { 'title' => 'A Wizard of Earthsea' } } }
|
701
|
+
|
702
|
+
it { expect(subject.and(&block)).to be subject }
|
703
|
+
end
|
704
|
+
|
705
|
+
describe 'with a hash' do
|
706
|
+
let(:value) { { 'title' => 'A Wizard of Earthsea' } }
|
707
|
+
|
708
|
+
it { expect(subject.and(value)).to be subject }
|
709
|
+
end
|
710
|
+
|
711
|
+
describe 'with an all scope' do
|
712
|
+
let(:original) do
|
713
|
+
Cuprum::Collections::Scopes::AllScope.new
|
714
|
+
end
|
715
|
+
|
716
|
+
it { expect(subject.and(original)).to be subject }
|
717
|
+
end
|
718
|
+
|
719
|
+
describe 'with a none scope' do
|
720
|
+
let(:original) do
|
721
|
+
Cuprum::Collections::Scopes::NoneScope.new
|
722
|
+
end
|
723
|
+
|
724
|
+
it { expect(subject.and(original)).to be subject }
|
725
|
+
end
|
726
|
+
|
727
|
+
describe 'with an empty conjunction scope' do
|
728
|
+
let(:original) do
|
729
|
+
Cuprum::Collections::Scopes::ConjunctionScope.new(scopes: [])
|
730
|
+
end
|
731
|
+
|
732
|
+
it { expect(subject.and(original)).to be subject }
|
733
|
+
end
|
734
|
+
|
735
|
+
describe 'with an empty criteria scope' do
|
736
|
+
let(:original) do
|
737
|
+
Cuprum::Collections::Scopes::CriteriaScope.new(criteria: [])
|
738
|
+
end
|
739
|
+
|
740
|
+
it { expect(subject.and(original)).to be subject }
|
741
|
+
end
|
742
|
+
|
743
|
+
describe 'with an empty disjunction scope' do
|
744
|
+
let(:original) do
|
745
|
+
Cuprum::Collections::Scopes::DisjunctionScope.new(scopes: [])
|
746
|
+
end
|
747
|
+
|
748
|
+
it { expect(subject.and(original)).to be subject }
|
749
|
+
end
|
750
|
+
|
751
|
+
describe 'with a non-empty conjunction scope' do
|
752
|
+
let(:original) do
|
753
|
+
wrapped =
|
754
|
+
Cuprum::Collections::Scope
|
755
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
756
|
+
|
757
|
+
Cuprum::Collections::Scopes::ConjunctionScope
|
758
|
+
.new(scopes: [wrapped])
|
759
|
+
end
|
760
|
+
|
761
|
+
it { expect(subject.and(original)).to be subject }
|
762
|
+
end
|
763
|
+
|
764
|
+
describe 'with a non-empty criteria scope' do
|
765
|
+
let(:original) do
|
766
|
+
Cuprum::Collections::Scope
|
767
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
768
|
+
end
|
769
|
+
|
770
|
+
it { expect(subject.and(original)).to be subject }
|
771
|
+
end
|
772
|
+
|
773
|
+
describe 'with a non-empty disjunction scope' do
|
774
|
+
let(:original) do
|
775
|
+
wrapped =
|
776
|
+
Cuprum::Collections::Scope
|
777
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
778
|
+
|
779
|
+
Cuprum::Collections::Scopes::DisjunctionScope
|
780
|
+
.new(scopes: [wrapped])
|
781
|
+
end
|
782
|
+
|
783
|
+
it { expect(subject.and(original)).to be subject }
|
784
|
+
end
|
785
|
+
end
|
786
|
+
|
787
|
+
describe '#as_json' do
|
788
|
+
let(:expected) { { 'type' => subject.type } }
|
789
|
+
|
790
|
+
it { expect(subject.as_json).to be == expected }
|
791
|
+
end
|
792
|
+
|
793
|
+
describe '#call' do
|
794
|
+
shared_context 'with data' do
|
795
|
+
let(:data) do
|
796
|
+
Cuprum::Collections::RSpec::Fixtures::BOOKS_FIXTURES
|
797
|
+
end
|
798
|
+
end
|
799
|
+
|
800
|
+
next if abstract
|
801
|
+
|
802
|
+
describe 'with empty data' do
|
803
|
+
let(:data) { [] }
|
804
|
+
|
805
|
+
it { expect(filtered_data).to be == [] }
|
806
|
+
end
|
807
|
+
|
808
|
+
wrap_context 'with data' do
|
809
|
+
let(:expected) { [] }
|
810
|
+
|
811
|
+
it { expect(filtered_data).to match_array expected }
|
812
|
+
end
|
813
|
+
end
|
814
|
+
|
815
|
+
describe '#empty?' do
|
816
|
+
it { expect(subject.empty?).to be false }
|
817
|
+
end
|
818
|
+
|
819
|
+
describe '#invert' do
|
820
|
+
let(:expected) { Cuprum::Collections::Scopes::AllScope.new }
|
821
|
+
|
822
|
+
it { expect(subject.invert).to be == expected }
|
823
|
+
end
|
824
|
+
|
825
|
+
describe '#not' do
|
826
|
+
it 'should define the method' do
|
827
|
+
expect(subject)
|
828
|
+
.to respond_to(:not)
|
829
|
+
.with(0..1).arguments
|
830
|
+
.and_a_block
|
831
|
+
end
|
832
|
+
|
833
|
+
describe 'with a block' do
|
834
|
+
let(:block) { -> { { 'title' => 'A Wizard of Earthsea' } } }
|
835
|
+
|
836
|
+
it { expect(subject.not(&block)).to be subject }
|
837
|
+
end
|
838
|
+
|
839
|
+
describe 'with a hash' do
|
840
|
+
let(:value) { { 'title' => 'A Wizard of Earthsea' } }
|
841
|
+
|
842
|
+
it { expect(subject.not(value)).to be subject }
|
843
|
+
end
|
844
|
+
|
845
|
+
describe 'with an all scope' do
|
846
|
+
let(:original) do
|
847
|
+
Cuprum::Collections::Scopes::AllScope.new
|
848
|
+
end
|
849
|
+
|
850
|
+
it { expect(subject.not(original)).to be subject }
|
851
|
+
end
|
852
|
+
|
853
|
+
describe 'with a none scope' do
|
854
|
+
let(:original) do
|
855
|
+
Cuprum::Collections::Scopes::AllScope.new
|
856
|
+
end
|
857
|
+
|
858
|
+
it { expect(subject.not(original)).to be subject }
|
859
|
+
end
|
860
|
+
|
861
|
+
describe 'with an empty conjunction scope' do
|
862
|
+
let(:original) do
|
863
|
+
Cuprum::Collections::Scopes::ConjunctionScope.new(scopes: [])
|
864
|
+
end
|
865
|
+
|
866
|
+
it { expect(subject.not(original)).to be subject }
|
867
|
+
end
|
868
|
+
|
869
|
+
describe 'with an empty criteria scope' do
|
870
|
+
let(:original) do
|
871
|
+
Cuprum::Collections::Scopes::CriteriaScope.new(criteria: [])
|
872
|
+
end
|
873
|
+
|
874
|
+
it { expect(subject.not(original)).to be subject }
|
875
|
+
end
|
876
|
+
|
877
|
+
describe 'with an empty disjunction scope' do
|
878
|
+
let(:original) do
|
879
|
+
Cuprum::Collections::Scopes::DisjunctionScope.new(scopes: [])
|
880
|
+
end
|
881
|
+
|
882
|
+
it { expect(subject.not(original)).to be subject }
|
883
|
+
end
|
884
|
+
|
885
|
+
describe 'with a non-empty conjunction scope' do
|
886
|
+
let(:original) do
|
887
|
+
wrapped =
|
888
|
+
Cuprum::Collections::Scope
|
889
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
890
|
+
|
891
|
+
Cuprum::Collections::Scopes::ConjunctionScope
|
892
|
+
.new(scopes: [wrapped])
|
893
|
+
end
|
894
|
+
|
895
|
+
it { expect(subject.not(original)).to be subject }
|
896
|
+
end
|
897
|
+
|
898
|
+
describe 'with a non-empty criteria scope' do
|
899
|
+
let(:original) do
|
900
|
+
Cuprum::Collections::Scope
|
901
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
902
|
+
end
|
903
|
+
|
904
|
+
it { expect(subject.not(original)).to be subject }
|
905
|
+
end
|
906
|
+
|
907
|
+
describe 'with a non-empty disjunction scope' do
|
908
|
+
let(:original) do
|
909
|
+
wrapped =
|
910
|
+
Cuprum::Collections::Scope
|
911
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
912
|
+
|
913
|
+
Cuprum::Collections::Scopes::DisjunctionScope
|
914
|
+
.new(scopes: [wrapped])
|
915
|
+
end
|
916
|
+
|
917
|
+
it { expect(subject.not(original)).to be subject }
|
918
|
+
end
|
919
|
+
end
|
920
|
+
|
921
|
+
describe '#or' do
|
922
|
+
it 'should define the method' do
|
923
|
+
expect(subject)
|
924
|
+
.to respond_to(:or)
|
925
|
+
.with(0..1).arguments
|
926
|
+
.and_a_block
|
927
|
+
end
|
928
|
+
|
929
|
+
describe 'with a block' do
|
930
|
+
let(:block) { -> { { 'title' => 'A Wizard of Earthsea' } } }
|
931
|
+
let(:expected) do
|
932
|
+
Cuprum::Collections::Scope.new(&block)
|
933
|
+
end
|
934
|
+
|
935
|
+
it { expect(subject.or(&block)).to be == expected }
|
936
|
+
end
|
937
|
+
|
938
|
+
describe 'with a hash' do
|
939
|
+
let(:value) { { 'title' => 'A Wizard of Earthsea' } }
|
940
|
+
let(:expected) do
|
941
|
+
Cuprum::Collections::Scope.new(value)
|
942
|
+
end
|
943
|
+
|
944
|
+
it { expect(subject.or(value)).to be == expected }
|
945
|
+
end
|
946
|
+
|
947
|
+
describe 'with an all scope' do
|
948
|
+
let(:original) do
|
949
|
+
Cuprum::Collections::Scopes::AllScope.new
|
950
|
+
end
|
951
|
+
|
952
|
+
it { expect(subject.or(original)).to be == original }
|
953
|
+
end
|
954
|
+
|
955
|
+
describe 'with a none scope' do
|
956
|
+
let(:original) do
|
957
|
+
Cuprum::Collections::Scopes::NoneScope.new
|
958
|
+
end
|
959
|
+
|
960
|
+
it { expect(subject.or(original)).to be == original }
|
961
|
+
end
|
962
|
+
|
963
|
+
describe 'with an empty conjunction scope' do
|
964
|
+
let(:original) do
|
965
|
+
Cuprum::Collections::Scopes::ConjunctionScope.new(scopes: [])
|
966
|
+
end
|
967
|
+
|
968
|
+
it { expect(subject.or(original)).to be subject }
|
969
|
+
end
|
970
|
+
|
971
|
+
describe 'with an empty criteria scope' do
|
972
|
+
let(:original) do
|
973
|
+
Cuprum::Collections::Scopes::CriteriaScope.new(criteria: [])
|
974
|
+
end
|
975
|
+
|
976
|
+
it { expect(subject.or(original)).to be subject }
|
977
|
+
end
|
978
|
+
|
979
|
+
describe 'with an empty disjunction scope' do
|
980
|
+
let(:original) do
|
981
|
+
Cuprum::Collections::Scopes::DisjunctionScope.new(scopes: [])
|
982
|
+
end
|
983
|
+
|
984
|
+
it { expect(subject.or(original)).to be subject }
|
985
|
+
end
|
986
|
+
|
987
|
+
describe 'with a non-empty conjunction scope' do
|
988
|
+
let(:original) do
|
989
|
+
wrapped =
|
990
|
+
Cuprum::Collections::Scope
|
991
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
992
|
+
|
993
|
+
Cuprum::Collections::Scopes::ConjunctionScope
|
994
|
+
.new(scopes: [wrapped])
|
995
|
+
end
|
996
|
+
|
997
|
+
it { expect(subject.or(original)).to be == original }
|
998
|
+
end
|
999
|
+
|
1000
|
+
describe 'with a non-empty criteria scope' do
|
1001
|
+
let(:original) do
|
1002
|
+
Cuprum::Collections::Scope
|
1003
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
1004
|
+
end
|
1005
|
+
|
1006
|
+
it { expect(subject.or(original)).to be == original }
|
1007
|
+
end
|
1008
|
+
|
1009
|
+
describe 'with a non-empty disjunction scope' do
|
1010
|
+
let(:original) do
|
1011
|
+
wrapped =
|
1012
|
+
Cuprum::Collections::Scope
|
1013
|
+
.new({ 'title' => 'A Wizard of Earthsea' })
|
1014
|
+
|
1015
|
+
Cuprum::Collections::Scopes::DisjunctionScope
|
1016
|
+
.new(scopes: [wrapped])
|
1017
|
+
end
|
1018
|
+
|
1019
|
+
it { expect(subject.or(original)).to be == original }
|
1020
|
+
end
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
describe '#type' do
|
1024
|
+
it { expect(subject.type).to be :none }
|
1025
|
+
end
|
1026
|
+
end
|
1027
|
+
end
|
1028
|
+
end
|
1029
|
+
end
|