shoulda-matchers 4.3.0 → 5.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{MIT-LICENSE → LICENSE} +1 -1
- data/README.md +170 -90
- data/lib/shoulda/matchers/action_controller/callback_matcher.rb +4 -89
- data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +3 -2
- data/lib/shoulda/matchers/action_controller/flash_store.rb +2 -4
- data/lib/shoulda/matchers/action_controller/permit_matcher.rb +29 -27
- data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +6 -8
- data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +6 -8
- data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +16 -13
- data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +2 -1
- data/lib/shoulda/matchers/action_controller/route_matcher.rb +5 -6
- data/lib/shoulda/matchers/action_controller/route_params.rb +1 -1
- data/lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb +19 -13
- data/lib/shoulda/matchers/active_model.rb +0 -1
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +29 -27
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb +1 -1
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +5 -5
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator.rb +2 -2
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters.rb +1 -1
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb +1 -1
- data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +51 -25
- data/lib/shoulda/matchers/active_model/helpers.rb +1 -1
- data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +32 -30
- data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/qualifiers/ignoring_interference_by_writer.rb +1 -1
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +10 -2
- data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +2 -2
- data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +8 -7
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +28 -46
- data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +33 -9
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +72 -27
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +4 -4
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +31 -6
- data/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +2 -4
- data/lib/shoulda/matchers/active_model/validation_message_finder.rb +2 -4
- data/lib/shoulda/matchers/active_model/validator.rb +4 -9
- data/lib/shoulda/matchers/active_record.rb +26 -24
- data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +6 -3
- data/lib/shoulda/matchers/active_record/association_matcher.rb +119 -50
- data/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +5 -2
- data/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +4 -4
- data/lib/shoulda/matchers/active_record/association_matchers/inverse_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +11 -6
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +14 -15
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +30 -8
- data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +23 -5
- data/lib/shoulda/matchers/active_record/association_matchers/optional_matcher.rb +3 -3
- data/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +4 -4
- data/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +3 -2
- data/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +7 -5
- data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +18 -9
- data/lib/shoulda/matchers/active_record/have_attached_matcher.rb +185 -0
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +39 -17
- data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/have_implicit_order_column.rb +106 -0
- data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +12 -10
- data/lib/shoulda/matchers/active_record/have_rich_text_matcher.rb +11 -7
- data/lib/shoulda/matchers/active_record/have_secure_token_matcher.rb +30 -9
- data/lib/shoulda/matchers/active_record/serialize_matcher.rb +13 -9
- data/lib/shoulda/matchers/active_record/uniqueness.rb +1 -1
- data/lib/shoulda/matchers/active_record/uniqueness/test_model_creator.rb +1 -3
- data/lib/shoulda/matchers/active_record/uniqueness/test_models.rb +0 -2
- data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +80 -73
- data/lib/shoulda/matchers/doublespeak.rb +2 -1
- data/lib/shoulda/matchers/doublespeak/double.rb +1 -1
- data/lib/shoulda/matchers/doublespeak/double_collection.rb +3 -3
- data/lib/shoulda/matchers/doublespeak/double_implementation_registry.rb +8 -5
- data/lib/shoulda/matchers/doublespeak/object_double.rb +1 -1
- data/lib/shoulda/matchers/doublespeak/stub_implementation.rb +1 -5
- data/lib/shoulda/matchers/doublespeak/world.rb +2 -2
- data/lib/shoulda/matchers/error.rb +1 -1
- data/lib/shoulda/matchers/independent.rb +0 -1
- data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +14 -13
- data/lib/shoulda/matchers/integrations/configuration.rb +1 -1
- data/lib/shoulda/matchers/integrations/libraries/action_controller.rb +1 -1
- data/lib/shoulda/matchers/integrations/libraries/rails.rb +2 -2
- 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/test_unit.rb +1 -1
- data/lib/shoulda/matchers/rails_shim.rb +7 -40
- data/lib/shoulda/matchers/util.rb +16 -4
- data/lib/shoulda/matchers/util/word_wrap.rb +8 -8
- data/lib/shoulda/matchers/version.rb +1 -1
- data/lib/shoulda/matchers/warn.rb +3 -3
- data/shoulda-matchers.gemspec +12 -9
- metadata +15 -15
- data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +0 -159
- data/lib/shoulda/matchers/independent/delegate_method_matcher/stubbed_target.rb +0 -37
@@ -4,12 +4,7 @@ module Shoulda
|
|
4
4
|
# The `have_secure_token` matcher tests usage of the
|
5
5
|
# `has_secure_token` macro.
|
6
6
|
#
|
7
|
-
# #### Example
|
8
|
-
#
|
9
7
|
# class User < ActiveRecord
|
10
|
-
# attr_accessor :token
|
11
|
-
# attr_accessor :auth_token
|
12
|
-
#
|
13
8
|
# has_secure_token
|
14
9
|
# has_secure_token :auth_token
|
15
10
|
# end
|
@@ -26,14 +21,32 @@ module Shoulda
|
|
26
21
|
# should have_secure_token(:auth_token)
|
27
22
|
# end
|
28
23
|
#
|
24
|
+
# #### Qualifiers
|
25
|
+
#
|
26
|
+
# ##### ignoring_check_for_db_index
|
27
|
+
#
|
28
|
+
# By default, this matcher tests that an index is defined on your token
|
29
|
+
# column. Use `ignoring_check_for_db_index` if this is not the case.
|
30
|
+
#
|
31
|
+
# class User < ActiveRecord
|
32
|
+
# has_secure_token :auth_token
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# # RSpec
|
36
|
+
# RSpec.describe User, type: :model do
|
37
|
+
# it { should have_secure_token(:auth_token).ignoring_check_for_db_index }
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# # Minitest (Shoulda)
|
41
|
+
# class UserTest < ActiveSupport::TestCase
|
42
|
+
# should have_secure_token(:auth_token).ignoring_check_for_db_index
|
43
|
+
# end
|
44
|
+
#
|
29
45
|
# @return [HaveSecureToken]
|
30
46
|
#
|
31
|
-
|
32
|
-
# rubocop:disable Style/PredicateName
|
33
47
|
def have_secure_token(token_attribute = :token)
|
34
48
|
HaveSecureTokenMatcher.new(token_attribute)
|
35
49
|
end
|
36
|
-
# rubocop:enable Style/PredicateName
|
37
50
|
|
38
51
|
# @private
|
39
52
|
class HaveSecureTokenMatcher
|
@@ -41,6 +54,7 @@ module Shoulda
|
|
41
54
|
|
42
55
|
def initialize(token_attribute)
|
43
56
|
@token_attribute = token_attribute
|
57
|
+
@options = { ignore_check_for_db_index: false }
|
44
58
|
end
|
45
59
|
|
46
60
|
def description
|
@@ -49,12 +63,14 @@ module Shoulda
|
|
49
63
|
|
50
64
|
def failure_message
|
51
65
|
return if !@errors
|
66
|
+
|
52
67
|
"Expected #{@subject.class} to #{description} but the following " \
|
53
68
|
"errors were found: #{@errors.join(', ')}"
|
54
69
|
end
|
55
70
|
|
56
71
|
def failure_message_when_negated
|
57
72
|
return if !@errors
|
73
|
+
|
58
74
|
"Did not expect #{@subject.class} to have secure token " \
|
59
75
|
":#{token_attribute}"
|
60
76
|
end
|
@@ -65,6 +81,11 @@ module Shoulda
|
|
65
81
|
@errors.empty?
|
66
82
|
end
|
67
83
|
|
84
|
+
def ignoring_check_for_db_index
|
85
|
+
@options[:ignore_check_for_db_index] = true
|
86
|
+
self
|
87
|
+
end
|
88
|
+
|
68
89
|
private
|
69
90
|
|
70
91
|
def run_checks
|
@@ -75,7 +96,7 @@ module Shoulda
|
|
75
96
|
if !has_expected_db_column?
|
76
97
|
@errors << "missing correct column #{token_attribute}:string"
|
77
98
|
end
|
78
|
-
if !has_expected_db_index?
|
99
|
+
if !@options[:ignore_check_for_db_index] && !has_expected_db_index?
|
79
100
|
@errors << "missing unique index for #{table_and_column}"
|
80
101
|
end
|
81
102
|
@errors
|
@@ -121,7 +121,9 @@ module Shoulda
|
|
121
121
|
|
122
122
|
def description
|
123
123
|
description = "serialize :#{@name}"
|
124
|
-
|
124
|
+
if @options.key?(:type)
|
125
|
+
description += " class_name => #{@options[:type]}"
|
126
|
+
end
|
125
127
|
description
|
126
128
|
end
|
127
129
|
|
@@ -141,13 +143,12 @@ module Shoulda
|
|
141
143
|
klass = serialization_coder
|
142
144
|
if klass == @options[:type]
|
143
145
|
true
|
146
|
+
elsif klass.respond_to?(:object_class) &&
|
147
|
+
klass.object_class == @options[:type]
|
148
|
+
true
|
144
149
|
else
|
145
|
-
|
146
|
-
|
147
|
-
else
|
148
|
-
@missing = ":#{@name} should be a type of #{@options[:type]}"
|
149
|
-
false
|
150
|
-
end
|
150
|
+
@missing = ":#{@name} should be a type of #{@options[:type]}"
|
151
|
+
false
|
151
152
|
end
|
152
153
|
else
|
153
154
|
true
|
@@ -176,9 +177,12 @@ module Shoulda
|
|
176
177
|
end
|
177
178
|
|
178
179
|
def expectation
|
179
|
-
expectation = "#{model_class.name} to serialize the attribute called
|
180
|
+
expectation = "#{model_class.name} to serialize the attribute called"\
|
181
|
+
" :#{@name}"
|
180
182
|
expectation += " with a type of #{@options[:type]}" if @options[:type]
|
181
|
-
|
183
|
+
if @options[:instance_type]
|
184
|
+
expectation += " with an instance of #{@options[:instance_type]}"
|
185
|
+
end
|
182
186
|
expectation
|
183
187
|
end
|
184
188
|
|
@@ -80,7 +80,7 @@ module Shoulda
|
|
80
80
|
#
|
81
81
|
# RSpec.describe Post, type: :model do
|
82
82
|
# describe "validations" do
|
83
|
-
# subject { Post.
|
83
|
+
# subject { Post.new(content: "Here is the content") }
|
84
84
|
# it { should validate_uniqueness_of(:title) }
|
85
85
|
# end
|
86
86
|
# end
|
@@ -92,7 +92,7 @@ module Shoulda
|
|
92
92
|
#
|
93
93
|
# RSpec.describe Post, type: :model do
|
94
94
|
# describe "validations" do
|
95
|
-
# subject { FactoryBot.
|
95
|
+
# subject { FactoryBot.build(:post) }
|
96
96
|
# it { should validate_uniqueness_of(:title) }
|
97
97
|
# end
|
98
98
|
# end
|
@@ -157,6 +157,12 @@ module Shoulda
|
|
157
157
|
# should validate_uniqueness_of(:slug).scoped_to(:journal_id)
|
158
158
|
# end
|
159
159
|
#
|
160
|
+
# NOTE: Support for testing uniqueness validation scoped to an array of
|
161
|
+
# associations is not available.
|
162
|
+
#
|
163
|
+
# For more information, please refer to
|
164
|
+
# https://github.com/thoughtbot/shoulda-matchers/issues/814
|
165
|
+
#
|
160
166
|
# ##### case_insensitive
|
161
167
|
#
|
162
168
|
# Use `case_insensitive` to test usage of the `:case_sensitive` option
|
@@ -264,14 +270,14 @@ module Shoulda
|
|
264
270
|
super(attribute)
|
265
271
|
@expected_message = :taken
|
266
272
|
@options = {
|
267
|
-
case_sensitivity_strategy: :sensitive
|
273
|
+
case_sensitivity_strategy: :sensitive,
|
268
274
|
}
|
269
275
|
@existing_record_created = false
|
270
276
|
@failure_reason = nil
|
271
277
|
@failure_reason_when_negated = nil
|
272
278
|
@attribute_setters = {
|
273
279
|
existing_record: AttributeSetters.new,
|
274
|
-
new_record: AttributeSetters.new
|
280
|
+
new_record: AttributeSetters.new,
|
275
281
|
}
|
276
282
|
end
|
277
283
|
|
@@ -396,7 +402,7 @@ module Shoulda
|
|
396
402
|
end
|
397
403
|
|
398
404
|
def validations
|
399
|
-
model.
|
405
|
+
model.validators_on(@attribute).select do |validator|
|
400
406
|
validator.is_a?(::ActiveRecord::Validations::UniquenessValidator)
|
401
407
|
end
|
402
408
|
end
|
@@ -407,11 +413,12 @@ module Shoulda
|
|
407
413
|
else
|
408
414
|
@failure_reason = 'Expected the validation '
|
409
415
|
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
416
|
+
@failure_reason <<
|
417
|
+
if expected_scopes.empty?
|
418
|
+
'not to be scoped to anything, '
|
419
|
+
else
|
420
|
+
"to be scoped to #{inspected_expected_scopes}, "
|
421
|
+
end
|
415
422
|
|
416
423
|
if actual_sets_of_scopes.any?
|
417
424
|
@failure_reason << 'but it was scoped to '
|
@@ -455,7 +462,7 @@ module Shoulda
|
|
455
462
|
def inspected_actual_scopes
|
456
463
|
inspected_actual_sets_of_scopes.to_sentence(
|
457
464
|
words_connector: ' and ',
|
458
|
-
last_word_connector: ', and'
|
465
|
+
last_word_connector: ', and',
|
459
466
|
)
|
460
467
|
end
|
461
468
|
|
@@ -491,7 +498,9 @@ module Shoulda
|
|
491
498
|
def does_not_match_allow_nil?
|
492
499
|
expects_to_allow_nil? && (
|
493
500
|
update_existing_record!(nil) &&
|
494
|
-
(@failure_reason = nil ||
|
501
|
+
(@failure_reason = nil ||
|
502
|
+
disallows_value_of(nil, @expected_message)
|
503
|
+
)
|
495
504
|
)
|
496
505
|
end
|
497
506
|
|
@@ -527,21 +536,15 @@ module Shoulda
|
|
527
536
|
end
|
528
537
|
|
529
538
|
def find_existing_record
|
530
|
-
|
531
|
-
|
532
|
-
if record.present?
|
533
|
-
record
|
534
|
-
else
|
535
|
-
nil
|
536
|
-
end
|
539
|
+
model.first.presence
|
537
540
|
end
|
538
541
|
|
539
542
|
def create_existing_record
|
540
543
|
@given_record.tap do |existing_record|
|
541
544
|
existing_record.save(validate: false)
|
542
545
|
end
|
543
|
-
rescue ::ActiveRecord::StatementInvalid =>
|
544
|
-
raise ExistingRecordInvalid.create(underlying_exception:
|
546
|
+
rescue ::ActiveRecord::StatementInvalid => e
|
547
|
+
raise ExistingRecordInvalid.create(underlying_exception: e)
|
545
548
|
end
|
546
549
|
|
547
550
|
def update_existing_record!(value)
|
@@ -577,7 +580,7 @@ module Shoulda
|
|
577
580
|
attribute_names_under_test.each do |attribute_name|
|
578
581
|
set_attribute_on_new_record!(
|
579
582
|
attribute_name,
|
580
|
-
existing_record.public_send(attribute_name)
|
583
|
+
existing_record.public_send(attribute_name),
|
581
584
|
)
|
582
585
|
end
|
583
586
|
|
@@ -619,11 +622,12 @@ module Shoulda
|
|
619
622
|
|
620
623
|
reason << inspected_scopes.to_sentence
|
621
624
|
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
625
|
+
reason <<
|
626
|
+
if inspected_scopes.many?
|
627
|
+
' do not seem to be attributes'
|
628
|
+
else
|
629
|
+
' does not seem to be an attribute'
|
630
|
+
end
|
627
631
|
|
628
632
|
reason << " on #{model.name}."
|
629
633
|
|
@@ -643,11 +647,12 @@ module Shoulda
|
|
643
647
|
|
644
648
|
reason << inspected_scopes.to_sentence
|
645
649
|
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
650
|
+
reason <<
|
651
|
+
if inspected_scopes.many?
|
652
|
+
' seem to be attributes'
|
653
|
+
else
|
654
|
+
' seems to be an attribute'
|
655
|
+
end
|
651
656
|
|
652
657
|
reason << " on #{model.name}."
|
653
658
|
|
@@ -658,14 +663,14 @@ module Shoulda
|
|
658
663
|
end
|
659
664
|
|
660
665
|
def scopes_present_on_model
|
661
|
-
@
|
666
|
+
@_scopes_present_on_model ||= expected_scopes.select do |scope|
|
662
667
|
model.method_defined?("#{scope}=")
|
663
668
|
end
|
664
669
|
end
|
665
670
|
|
666
671
|
def scopes_missing_on_model
|
667
|
-
@
|
668
|
-
|
672
|
+
@_scopes_missing_on_model ||= expected_scopes.reject do |scope|
|
673
|
+
model.method_defined?("#{scope}=")
|
669
674
|
end
|
670
675
|
end
|
671
676
|
|
@@ -697,7 +702,7 @@ module Shoulda
|
|
697
702
|
raise NonCaseSwappableValueError.create(
|
698
703
|
model: model,
|
699
704
|
attribute: @attribute,
|
700
|
-
value: value
|
705
|
+
value: value,
|
701
706
|
)
|
702
707
|
end
|
703
708
|
|
@@ -724,7 +729,7 @@ module Shoulda
|
|
724
729
|
raise NonCaseSwappableValueError.create(
|
725
730
|
model: model,
|
726
731
|
attribute: @attribute,
|
727
|
-
value: value
|
732
|
+
value: value,
|
728
733
|
)
|
729
734
|
end
|
730
735
|
|
@@ -789,7 +794,7 @@ module Shoulda
|
|
789
794
|
column = column_for(scope)
|
790
795
|
|
791
796
|
if column.respond_to?(:array) && column.array
|
792
|
-
[
|
797
|
+
[dummy_scalar_value_for(column)]
|
793
798
|
else
|
794
799
|
dummy_scalar_value_for(column)
|
795
800
|
end
|
@@ -801,7 +806,7 @@ module Shoulda
|
|
801
806
|
|
802
807
|
def next_value_for(scope, previous_value)
|
803
808
|
if previous_value.is_a?(Array)
|
804
|
-
[
|
809
|
+
[next_scalar_value_for(scope, previous_value[0])]
|
805
810
|
else
|
806
811
|
next_scalar_value_for(scope, previous_value)
|
807
812
|
end
|
@@ -820,7 +825,7 @@ module Shoulda
|
|
820
825
|
elsif previous_value.respond_to?(:next)
|
821
826
|
previous_value.next
|
822
827
|
elsif previous_value.respond_to?(:to_datetime)
|
823
|
-
previous_value.to_datetime.next
|
828
|
+
previous_value.to_datetime.in(60).next
|
824
829
|
elsif boolean_value?(previous_value)
|
825
830
|
!previous_value
|
826
831
|
else
|
@@ -857,7 +862,7 @@ module Shoulda
|
|
857
862
|
attribute_setter = build_attribute_setter(
|
858
863
|
record,
|
859
864
|
attribute_name,
|
860
|
-
value
|
865
|
+
value,
|
861
866
|
)
|
862
867
|
attribute_setter.set!
|
863
868
|
|
@@ -869,7 +874,7 @@ module Shoulda
|
|
869
874
|
:existing_record,
|
870
875
|
existing_record,
|
871
876
|
attribute_name,
|
872
|
-
value
|
877
|
+
value,
|
873
878
|
)
|
874
879
|
end
|
875
880
|
|
@@ -878,7 +883,7 @@ module Shoulda
|
|
878
883
|
:new_record,
|
879
884
|
new_record,
|
880
885
|
attribute_name,
|
881
|
-
value
|
886
|
+
value,
|
882
887
|
)
|
883
888
|
end
|
884
889
|
|
@@ -896,13 +901,14 @@ module Shoulda
|
|
896
901
|
end
|
897
902
|
|
898
903
|
def build_attribute_setter(record, attribute_name, value)
|
899
|
-
Shoulda::Matchers::ActiveModel::AllowValueMatcher::AttributeSetter.
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
904
|
+
Shoulda::Matchers::ActiveModel::AllowValueMatcher::AttributeSetter.
|
905
|
+
new(
|
906
|
+
matcher_name: :validate_uniqueness_of,
|
907
|
+
object: record,
|
908
|
+
attribute_name: attribute_name,
|
909
|
+
value: value,
|
910
|
+
ignore_interference_by_writer: ignore_interference_by_writer,
|
911
|
+
)
|
906
912
|
end
|
907
913
|
|
908
914
|
def existing_value_read
|
@@ -929,7 +935,7 @@ module Shoulda
|
|
929
935
|
@given_record.class
|
930
936
|
end
|
931
937
|
|
932
|
-
def failure_message_preface
|
938
|
+
def failure_message_preface # rubocop:disable Metrics/MethodLength
|
933
939
|
prefix = ''
|
934
940
|
|
935
941
|
if @existing_record_created
|
@@ -938,30 +944,28 @@ module Shoulda
|
|
938
944
|
if attribute_setter_for_existing_record
|
939
945
|
prefix << ', setting '
|
940
946
|
prefix << description_for_attribute_setter(
|
941
|
-
attribute_setter_for_existing_record
|
947
|
+
attribute_setter_for_existing_record,
|
942
948
|
)
|
943
949
|
else
|
944
950
|
prefix << ", whose :#{attribute} is "
|
945
951
|
prefix << "‹#{existing_value_read.inspect}›"
|
946
952
|
end
|
947
953
|
|
948
|
-
prefix <<
|
954
|
+
prefix << ', and saving it as the existing record, then'
|
955
|
+
elsif attribute_setter_for_existing_record
|
956
|
+
prefix << "Given an existing #{model.name},"
|
957
|
+
prefix << ' after setting '
|
958
|
+
prefix << description_for_attribute_setter(
|
959
|
+
attribute_setter_for_existing_record,
|
960
|
+
)
|
961
|
+
prefix << ', then'
|
949
962
|
else
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
prefix << ', then'
|
957
|
-
else
|
958
|
-
prefix << "Given an existing #{model.name} whose :#{attribute}"
|
959
|
-
prefix << ' is '
|
960
|
-
prefix << Shoulda::Matchers::Util.inspect_value(
|
961
|
-
existing_value_read
|
962
|
-
)
|
963
|
-
prefix << ', after'
|
964
|
-
end
|
963
|
+
prefix << "Given an existing #{model.name} whose :#{attribute}"
|
964
|
+
prefix << ' is '
|
965
|
+
prefix << Shoulda::Matchers::Util.inspect_value(
|
966
|
+
existing_value_read,
|
967
|
+
)
|
968
|
+
prefix << ', after'
|
965
969
|
end
|
966
970
|
|
967
971
|
prefix << " making a new #{model.name} and setting "
|
@@ -988,7 +992,10 @@ different altogether.
|
|
988
992
|
MESSAGE
|
989
993
|
end
|
990
994
|
|
991
|
-
def description_for_attribute_setter(
|
995
|
+
def description_for_attribute_setter(
|
996
|
+
attribute_setter,
|
997
|
+
same_as_existing: nil
|
998
|
+
)
|
992
999
|
description = "its :#{attribute_setter.attribute_name} to "
|
993
1000
|
|
994
1001
|
if same_as_existing == false
|
@@ -996,13 +1003,13 @@ different altogether.
|
|
996
1003
|
end
|
997
1004
|
|
998
1005
|
description << Shoulda::Matchers::Util.inspect_value(
|
999
|
-
attribute_setter.value_written
|
1006
|
+
attribute_setter.value_written,
|
1000
1007
|
)
|
1001
1008
|
|
1002
1009
|
if attribute_setter.attribute_changed_value?
|
1003
1010
|
description << ' (read back as '
|
1004
1011
|
description << Shoulda::Matchers::Util.inspect_value(
|
1005
|
-
attribute_setter.value_read
|
1012
|
+
attribute_setter.value_read,
|
1006
1013
|
)
|
1007
1014
|
description << ')'
|
1008
1015
|
end
|
@@ -1026,7 +1033,7 @@ different altogether.
|
|
1026
1033
|
)
|
1027
1034
|
description_for_attribute_setter(
|
1028
1035
|
attribute_setter,
|
1029
|
-
same_as_existing: same_as_existing
|
1036
|
+
same_as_existing: same_as_existing,
|
1030
1037
|
)
|
1031
1038
|
end
|
1032
1039
|
end
|
@@ -1109,7 +1116,7 @@ b) If you meant for the validation to be case-insensitive, then you need to
|
|
1109
1116
|
|
1110
1117
|
For more information, please see:
|
1111
1118
|
|
1112
|
-
|
1119
|
+
https://matchers.shoulda.io/docs/v#{Shoulda::Matchers::VERSION}/file.NonCaseSwappableValueError.html
|
1113
1120
|
MESSAGE
|
1114
1121
|
end
|
1115
1122
|
end
|