shoulda-matchers 5.3.0 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|