shoulda-matchers 5.3.0 → 6.1.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/LICENSE +1 -1
- data/README.md +26 -9
- data/lib/shoulda/matchers/action_controller/permit_matcher.rb +7 -9
- data/lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb +13 -15
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +10 -1
- data/lib/shoulda/matchers/active_model/comparison_matcher.rb +157 -0
- data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +7 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/range_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/numericality_matchers/submatchers.rb +16 -6
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +0 -6
- data/lib/shoulda/matchers/active_model/validate_comparison_of_matcher.rb +532 -0
- data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +3 -3
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +4 -3
- data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +64 -9
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +40 -96
- data/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +6 -7
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +6 -0
- data/lib/shoulda/matchers/active_model/validator.rb +4 -0
- data/lib/shoulda/matchers/active_model.rb +2 -1
- data/lib/shoulda/matchers/active_record/association_matcher.rb +31 -11
- data/lib/shoulda/matchers/active_record/association_matchers/optional_matcher.rb +23 -19
- data/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +27 -23
- data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +0 -8
- data/lib/shoulda/matchers/active_record/encrypt_matcher.rb +174 -0
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +46 -6
- data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +24 -13
- data/lib/shoulda/matchers/active_record/have_implicit_order_column.rb +3 -5
- data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/normalize_matcher.rb +151 -0
- data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +82 -70
- data/lib/shoulda/matchers/active_record.rb +2 -0
- data/lib/shoulda/matchers/doublespeak/double_collection.rb +2 -6
- data/lib/shoulda/matchers/doublespeak/world.rb +2 -6
- data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +13 -15
- data/lib/shoulda/matchers/rails_shim.rb +8 -6
- data/lib/shoulda/matchers/util/word_wrap.rb +1 -1
- data/lib/shoulda/matchers/util.rb +17 -19
- data/lib/shoulda/matchers/version.rb +1 -1
- data/lib/shoulda/matchers.rb +2 -2
- data/shoulda-matchers.gemspec +1 -1
- metadata +11 -8
- data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +0 -136
@@ -357,51 +357,33 @@ module Shoulda
|
|
357
357
|
end
|
358
358
|
|
359
359
|
# @private
|
360
|
-
class ValidateNumericalityOfMatcher
|
360
|
+
class ValidateNumericalityOfMatcher < ValidationMatcher
|
361
361
|
NUMERIC_NAME = 'number'.freeze
|
362
362
|
DEFAULT_DIFF_TO_COMPARE = 1
|
363
363
|
|
364
|
-
include Qualifiers::IgnoringInterferenceByWriter
|
365
|
-
|
366
364
|
attr_reader :diff_to_compare
|
367
365
|
|
368
366
|
def initialize(attribute)
|
369
367
|
super
|
370
|
-
@attribute = attribute
|
371
368
|
@submatchers = []
|
372
369
|
@diff_to_compare = DEFAULT_DIFF_TO_COMPARE
|
373
|
-
@expects_custom_validation_message = false
|
374
370
|
@expects_to_allow_nil = false
|
375
|
-
@expects_strict = false
|
376
371
|
@allowed_type_adjective = nil
|
377
372
|
@allowed_type_name = 'number'
|
378
|
-
@context = nil
|
379
|
-
@expected_message = nil
|
380
|
-
end
|
381
|
-
|
382
|
-
def strict
|
383
|
-
@expects_strict = true
|
384
|
-
self
|
385
|
-
end
|
386
373
|
|
387
|
-
|
388
|
-
@expects_strict
|
374
|
+
add_disallow_non_numeric_value_matcher
|
389
375
|
end
|
390
376
|
|
391
377
|
def only_integer
|
392
378
|
prepare_submatcher(
|
393
|
-
NumericalityMatchers::OnlyIntegerMatcher.new(self,
|
379
|
+
NumericalityMatchers::OnlyIntegerMatcher.new(self, attribute),
|
394
380
|
)
|
395
381
|
self
|
396
382
|
end
|
397
383
|
|
398
384
|
def allow_nil
|
399
385
|
@expects_to_allow_nil = true
|
400
|
-
prepare_submatcher(
|
401
|
-
AllowValueMatcher.new(nil).
|
402
|
-
for(@attribute).
|
403
|
-
with_message(:not_a_number),
|
404
|
-
)
|
386
|
+
prepare_submatcher(allow_value_matcher(nil, :not_a_number))
|
405
387
|
self
|
406
388
|
end
|
407
389
|
|
@@ -411,70 +393,55 @@ module Shoulda
|
|
411
393
|
|
412
394
|
def odd
|
413
395
|
prepare_submatcher(
|
414
|
-
NumericalityMatchers::OddNumberMatcher.new(self,
|
396
|
+
NumericalityMatchers::OddNumberMatcher.new(self, attribute),
|
415
397
|
)
|
416
398
|
self
|
417
399
|
end
|
418
400
|
|
419
401
|
def even
|
420
402
|
prepare_submatcher(
|
421
|
-
NumericalityMatchers::EvenNumberMatcher.new(self,
|
403
|
+
NumericalityMatchers::EvenNumberMatcher.new(self, attribute),
|
422
404
|
)
|
423
405
|
self
|
424
406
|
end
|
425
407
|
|
426
408
|
def is_greater_than(value)
|
427
|
-
prepare_submatcher(comparison_matcher_for(value, :>).for(
|
409
|
+
prepare_submatcher(comparison_matcher_for(value, :>).for(attribute))
|
428
410
|
self
|
429
411
|
end
|
430
412
|
|
431
413
|
def is_greater_than_or_equal_to(value)
|
432
|
-
prepare_submatcher(comparison_matcher_for(value, :>=).for(
|
414
|
+
prepare_submatcher(comparison_matcher_for(value, :>=).for(attribute))
|
433
415
|
self
|
434
416
|
end
|
435
417
|
|
436
418
|
def is_equal_to(value)
|
437
|
-
prepare_submatcher(comparison_matcher_for(value, :==).for(
|
419
|
+
prepare_submatcher(comparison_matcher_for(value, :==).for(attribute))
|
438
420
|
self
|
439
421
|
end
|
440
422
|
|
441
423
|
def is_less_than(value)
|
442
|
-
prepare_submatcher(comparison_matcher_for(value, :<).for(
|
424
|
+
prepare_submatcher(comparison_matcher_for(value, :<).for(attribute))
|
443
425
|
self
|
444
426
|
end
|
445
427
|
|
446
428
|
def is_less_than_or_equal_to(value)
|
447
|
-
prepare_submatcher(comparison_matcher_for(value, :<=).for(
|
429
|
+
prepare_submatcher(comparison_matcher_for(value, :<=).for(attribute))
|
448
430
|
self
|
449
431
|
end
|
450
432
|
|
451
433
|
def is_other_than(value)
|
452
|
-
prepare_submatcher(comparison_matcher_for(value, :!=).for(
|
434
|
+
prepare_submatcher(comparison_matcher_for(value, :!=).for(attribute))
|
453
435
|
self
|
454
436
|
end
|
455
437
|
|
456
438
|
def is_in(range)
|
457
439
|
prepare_submatcher(
|
458
|
-
NumericalityMatchers::RangeMatcher.new(self,
|
440
|
+
NumericalityMatchers::RangeMatcher.new(self, attribute, range),
|
459
441
|
)
|
460
442
|
self
|
461
443
|
end
|
462
444
|
|
463
|
-
def with_message(message)
|
464
|
-
@expects_custom_validation_message = true
|
465
|
-
@expected_message = message
|
466
|
-
self
|
467
|
-
end
|
468
|
-
|
469
|
-
def expects_custom_validation_message?
|
470
|
-
@expects_custom_validation_message
|
471
|
-
end
|
472
|
-
|
473
|
-
def on(context)
|
474
|
-
@context = context
|
475
|
-
self
|
476
|
-
end
|
477
|
-
|
478
445
|
def matches?(subject)
|
479
446
|
matches_or_does_not_match?(subject)
|
480
447
|
first_submatcher_that_fails_to_match.nil?
|
@@ -486,24 +453,18 @@ module Shoulda
|
|
486
453
|
end
|
487
454
|
|
488
455
|
def simple_description
|
489
|
-
|
456
|
+
String.new.tap do |description|
|
457
|
+
description << "validate that :#{attribute} looks like "
|
458
|
+
description << Shoulda::Matchers::Util.a_or_an(full_allowed_type)
|
490
459
|
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
if range_description.present?
|
495
|
-
description << " #{range_description}"
|
496
|
-
end
|
460
|
+
if range_description.present?
|
461
|
+
description << " #{range_description}"
|
462
|
+
end
|
497
463
|
|
498
|
-
|
499
|
-
|
464
|
+
if comparison_descriptions.present?
|
465
|
+
description << " #{comparison_descriptions}"
|
466
|
+
end
|
500
467
|
end
|
501
|
-
|
502
|
-
description
|
503
|
-
end
|
504
|
-
|
505
|
-
def description
|
506
|
-
ValidationMatcher::BuildDescription.call(self, simple_description)
|
507
468
|
end
|
508
469
|
|
509
470
|
def failure_message
|
@@ -532,44 +493,29 @@ module Shoulda
|
|
532
493
|
@subject = subject
|
533
494
|
@number_of_submatchers = @submatchers.size
|
534
495
|
|
535
|
-
add_disallow_value_matcher
|
536
496
|
qualify_submatchers
|
537
497
|
end
|
538
498
|
|
539
|
-
def overall_failure_message
|
540
|
-
Shoulda::Matchers.word_wrap(
|
541
|
-
"Expected #{model.name} to #{description}, but this could not "\
|
542
|
-
'be proved.',
|
543
|
-
)
|
544
|
-
end
|
545
|
-
|
546
|
-
def overall_failure_message_when_negated
|
547
|
-
Shoulda::Matchers.word_wrap(
|
548
|
-
"Expected #{model.name} not to #{description}, but this could not "\
|
549
|
-
'be proved.',
|
550
|
-
)
|
551
|
-
end
|
552
|
-
|
553
499
|
def attribute_is_active_record_column?
|
554
|
-
columns_hash.key?(
|
500
|
+
columns_hash.key?(attribute.to_s)
|
555
501
|
end
|
556
502
|
|
557
503
|
def column_type
|
558
|
-
columns_hash[
|
504
|
+
columns_hash[attribute.to_s].type
|
559
505
|
end
|
560
506
|
|
561
507
|
def columns_hash
|
562
|
-
if
|
563
|
-
|
508
|
+
if subject.class.respond_to?(:columns_hash)
|
509
|
+
subject.class.columns_hash
|
564
510
|
else
|
565
511
|
{}
|
566
512
|
end
|
567
513
|
end
|
568
514
|
|
569
|
-
def
|
515
|
+
def add_disallow_non_numeric_value_matcher
|
570
516
|
disallow_value_matcher = DisallowValueMatcher.
|
571
517
|
new(non_numeric_value).
|
572
|
-
for(
|
518
|
+
for(attribute).
|
573
519
|
with_message(:not_a_number)
|
574
520
|
|
575
521
|
add_submatcher(disallow_value_matcher)
|
@@ -581,9 +527,9 @@ module Shoulda
|
|
581
527
|
end
|
582
528
|
|
583
529
|
def comparison_matcher_for(value, operator)
|
584
|
-
|
530
|
+
ComparisonMatcher.
|
585
531
|
new(self, value, operator).
|
586
|
-
for(
|
532
|
+
for(attribute)
|
587
533
|
end
|
588
534
|
|
589
535
|
def add_submatcher(submatcher)
|
@@ -615,8 +561,8 @@ module Shoulda
|
|
615
561
|
submatcher.with_message(@expected_message)
|
616
562
|
end
|
617
563
|
|
618
|
-
if
|
619
|
-
submatcher.on(
|
564
|
+
if context
|
565
|
+
submatcher.on(context)
|
620
566
|
end
|
621
567
|
|
622
568
|
submatcher.ignoring_interference_by_writer(
|
@@ -634,23 +580,25 @@ module Shoulda
|
|
634
580
|
end
|
635
581
|
|
636
582
|
def has_been_qualified?
|
637
|
-
@submatchers.any?
|
638
|
-
|
639
|
-
|
640
|
-
|
583
|
+
@submatchers.any? { |submatcher| submatcher_qualified?(submatcher) }
|
584
|
+
end
|
585
|
+
|
586
|
+
def submatcher_qualified?(submatcher)
|
587
|
+
Shoulda::Matchers::RailsShim.parent_of(submatcher.class) ==
|
588
|
+
NumericalityMatchers || submatcher.instance_of?(ComparisonMatcher)
|
641
589
|
end
|
642
590
|
|
643
591
|
def first_submatcher_that_fails_to_match
|
644
592
|
@_first_submatcher_that_fails_to_match ||=
|
645
593
|
@submatchers.detect do |submatcher|
|
646
|
-
!submatcher.matches?(
|
594
|
+
!submatcher.matches?(subject)
|
647
595
|
end
|
648
596
|
end
|
649
597
|
|
650
598
|
def first_submatcher_that_fails_to_not_match
|
651
599
|
@_first_submatcher_that_fails_to_not_match ||=
|
652
600
|
@submatchers.detect do |submatcher|
|
653
|
-
!submatcher.does_not_match?(
|
601
|
+
!submatcher.does_not_match?(subject)
|
654
602
|
end
|
655
603
|
end
|
656
604
|
|
@@ -719,10 +667,6 @@ module Shoulda
|
|
719
667
|
range_submatcher&.range_description
|
720
668
|
end
|
721
669
|
|
722
|
-
def model
|
723
|
-
@subject.class
|
724
|
-
end
|
725
|
-
|
726
670
|
def non_numeric_value
|
727
671
|
'abcd'
|
728
672
|
end
|
@@ -42,13 +42,12 @@ module Shoulda
|
|
42
42
|
description_clauses = []
|
43
43
|
|
44
44
|
if matcher.try(:expects_strict?)
|
45
|
-
description_clauses <<
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
description_clauses.last << ' on failure'
|
45
|
+
description_clauses <<
|
46
|
+
if matcher.try(:expects_custom_validation_message?)
|
47
|
+
'raising a validation exception with a custom message on failure'
|
48
|
+
else
|
49
|
+
'raising a validation exception on failure'
|
50
|
+
end
|
52
51
|
elsif matcher.try(:expects_custom_validation_message?)
|
53
52
|
description_clauses <<
|
54
53
|
'producing a custom validation error on failure'
|
@@ -186,6 +186,12 @@ module Shoulda
|
|
186
186
|
def blank_values
|
187
187
|
['', ' ', "\n", "\r", "\t", "\f"]
|
188
188
|
end
|
189
|
+
|
190
|
+
def array_column?
|
191
|
+
@subject.class.respond_to?(:columns_hash) &&
|
192
|
+
@subject.class.columns_hash[@attribute.to_s].respond_to?(:array) &&
|
193
|
+
@subject.class.columns_hash[@attribute.to_s].array
|
194
|
+
end
|
189
195
|
end
|
190
196
|
end
|
191
197
|
end
|
@@ -21,8 +21,9 @@ require 'shoulda/matchers/active_model/validate_presence_of_matcher'
|
|
21
21
|
require 'shoulda/matchers/active_model/validate_acceptance_of_matcher'
|
22
22
|
require 'shoulda/matchers/active_model/validate_confirmation_of_matcher'
|
23
23
|
require 'shoulda/matchers/active_model/validate_numericality_of_matcher'
|
24
|
+
require 'shoulda/matchers/active_model/validate_comparison_of_matcher'
|
25
|
+
require 'shoulda/matchers/active_model/comparison_matcher'
|
24
26
|
require 'shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher'
|
25
|
-
require 'shoulda/matchers/active_model/numericality_matchers/comparison_matcher'
|
26
27
|
require 'shoulda/matchers/active_model/numericality_matchers/odd_number_matcher'
|
27
28
|
require 'shoulda/matchers/active_model/numericality_matchers/even_number_matcher'
|
28
29
|
require 'shoulda/matchers/active_model/numericality_matchers/only_integer_matcher'
|
@@ -1093,6 +1093,11 @@ module Shoulda
|
|
1093
1093
|
self
|
1094
1094
|
end
|
1095
1095
|
|
1096
|
+
def with_query_constraints(query_constraints)
|
1097
|
+
@options[:query_constraints] = query_constraints
|
1098
|
+
self
|
1099
|
+
end
|
1100
|
+
|
1096
1101
|
def required(required = true)
|
1097
1102
|
remove_submatcher(AssociationMatchers::OptionalMatcher)
|
1098
1103
|
add_submatcher(
|
@@ -1157,6 +1162,7 @@ module Shoulda
|
|
1157
1162
|
(polymorphic? || class_exists?) &&
|
1158
1163
|
foreign_key_exists? &&
|
1159
1164
|
primary_key_exists? &&
|
1165
|
+
query_constraints_exists? &&
|
1160
1166
|
class_name_correct? &&
|
1161
1167
|
join_table_correct? &&
|
1162
1168
|
autosave_correct? &&
|
@@ -1258,7 +1264,7 @@ module Shoulda
|
|
1258
1264
|
false
|
1259
1265
|
end
|
1260
1266
|
|
1261
|
-
def
|
1267
|
+
def macro_is_not_through?
|
1262
1268
|
macro == :belongs_to ||
|
1263
1269
|
([:has_many, :has_one].include?(macro) && !through?)
|
1264
1270
|
end
|
@@ -1268,7 +1274,25 @@ module Shoulda
|
|
1268
1274
|
end
|
1269
1275
|
|
1270
1276
|
def primary_key_exists?
|
1271
|
-
!
|
1277
|
+
!macro_is_not_through? || primary_key_correct?(model_class)
|
1278
|
+
end
|
1279
|
+
|
1280
|
+
def query_constraints_exists?
|
1281
|
+
!macro_is_not_through? || query_constraints_correct?
|
1282
|
+
end
|
1283
|
+
|
1284
|
+
def query_constraints_correct?
|
1285
|
+
if options.key?(:query_constraints)
|
1286
|
+
if option_verifier.correct_for_string?(:query_constraints, options[:query_constraints])
|
1287
|
+
true
|
1288
|
+
else
|
1289
|
+
@missing = "#{model_class} should have \:query_constraints"\
|
1290
|
+
" options set to #{options[:query_constraints]}"
|
1291
|
+
false
|
1292
|
+
end
|
1293
|
+
else
|
1294
|
+
true
|
1295
|
+
end
|
1272
1296
|
end
|
1273
1297
|
|
1274
1298
|
def belongs_foreign_key_missing?
|
@@ -1299,10 +1323,7 @@ module Shoulda
|
|
1299
1323
|
end
|
1300
1324
|
|
1301
1325
|
def join_table_correct?
|
1302
|
-
if (
|
1303
|
-
macro != :has_and_belongs_to_many ||
|
1304
|
-
join_table_matcher.matches?(@subject)
|
1305
|
-
)
|
1326
|
+
if macro != :has_and_belongs_to_many || join_table_matcher.matches?(@subject)
|
1306
1327
|
true
|
1307
1328
|
else
|
1308
1329
|
@missing = join_table_matcher.failure_message
|
@@ -1457,11 +1478,10 @@ module Shoulda
|
|
1457
1478
|
end
|
1458
1479
|
|
1459
1480
|
def foreign_key_reflection
|
1460
|
-
if (
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
)
|
1481
|
+
if [:has_one, :has_many].include?(macro) &&
|
1482
|
+
reflection.options.include?(:inverse_of) &&
|
1483
|
+
reflection.options[:inverse_of] != false
|
1484
|
+
|
1465
1485
|
associated_class.reflect_on_association(
|
1466
1486
|
reflection.options[:inverse_of],
|
1467
1487
|
)
|
@@ -22,44 +22,48 @@ module Shoulda
|
|
22
22
|
if submatcher_passes?(subject)
|
23
23
|
true
|
24
24
|
else
|
25
|
-
@missing_option =
|
25
|
+
@missing_option = build_missing_option
|
26
26
|
|
27
|
-
|
27
|
+
false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
attr_reader :attribute_name, :optional, :submatcher
|
34
|
+
|
35
|
+
def submatcher_passes?(subject)
|
36
|
+
if optional
|
37
|
+
submatcher.matches?(subject)
|
38
|
+
else
|
39
|
+
submatcher.does_not_match?(subject)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def build_missing_option
|
44
|
+
String.new('and for the record ').tap do |missing_option_string|
|
45
|
+
missing_option_string <<
|
28
46
|
if optional
|
29
47
|
'not to '
|
30
48
|
else
|
31
49
|
'to '
|
32
50
|
end
|
33
51
|
|
34
|
-
|
52
|
+
missing_option_string << (
|
35
53
|
'fail validation if '\
|
36
54
|
":#{attribute_name} is unset; i.e., either the association "\
|
37
55
|
'should have been defined with `optional: '\
|
38
56
|
"#{optional.inspect}`, or there "
|
39
57
|
)
|
40
58
|
|
41
|
-
|
59
|
+
missing_option_string <<
|
42
60
|
if optional
|
43
61
|
'should not '
|
44
62
|
else
|
45
63
|
'should '
|
46
64
|
end
|
47
65
|
|
48
|
-
|
49
|
-
|
50
|
-
false
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
attr_reader :attribute_name, :optional, :submatcher
|
57
|
-
|
58
|
-
def submatcher_passes?(subject)
|
59
|
-
if optional
|
60
|
-
submatcher.matches?(subject)
|
61
|
-
else
|
62
|
-
submatcher.does_not_match?(subject)
|
66
|
+
missing_option_string << "be a presence validation on :#{attribute_name}"
|
63
67
|
end
|
64
68
|
end
|
65
69
|
end
|
@@ -23,50 +23,54 @@ module Shoulda
|
|
23
23
|
if submatcher_passes?(subject)
|
24
24
|
true
|
25
25
|
else
|
26
|
-
@missing_option =
|
26
|
+
@missing_option = build_missing_option
|
27
27
|
|
28
|
-
|
28
|
+
false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_reader :attribute_name, :required, :submatcher
|
35
|
+
|
36
|
+
def submatcher_passes?(subject)
|
37
|
+
if required
|
38
|
+
submatcher.matches?(subject)
|
39
|
+
else
|
40
|
+
submatcher.does_not_match?(subject)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def validation_message_key
|
45
|
+
:required
|
46
|
+
end
|
47
|
+
|
48
|
+
def build_missing_option
|
49
|
+
String.new('and for the record ').tap do |missing_option_string|
|
50
|
+
missing_option_string <<
|
29
51
|
if required
|
30
52
|
'to '
|
31
53
|
else
|
32
54
|
'not to '
|
33
55
|
end
|
34
56
|
|
35
|
-
|
57
|
+
missing_option_string << (
|
36
58
|
'fail validation if '\
|
37
59
|
":#{attribute_name} is unset; i.e., either the association "\
|
38
60
|
'should have been defined with `required: '\
|
39
61
|
"#{required.inspect}`, or there "
|
40
62
|
)
|
41
63
|
|
42
|
-
|
64
|
+
missing_option_string <<
|
43
65
|
if required
|
44
66
|
'should '
|
45
67
|
else
|
46
68
|
'should not '
|
47
69
|
end
|
48
70
|
|
49
|
-
|
50
|
-
|
51
|
-
false
|
71
|
+
missing_option_string << "be a presence validation on :#{attribute_name}"
|
52
72
|
end
|
53
73
|
end
|
54
|
-
|
55
|
-
private
|
56
|
-
|
57
|
-
attr_reader :attribute_name, :required, :submatcher
|
58
|
-
|
59
|
-
def submatcher_passes?(subject)
|
60
|
-
if required
|
61
|
-
submatcher.matches?(subject)
|
62
|
-
else
|
63
|
-
submatcher.does_not_match?(subject)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def validation_message_key
|
68
|
-
:required
|
69
|
-
end
|
70
74
|
end
|
71
75
|
end
|
72
76
|
end
|
@@ -227,14 +227,6 @@ module Shoulda
|
|
227
227
|
self
|
228
228
|
end
|
229
229
|
|
230
|
-
def with(expected_enum_values)
|
231
|
-
Shoulda::Matchers.warn_about_deprecated_method(
|
232
|
-
'The `with` qualifier on `define_enum_for`',
|
233
|
-
'`with_values`',
|
234
|
-
)
|
235
|
-
with_values(expected_enum_values)
|
236
|
-
end
|
237
|
-
|
238
230
|
def with_prefix(expected_prefix = true)
|
239
231
|
options[:prefix] = expected_prefix
|
240
232
|
self
|