shoulda-matchers 3.0.0.rc1 → 3.0.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/Gemfile +2 -3
- data/Gemfile.lock +12 -41
- data/NEWS.md +118 -26
- data/README.md +34 -11
- data/doc_config/yard/templates/default/fulldoc/html/css/bootstrap.css +0 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/style.css +4 -0
- data/gemfiles/4.0.0.gemfile +2 -3
- data/gemfiles/4.0.0.gemfile.lock +47 -77
- data/gemfiles/4.0.1.gemfile +2 -3
- data/gemfiles/4.0.1.gemfile.lock +51 -79
- data/gemfiles/4.1.gemfile +2 -3
- data/gemfiles/4.1.gemfile.lock +73 -103
- data/gemfiles/4.2.gemfile +2 -3
- data/gemfiles/4.2.gemfile.lock +90 -124
- data/lib/shoulda/matchers.rb +1 -0
- data/lib/shoulda/matchers/action_controller/callback_matcher.rb +6 -8
- data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +1 -3
- data/lib/shoulda/matchers/action_controller/flash_store.rb +1 -8
- data/lib/shoulda/matchers/action_controller/permit_matcher.rb +140 -88
- data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +2 -5
- data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +5 -10
- data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +2 -4
- data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +1 -3
- data/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +3 -5
- data/lib/shoulda/matchers/action_controller/route_matcher.rb +5 -7
- data/lib/shoulda/matchers/action_controller/set_flash_matcher.rb +35 -9
- data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +3 -3
- data/lib/shoulda/matchers/active_model.rb +57 -1
- data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +2 -5
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +162 -54
- data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +5 -2
- data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +1 -3
- data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +24 -11
- data/lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb +4 -3
- data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +0 -2
- data/lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb +4 -3
- data/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +2 -1
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +15 -13
- data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +3 -3
- data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +3 -3
- data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +4 -4
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +8 -8
- data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +8 -8
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +12 -14
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +10 -4
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +0 -3
- data/lib/shoulda/matchers/active_model/validator.rb +0 -8
- data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +4 -6
- data/lib/shoulda/matchers/active_record/association_matcher.rb +58 -43
- data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +2 -2
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +3 -5
- data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +3 -5
- data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +1 -4
- data/lib/shoulda/matchers/active_record/serialize_matcher.rb +3 -5
- data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +7 -7
- data/lib/shoulda/matchers/doublespeak/double.rb +10 -1
- data/lib/shoulda/matchers/doublespeak/double_collection.rb +13 -5
- data/lib/shoulda/matchers/doublespeak/method_call.rb +10 -1
- data/lib/shoulda/matchers/doublespeak/object_double.rb +2 -1
- data/lib/shoulda/matchers/doublespeak/world.rb +10 -0
- data/lib/shoulda/matchers/error.rb +4 -0
- data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +11 -10
- data/lib/shoulda/matchers/integrations/libraries.rb +1 -0
- data/lib/shoulda/matchers/integrations/libraries/action_controller.rb +1 -1
- data/lib/shoulda/matchers/integrations/libraries/active_model.rb +1 -1
- data/lib/shoulda/matchers/integrations/libraries/active_record.rb +1 -1
- data/lib/shoulda/matchers/integrations/libraries/rails.rb +2 -1
- data/lib/shoulda/matchers/integrations/libraries/routing.rb +27 -0
- data/lib/shoulda/matchers/integrations/test_frameworks/active_support_test_case.rb +1 -1
- data/lib/shoulda/matchers/integrations/test_frameworks/minitest_4.rb +1 -1
- data/lib/shoulda/matchers/integrations/test_frameworks/minitest_5.rb +1 -1
- data/lib/shoulda/matchers/integrations/test_frameworks/missing_test_framework.rb +1 -1
- data/lib/shoulda/matchers/integrations/test_frameworks/rspec.rb +2 -2
- data/lib/shoulda/matchers/integrations/test_frameworks/test_unit.rb +1 -1
- data/lib/shoulda/matchers/routing.rb +10 -0
- data/lib/shoulda/matchers/version.rb +1 -1
- data/script/SUPPORTED_VERSIONS +1 -1
- data/spec/acceptance/independent_matchers_spec.rb +103 -42
- data/spec/doublespeak_spec_helper.rb +5 -1
- data/spec/support/acceptance/adds_shoulda_matchers_to_project.rb +34 -11
- data/spec/support/acceptance/helpers/rspec_helpers.rb +9 -13
- data/spec/support/acceptance/helpers/step_helpers.rb +13 -0
- data/spec/support/acceptance/matchers/have_output.rb +1 -1
- data/spec/support/acceptance/matchers/indicate_number_of_tests_was_run_matcher.rb +1 -1
- data/spec/support/tests/command_runner.rb +5 -1
- data/spec/support/unit/helpers/active_record_versions.rb +0 -4
- data/spec/support/unit/shared_examples/set_session_or_flash.rb +8 -3
- data/spec/unit/shoulda/matchers/action_controller/permit_matcher_spec.rb +198 -39
- data/spec/unit/shoulda/matchers/action_controller/route_matcher_spec.rb +269 -102
- data/spec/unit/shoulda/matchers/action_controller/set_flash_matcher_spec.rb +24 -0
- data/spec/unit/shoulda/matchers/active_model/allow_value_matcher_spec.rb +118 -101
- data/spec/unit/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +0 -82
- data/spec/unit/shoulda/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +148 -121
- data/spec/unit/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +20 -8
- data/spec/unit/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +64 -183
- data/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +14 -0
- data/spec/unit/shoulda/matchers/doublespeak/double_collection_spec.rb +60 -0
- data/spec/unit/shoulda/matchers/doublespeak/double_spec.rb +23 -7
- data/spec/unit/shoulda/matchers/routing/route_matcher_spec.rb +242 -0
- data/spec/unit_spec_helper.rb +4 -0
- data/tasks/documentation.rb +35 -0
- metadata +9 -8
- data/Guardfile +0 -5
- data/cucumber.yml +0 -1
- data/lib/shoulda/matchers/active_model/validator_with_captured_range_error.rb +0 -12
@@ -40,4 +40,28 @@ describe Shoulda::Matchers::ActionController::SetFlashMatcher, type: :controller
|
|
40
40
|
expect(controller).not_to set_flash.now['key for flash']
|
41
41
|
end
|
42
42
|
end
|
43
|
+
|
44
|
+
context 'when the now qualifier is called after the key is set' do
|
45
|
+
it 'raises a QualifierOrderError' do
|
46
|
+
controller = build_fake_response
|
47
|
+
|
48
|
+
usage = lambda do
|
49
|
+
expect(controller).to set_flash['any key'].now
|
50
|
+
end
|
51
|
+
|
52
|
+
expect(&usage).to raise_error(described_class::QualifierOrderError)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when the now qualifier is called after the to qualifier' do
|
57
|
+
it 'raises a QualifierOrderError' do
|
58
|
+
controller = build_fake_response
|
59
|
+
|
60
|
+
usage = lambda do
|
61
|
+
expect(controller).to set_flash.to('any value').now
|
62
|
+
end
|
63
|
+
|
64
|
+
expect(&usage).to raise_error(described_class::QualifierOrderError)
|
65
|
+
end
|
66
|
+
end
|
43
67
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'unit_spec_helper'
|
2
2
|
|
3
|
-
describe Shoulda::Matchers::ActiveModel do
|
3
|
+
describe Shoulda::Matchers::ActiveModel, type: :model do
|
4
4
|
describe '#allow_values' do
|
5
5
|
it 'is aliased to #allow_value' do
|
6
6
|
expect(method(:allow_values)).to eq(method(:allow_value))
|
@@ -62,7 +62,9 @@ describe Shoulda::Matchers::ActiveModel::AllowValueMatcher, type: :model do
|
|
62
62
|
|
63
63
|
it 'rejects several bad values' do
|
64
64
|
expect(validating_format(with: /abc/)).
|
65
|
-
not_to allow_value('xyz', 'zyx', nil, []).
|
65
|
+
not_to allow_value('xyz', 'zyx', nil, []).
|
66
|
+
for(:attr).
|
67
|
+
ignoring_interference_by_writer
|
66
68
|
end
|
67
69
|
end
|
68
70
|
|
@@ -182,12 +184,18 @@ describe Shoulda::Matchers::ActiveModel::AllowValueMatcher, type: :model do
|
|
182
184
|
|
183
185
|
it 'does not match given a bad value' do
|
184
186
|
bad_values.each do |bad_value|
|
185
|
-
expect(model).
|
187
|
+
expect(model).
|
188
|
+
not_to allow_value(bad_value).
|
189
|
+
for(:attr).
|
190
|
+
ignoring_interference_by_writer
|
186
191
|
end
|
187
192
|
end
|
188
193
|
|
189
194
|
it 'does not match given multiple bad values' do
|
190
|
-
expect(model).
|
195
|
+
expect(model).
|
196
|
+
not_to allow_value(*bad_values).
|
197
|
+
for(:attr).
|
198
|
+
ignoring_interference_by_writer
|
191
199
|
end
|
192
200
|
|
193
201
|
it "does not match given good values along with bad values" do
|
@@ -241,130 +249,139 @@ describe Shoulda::Matchers::ActiveModel::AllowValueMatcher, type: :model do
|
|
241
249
|
end
|
242
250
|
end
|
243
251
|
|
244
|
-
|
245
|
-
context 'when the
|
246
|
-
context '
|
247
|
-
it '
|
248
|
-
|
249
|
-
|
250
|
-
record = define_model(:example, attr: attribute_options).new
|
251
|
-
assertion = -> { expect(record).to allow_value(100000).for(:attr) }
|
252
|
-
column_type_class = column_type_class_for(type)
|
253
|
-
message = <<-MESSAGE.strip_heredoc.strip
|
254
|
-
Did not expect errors when attr is set to 100000,
|
255
|
-
got RangeError: "100000 is out of range for #{column_type_class} with limit 2"
|
256
|
-
MESSAGE
|
257
|
-
expect(&assertion).to fail_with_message(message)
|
258
|
-
end
|
252
|
+
context 'when the attribute interferes with attempts to be set' do
|
253
|
+
context 'when the matcher has not been qualified with #ignoring_interference_by_writer' do
|
254
|
+
context 'when the attribute cannot be changed from nil to non-nil' do
|
255
|
+
it 'raises a CouldNotSetAttributeError' do
|
256
|
+
model = define_active_model_class 'Example' do
|
257
|
+
attr_reader :name
|
259
258
|
|
260
|
-
|
261
|
-
|
262
|
-
type = :integer
|
263
|
-
attribute_options = { type: type, options: { limit: 2 } }
|
264
|
-
record = define_model(:example, attr: attribute_options).new
|
265
|
-
assertion = -> do
|
266
|
-
expect(record).
|
267
|
-
to allow_value(100000).
|
268
|
-
for(:attr).
|
269
|
-
with_message('some message')
|
259
|
+
def name=(_value)
|
260
|
+
nil
|
270
261
|
end
|
271
|
-
column_type_class = column_type_class_for(type)
|
272
|
-
message = <<-MESSAGE.strip_heredoc.strip
|
273
|
-
Did not expect errors to include "some message" when attr is set to 100000,
|
274
|
-
got RangeError: "100000 is out of range for #{column_type_class} with limit 2"
|
275
|
-
MESSAGE
|
276
|
-
expect(&assertion).to fail_with_message(message)
|
277
262
|
end
|
263
|
+
|
264
|
+
assertion = -> {
|
265
|
+
expect(model.new).to allow_value('anything').for(:name)
|
266
|
+
}
|
267
|
+
|
268
|
+
expect(&assertion).to raise_error(
|
269
|
+
described_class::CouldNotSetAttributeError
|
270
|
+
)
|
278
271
|
end
|
279
272
|
end
|
280
273
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
expect(record).
|
289
|
-
to allow_value(100000).
|
290
|
-
for(:attr).
|
291
|
-
strict
|
274
|
+
context 'when the attribute cannot be changed from non-nil to nil' do
|
275
|
+
it 'raises a CouldNotSetAttribute error' do
|
276
|
+
model = define_active_model_class 'Example' do
|
277
|
+
attr_reader :name
|
278
|
+
|
279
|
+
def name=(value)
|
280
|
+
@name = value unless value.nil?
|
292
281
|
end
|
293
|
-
column_type_class = column_type_class_for(type)
|
294
|
-
message = <<-MESSAGE.strip_heredoc.strip
|
295
|
-
Did not expect an exception to have been raised when attr is set to 100000,
|
296
|
-
got RangeError: "100000 is out of range for #{column_type_class} with limit 2"
|
297
|
-
MESSAGE
|
298
|
-
expect(&assertion).to fail_with_message(message)
|
299
282
|
end
|
300
283
|
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
284
|
+
record = model.new(name: 'some name')
|
285
|
+
|
286
|
+
assertion = -> {
|
287
|
+
expect(record).to allow_value(nil).for(:name)
|
288
|
+
}
|
289
|
+
|
290
|
+
expect(&assertion).to raise_error(
|
291
|
+
described_class::CouldNotSetAttributeError
|
292
|
+
)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
context 'when the attribute cannot be changed from a non-nil value to another non-nil value' do
|
297
|
+
it 'raises a CouldNotSetAttribute error' do
|
298
|
+
model = define_active_model_class 'Example' do
|
299
|
+
attr_reader :name
|
300
|
+
|
301
|
+
def name=(_value)
|
302
|
+
@name = 'constant name'
|
319
303
|
end
|
320
304
|
end
|
305
|
+
|
306
|
+
record = model.new(name: 'some name')
|
307
|
+
|
308
|
+
assertion = -> {
|
309
|
+
expect(record).to allow_value('another name').for(:name)
|
310
|
+
}
|
311
|
+
|
312
|
+
expect(&assertion).to raise_error(
|
313
|
+
described_class::CouldNotSetAttributeError
|
314
|
+
)
|
321
315
|
end
|
322
316
|
end
|
323
317
|
end
|
324
|
-
end
|
325
318
|
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
319
|
+
context 'when the matcher has been qualified with #ignoring_interference_by_writer' do
|
320
|
+
context 'when the attribute cannot be changed from nil to non-nil' do
|
321
|
+
it 'does not raise an error at all' do
|
322
|
+
model = define_active_model_class 'Example' do
|
323
|
+
attr_reader :name
|
331
324
|
|
332
|
-
|
333
|
-
|
325
|
+
def name=(_value)
|
326
|
+
nil
|
327
|
+
end
|
334
328
|
end
|
335
|
-
end
|
336
329
|
|
337
|
-
|
338
|
-
|
339
|
-
|
330
|
+
assertion = lambda do
|
331
|
+
expect(model.new).
|
332
|
+
to allow_value('anything').
|
333
|
+
for(:name).
|
334
|
+
ignoring_interference_by_writer
|
335
|
+
end
|
340
336
|
|
341
|
-
|
342
|
-
|
343
|
-
)
|
337
|
+
expect(&assertion).not_to raise_error
|
338
|
+
end
|
344
339
|
end
|
345
|
-
end
|
346
|
-
end
|
347
340
|
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
341
|
+
context 'when the attribute cannot be changed from non-nil to nil' do
|
342
|
+
it 'does not raise an error at all' do
|
343
|
+
model = define_active_model_class 'Example' do
|
344
|
+
attr_reader :name
|
345
|
+
|
346
|
+
def name=(value)
|
347
|
+
@name = value unless value.nil?
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
record = model.new(name: 'some name')
|
353
352
|
|
354
|
-
|
355
|
-
|
353
|
+
assertion = lambda do
|
354
|
+
expect(record).
|
355
|
+
to allow_value(nil).
|
356
|
+
for(:name).
|
357
|
+
ignoring_interference_by_writer
|
356
358
|
end
|
359
|
+
|
360
|
+
expect(&assertion).not_to raise_error
|
357
361
|
end
|
362
|
+
end
|
358
363
|
|
359
|
-
|
364
|
+
context 'when the attribute cannot be changed from a non-nil value to another non-nil value' do
|
365
|
+
it 'does not raise an error at all' do
|
366
|
+
model = define_active_model_class 'Example' do
|
367
|
+
attr_reader :name
|
360
368
|
|
361
|
-
|
362
|
-
|
363
|
-
|
369
|
+
def name=(_value)
|
370
|
+
@name = 'constant name'
|
371
|
+
end
|
372
|
+
end
|
364
373
|
|
365
|
-
|
366
|
-
|
367
|
-
|
374
|
+
record = model.new(name: 'some name')
|
375
|
+
|
376
|
+
assertion = lambda do
|
377
|
+
expect(record).
|
378
|
+
to allow_value('another name').
|
379
|
+
for(:name).
|
380
|
+
ignoring_interference_by_writer
|
381
|
+
end
|
382
|
+
|
383
|
+
expect(&assertion).not_to raise_error
|
384
|
+
end
|
368
385
|
end
|
369
386
|
end
|
370
387
|
end
|
@@ -79,88 +79,6 @@ describe Shoulda::Matchers::ActiveModel::DisallowValueMatcher, type: :model do
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
if active_record_can_raise_range_error?
|
83
|
-
context 'when the value is outside of the range of the column' do
|
84
|
-
context 'not qualified with strict' do
|
85
|
-
it 'accepts, failing with the correct message' do
|
86
|
-
type = :integer
|
87
|
-
attribute_options = { type: type, options: { limit: 2 } }
|
88
|
-
record = define_model(:example, attr: attribute_options).new
|
89
|
-
assertion = -> { expect(record).not_to disallow_value(100000).for(:attr) }
|
90
|
-
column_type_class = column_type_class_for(type)
|
91
|
-
message = <<-MESSAGE.strip_heredoc.strip
|
92
|
-
Did not expect errors when attr is set to 100000,
|
93
|
-
got RangeError: "100000 is out of range for #{column_type_class} with limit 2"
|
94
|
-
MESSAGE
|
95
|
-
expect(&assertion).to fail_with_message(message)
|
96
|
-
end
|
97
|
-
|
98
|
-
context 'qualified with a message' do
|
99
|
-
it 'ignores any specified message, failing with the correct message' do
|
100
|
-
type = :integer
|
101
|
-
attribute_options = { type: type, options: { limit: 2 } }
|
102
|
-
record = define_model(:example, attr: attribute_options).new
|
103
|
-
assertion = -> do
|
104
|
-
expect(record).
|
105
|
-
not_to disallow_value(100000).
|
106
|
-
for(:attr).
|
107
|
-
with_message('some message')
|
108
|
-
end
|
109
|
-
column_type_class = column_type_class_for(type)
|
110
|
-
message = <<-MESSAGE.strip_heredoc.strip
|
111
|
-
Did not expect errors to include "some message" when attr is set to 100000,
|
112
|
-
got RangeError: "100000 is out of range for #{column_type_class} with limit 2"
|
113
|
-
MESSAGE
|
114
|
-
expect(&assertion).to fail_with_message(message)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
if active_model_supports_strict?
|
120
|
-
context 'qualified with strict' do
|
121
|
-
it 'accepts, failing with the correct message' do
|
122
|
-
type = :integer
|
123
|
-
attribute_options = { type: type, options: { limit: 2 } }
|
124
|
-
record = define_model(:example, attr: attribute_options).new
|
125
|
-
assertion = -> do
|
126
|
-
expect(record).
|
127
|
-
not_to disallow_value(100000).
|
128
|
-
for(:attr).
|
129
|
-
strict
|
130
|
-
end
|
131
|
-
column_type_class = column_type_class_for(type)
|
132
|
-
message = <<-MESSAGE.strip_heredoc.strip
|
133
|
-
Did not expect an exception to have been raised when attr is set to 100000,
|
134
|
-
got RangeError: "100000 is out of range for #{column_type_class} with limit 2"
|
135
|
-
MESSAGE
|
136
|
-
expect(&assertion).to fail_with_message(message)
|
137
|
-
end
|
138
|
-
|
139
|
-
context 'qualified with a message' do
|
140
|
-
it 'ignores any specified message' do
|
141
|
-
type = :integer
|
142
|
-
attribute_options = { type: type, options: { limit: 2 } }
|
143
|
-
record = define_model(:example, attr: attribute_options).new
|
144
|
-
assertion = -> do
|
145
|
-
expect(record).
|
146
|
-
not_to disallow_value(100000).
|
147
|
-
for(:attr).
|
148
|
-
with_message('some message').
|
149
|
-
strict
|
150
|
-
end
|
151
|
-
column_type_class = column_type_class_for(type)
|
152
|
-
message = <<-MESSAGE.strip_heredoc.strip
|
153
|
-
Did not expect exception to include "some message" when attr is set to 100000,
|
154
|
-
got RangeError: "100000 is out of range for #{column_type_class} with limit 2"
|
155
|
-
MESSAGE
|
156
|
-
expect(&assertion).to fail_with_message(message)
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
82
|
def matcher(value)
|
165
83
|
described_class.new(value)
|
166
84
|
end
|
data/spec/unit/shoulda/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb
CHANGED
@@ -1,22 +1,19 @@
|
|
1
1
|
require 'unit_spec_helper'
|
2
2
|
|
3
3
|
describe Shoulda::Matchers::ActiveModel::NumericalityMatchers::ComparisonMatcher do
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
it_behaves_like 'a numerical submatcher' do
|
5
|
+
subject { build_matcher }
|
6
|
+
end
|
7
7
|
|
8
8
|
shared_examples_for 'strict qualifier' do
|
9
|
-
def validation_qualifier
|
10
|
-
matcher_qualifier.to_s.gsub(/^is_/, '').to_sym
|
11
|
-
end
|
12
|
-
|
13
9
|
context 'asserting strict validation when validating strictly' do
|
14
10
|
it 'accepts' do
|
15
11
|
record = instance_with_validations(
|
16
12
|
validation_qualifier => 1,
|
17
13
|
strict: true
|
18
14
|
)
|
19
|
-
|
15
|
+
matcher = build_matcher(operator: operator, value: 1).strict
|
16
|
+
expect(record).to matcher
|
20
17
|
end
|
21
18
|
end
|
22
19
|
|
@@ -27,209 +24,231 @@ describe Shoulda::Matchers::ActiveModel::NumericalityMatchers::ComparisonMatcher
|
|
27
24
|
validation_qualifier => 1,
|
28
25
|
strict: true
|
29
26
|
)
|
30
|
-
|
27
|
+
matcher = build_matcher(operator: operator, value: 1)
|
28
|
+
expect(record).not_to matcher
|
31
29
|
end
|
32
30
|
end
|
33
31
|
|
34
32
|
context 'asserting strict validation when not validating strictly' do
|
35
33
|
it 'rejects' do
|
36
34
|
record = instance_with_validations(validation_qualifier => 1)
|
37
|
-
|
35
|
+
matcher = build_matcher(operator: operator, value: 1).strict
|
36
|
+
expect(record).not_to matcher
|
38
37
|
end
|
39
38
|
end
|
40
39
|
end
|
41
40
|
|
42
41
|
context 'when initialized without correct numerical matcher' do
|
43
|
-
it 'raises an
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
48
|
-
expect do
|
49
|
-
described_class.new(fake_matcher, 0, :>)
|
50
|
-
end.to raise_error ArgumentError
|
42
|
+
it 'raises an ArgumentError' do
|
43
|
+
numericality_matcher = double
|
44
|
+
expect { described_class.new(numericality_matcher, 0, :>) }.
|
45
|
+
to raise_error(ArgumentError)
|
51
46
|
end
|
52
47
|
end
|
53
48
|
|
54
|
-
|
55
|
-
include_examples 'strict qualifier'
|
56
|
-
def matcher_qualifier
|
57
|
-
:is_greater_than
|
58
|
-
end
|
59
|
-
end
|
49
|
+
describe 'is_greater_than' do
|
50
|
+
include_examples 'strict qualifier'
|
60
51
|
|
61
52
|
it do
|
62
|
-
|
63
|
-
|
53
|
+
record = instance_with_validations(greater_than: 1.5)
|
54
|
+
matcher = build_matcher(operator: :>, value: 2)
|
55
|
+
expect(record).not_to matcher
|
64
56
|
end
|
65
57
|
|
66
58
|
it do
|
67
|
-
|
68
|
-
|
59
|
+
record = instance_with_validations(greater_than: 2)
|
60
|
+
matcher = build_matcher(operator: :>, value: 2)
|
61
|
+
expect(record).to matcher
|
69
62
|
end
|
70
63
|
|
71
64
|
it do
|
72
|
-
|
73
|
-
|
65
|
+
record = instance_with_validations(greater_than: 2.5)
|
66
|
+
matcher = build_matcher(operator: :>, value: 2)
|
67
|
+
expect(record).not_to matcher
|
74
68
|
end
|
75
69
|
|
76
70
|
it do
|
77
|
-
|
71
|
+
record = instance_without_validations
|
72
|
+
matcher = build_matcher(operator: :>, value: 2)
|
73
|
+
expect(record).not_to matcher
|
78
74
|
end
|
79
|
-
end
|
80
75
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
76
|
+
def operator
|
77
|
+
:>
|
78
|
+
end
|
79
|
+
|
80
|
+
def validation_qualifier
|
81
|
+
:greater_than
|
86
82
|
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'is_greater_than_or_equal_to' do
|
86
|
+
include_examples 'strict qualifier'
|
87
87
|
|
88
88
|
it do
|
89
|
-
|
90
|
-
|
89
|
+
record = instance_with_validations(greater_than_or_equal_to: 1.5)
|
90
|
+
matcher = build_matcher(operator: :>=, value: 2)
|
91
|
+
expect(record).not_to matcher
|
91
92
|
end
|
92
93
|
|
93
94
|
it do
|
94
|
-
|
95
|
-
|
95
|
+
record = instance_with_validations(greater_than_or_equal_to: 2)
|
96
|
+
matcher = build_matcher(operator: :>=, value: 2)
|
97
|
+
expect(record).to matcher
|
96
98
|
end
|
97
99
|
|
98
100
|
it do
|
99
|
-
|
100
|
-
|
101
|
+
record = instance_with_validations(greater_than_or_equal_to: 2.5)
|
102
|
+
matcher = build_matcher(operator: :>=, value: 2)
|
103
|
+
expect(record).not_to matcher
|
101
104
|
end
|
102
105
|
|
103
106
|
it do
|
104
|
-
|
105
|
-
|
107
|
+
record = instance_without_validations
|
108
|
+
matcher = build_matcher(operator: :>=, value: 2)
|
109
|
+
expect(record).not_to matcher
|
106
110
|
end
|
107
|
-
end
|
108
111
|
|
109
|
-
|
110
|
-
|
111
|
-
def matcher_qualifier
|
112
|
-
:is_less_than
|
113
|
-
end
|
112
|
+
def operator
|
113
|
+
:>=
|
114
114
|
end
|
115
115
|
|
116
|
+
def validation_qualifier
|
117
|
+
:greater_than_or_equal_to
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe 'is_less_than' do
|
122
|
+
include_examples 'strict qualifier'
|
123
|
+
|
116
124
|
it do
|
117
|
-
|
118
|
-
|
125
|
+
record = instance_with_validations(less_than: 1.5)
|
126
|
+
matcher = build_matcher(operator: :<, value: 2)
|
127
|
+
expect(record).not_to matcher
|
119
128
|
end
|
120
129
|
|
121
130
|
it do
|
122
|
-
|
123
|
-
|
131
|
+
record = instance_with_validations(less_than: 2)
|
132
|
+
matcher = build_matcher(operator: :<, value: 2)
|
133
|
+
expect(record).to matcher
|
124
134
|
end
|
125
135
|
|
126
136
|
it do
|
127
|
-
|
128
|
-
|
137
|
+
record = instance_with_validations(less_than: 2.5)
|
138
|
+
matcher = build_matcher(operator: :<, value: 2)
|
139
|
+
expect(record).not_to matcher
|
129
140
|
end
|
130
141
|
|
131
142
|
it do
|
132
|
-
|
133
|
-
|
143
|
+
record = instance_without_validations
|
144
|
+
matcher = build_matcher(operator: :<, value: 2)
|
145
|
+
expect(record).not_to matcher
|
134
146
|
end
|
135
|
-
end
|
136
147
|
|
137
|
-
|
138
|
-
|
139
|
-
def matcher_qualifier
|
140
|
-
:is_less_than_or_equal_to
|
141
|
-
end
|
148
|
+
def operator
|
149
|
+
:<
|
142
150
|
end
|
143
151
|
|
152
|
+
def validation_qualifier
|
153
|
+
:less_than
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe 'is_less_than_or_equal_to' do
|
158
|
+
include_examples 'strict qualifier'
|
159
|
+
|
144
160
|
it do
|
145
|
-
|
146
|
-
|
161
|
+
record = instance_with_validations(less_than_or_equal_to: 1.5)
|
162
|
+
matcher = build_matcher(operator: :<=, value: 2)
|
163
|
+
expect(record).not_to matcher
|
147
164
|
end
|
148
165
|
|
149
166
|
it do
|
150
|
-
|
151
|
-
|
167
|
+
record = instance_with_validations(less_than_or_equal_to: 2)
|
168
|
+
matcher = build_matcher(operator: :<=, value: 2)
|
169
|
+
expect(record).to matcher
|
152
170
|
end
|
153
171
|
|
154
172
|
it do
|
155
|
-
|
156
|
-
|
173
|
+
record = instance_with_validations(less_than_or_equal_to: 2.5)
|
174
|
+
matcher = build_matcher(operator: :<=, value: 2)
|
175
|
+
expect(record).not_to matcher
|
157
176
|
end
|
158
177
|
|
159
178
|
it do
|
160
|
-
|
161
|
-
|
179
|
+
record = instance_without_validations
|
180
|
+
matcher = build_matcher(operator: :<=, value: 2)
|
181
|
+
expect(record).not_to matcher
|
162
182
|
end
|
163
|
-
end
|
164
183
|
|
165
|
-
|
166
|
-
|
167
|
-
def matcher_qualifier
|
168
|
-
:is_equal_to
|
169
|
-
end
|
184
|
+
def operator
|
185
|
+
:<=
|
170
186
|
end
|
171
187
|
|
172
|
-
|
173
|
-
|
174
|
-
.to matcher.is_equal_to(0)
|
188
|
+
def validation_qualifier
|
189
|
+
:less_than_or_equal_to
|
175
190
|
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe 'is_equal_to' do
|
194
|
+
include_examples 'strict qualifier'
|
176
195
|
|
177
196
|
it do
|
178
|
-
|
179
|
-
|
197
|
+
record = instance_with_validations(equal_to: 1.5)
|
198
|
+
matcher = build_matcher(operator: :==, value: 2)
|
199
|
+
expect(record).not_to matcher
|
180
200
|
end
|
181
201
|
|
182
202
|
it do
|
183
|
-
|
184
|
-
|
203
|
+
record = instance_with_validations(equal_to: 2)
|
204
|
+
matcher = build_matcher(operator: :==, value: 2)
|
205
|
+
expect(record).to matcher
|
185
206
|
end
|
186
207
|
|
187
208
|
it do
|
188
|
-
|
189
|
-
|
209
|
+
record = instance_with_validations(equal_to: 2.5)
|
210
|
+
matcher = build_matcher(operator: :==, value: 2)
|
211
|
+
expect(record).not_to matcher
|
190
212
|
end
|
191
|
-
end
|
192
213
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
expect(
|
214
|
+
it do
|
215
|
+
record = instance_without_validations
|
216
|
+
matcher = build_matcher(operator: :==, value: 2)
|
217
|
+
expect(record).not_to matcher
|
197
218
|
end
|
198
|
-
end
|
199
219
|
|
200
|
-
|
201
|
-
|
202
|
-
expect(instance_with_validations(on: :customizable)).
|
203
|
-
to matcher.on(:customizable)
|
220
|
+
def operator
|
221
|
+
:==
|
204
222
|
end
|
205
|
-
end
|
206
223
|
|
207
|
-
|
208
|
-
|
209
|
-
expect(instance_with_validations).to matcher.on(:customizable)
|
224
|
+
def validation_qualifier
|
225
|
+
:equal_to
|
210
226
|
end
|
211
227
|
end
|
212
228
|
|
213
|
-
|
214
|
-
it '
|
215
|
-
|
216
|
-
|
229
|
+
describe 'with_message' do
|
230
|
+
it 'verifies the message for the validation' do
|
231
|
+
instance = instance_with_validations(equal_to: 0, message: 'Must be zero')
|
232
|
+
matcher = build_matcher.with_message('Must be zero')
|
233
|
+
expect(instance).to matcher
|
217
234
|
end
|
218
235
|
end
|
219
236
|
|
220
237
|
describe '#comparison_description' do
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
238
|
+
tests = [
|
239
|
+
{ operator: :>, value: 0, expectation: 'greater than 0' },
|
240
|
+
{ operator: :>=, value: -1.0, expectation: 'greater than or equal to -1.0' },
|
241
|
+
{ operator: :==, value: 2.2, expectation: 'equal to 2.2' },
|
242
|
+
{ operator: :<, value: -3, expectation: 'less than -3' },
|
243
|
+
{ operator: :<=, value: 4, expectation: 'less than or equal to 4' },
|
244
|
+
]
|
245
|
+
|
246
|
+
tests.each do |test|
|
247
|
+
context "with :#{test[:operator]} as operator and #{test[:value]} as value" do
|
248
|
+
it do
|
249
|
+
matcher = build_matcher(operator: test[:operator], value: test[:value])
|
250
|
+
expect(matcher.comparison_description).to eq test[:expectation]
|
231
251
|
end
|
232
|
-
it { should eq h[:expectation] }
|
233
252
|
end
|
234
253
|
end
|
235
254
|
end
|
@@ -245,17 +264,25 @@ describe Shoulda::Matchers::ActiveModel::NumericalityMatchers::ComparisonMatcher
|
|
245
264
|
model_with_validations(options).new(attribute_name => '1')
|
246
265
|
end
|
247
266
|
|
248
|
-
def
|
267
|
+
def model_without_validations
|
249
268
|
define_model :example, attribute_name => :string do |model|
|
250
269
|
model.attr_accessible(attribute_name)
|
251
|
-
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
def instance_without_validations
|
274
|
+
model_without_validations.new
|
252
275
|
end
|
253
276
|
|
254
277
|
def attribute_name
|
255
278
|
:attr
|
256
279
|
end
|
257
280
|
|
258
|
-
def
|
259
|
-
|
281
|
+
def build_matcher(operator: :==, value: 0)
|
282
|
+
described_class.new(numericality_matcher, value, operator).for(attribute_name)
|
283
|
+
end
|
284
|
+
|
285
|
+
def numericality_matcher
|
286
|
+
double(diff_to_compare: 1)
|
260
287
|
end
|
261
288
|
end
|