shoulda-matchers 3.0.1 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +3 -3
- data/CONTRIBUTING.md +60 -28
- data/Gemfile +1 -0
- data/Gemfile.lock +15 -12
- data/NEWS.md +111 -0
- data/README.md +94 -6
- data/Rakefile +10 -8
- data/custom_plan.rb +88 -0
- data/gemfiles/4.0.0.gemfile +1 -0
- data/gemfiles/4.0.0.gemfile.lock +21 -18
- data/gemfiles/4.0.1.gemfile +1 -0
- data/gemfiles/4.0.1.gemfile.lock +21 -18
- data/gemfiles/4.1.gemfile +1 -0
- data/gemfiles/4.1.gemfile.lock +21 -18
- data/gemfiles/4.2.gemfile +1 -0
- data/gemfiles/4.2.gemfile.lock +24 -21
- data/lib/shoulda/matchers/action_controller/permit_matcher.rb +6 -11
- data/lib/shoulda/matchers/active_model.rb +10 -1
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +258 -180
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb +45 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_does_not_exist_error.rb +23 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +236 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator.rb +62 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters.rb +40 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb +48 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher/successful_check.rb +14 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher/successful_setting.rb +14 -0
- data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +34 -14
- data/lib/shoulda/matchers/active_model/helpers.rb +9 -17
- data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +13 -6
- data/lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb +13 -2
- data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +19 -35
- data/lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb +13 -2
- data/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +12 -2
- data/lib/shoulda/matchers/active_model/qualifiers.rb +12 -0
- data/lib/shoulda/matchers/active_model/qualifiers/ignore_interference_by_writer.rb +101 -0
- data/lib/shoulda/matchers/active_model/qualifiers/ignoring_interference_by_writer.rb +21 -0
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +30 -32
- data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +5 -8
- data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +22 -22
- data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +27 -16
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +58 -15
- data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +22 -12
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +165 -87
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +7 -9
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +111 -49
- data/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +60 -0
- data/lib/shoulda/matchers/active_model/validator.rb +71 -52
- data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +19 -5
- data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +450 -124
- data/lib/shoulda/matchers/util.rb +43 -0
- data/lib/shoulda/matchers/util/word_wrap.rb +59 -31
- data/lib/shoulda/matchers/version.rb +1 -1
- data/script/update_gem_in_all_appraisals +1 -1
- data/script/update_gems_in_all_appraisals +1 -1
- data/spec/acceptance/multiple_libraries_integration_spec.rb +5 -2
- data/spec/acceptance/rails_integration_spec.rb +6 -2
- data/spec/spec_helper.rb +1 -3
- data/spec/support/acceptance/helpers/step_helpers.rb +4 -1
- data/spec/support/tests/current_bundle.rb +21 -7
- data/spec/support/unit/active_record/create_table.rb +54 -0
- data/spec/support/unit/attribute.rb +47 -0
- data/spec/support/unit/capture.rb +6 -0
- data/spec/support/unit/change_value.rb +111 -0
- data/spec/support/unit/create_model_arguments/basic.rb +135 -0
- data/spec/support/unit/create_model_arguments/has_many.rb +15 -0
- data/spec/support/unit/create_model_arguments/uniqueness_matcher.rb +74 -0
- data/spec/support/unit/helpers/active_record_versions.rb +1 -1
- data/spec/support/unit/helpers/class_builder.rb +61 -47
- data/spec/support/unit/helpers/database_helpers.rb +5 -3
- data/spec/support/unit/helpers/model_builder.rb +77 -97
- data/spec/support/unit/helpers/validation_matcher_scenario_helpers.rb +44 -0
- data/spec/support/unit/load_environment.rb +12 -0
- data/spec/support/unit/matchers/fail_with_message_including_matcher.rb +2 -2
- data/spec/support/unit/matchers/fail_with_message_matcher.rb +12 -1
- data/spec/support/unit/model_creation_strategies/active_model.rb +111 -0
- data/spec/support/unit/model_creation_strategies/active_record.rb +77 -0
- data/spec/support/unit/model_creators.rb +19 -0
- data/spec/support/unit/model_creators/active_model.rb +39 -0
- data/spec/support/unit/model_creators/active_record.rb +43 -0
- data/spec/support/unit/model_creators/active_record/has_and_belongs_to_many.rb +95 -0
- data/spec/support/unit/model_creators/active_record/has_many.rb +67 -0
- data/spec/support/unit/model_creators/active_record/uniqueness_matcher.rb +42 -0
- data/spec/support/unit/model_creators/basic.rb +97 -0
- data/spec/support/unit/rails_application.rb +1 -1
- data/spec/support/unit/record_validating_confirmation_builder.rb +3 -7
- data/spec/support/unit/shared_examples/ignoring_interference_by_writer.rb +79 -0
- data/spec/support/unit/validation_matcher_scenario.rb +62 -0
- data/spec/unit/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +4 -0
- data/spec/unit/shoulda/matchers/active_model/allow_value_matcher_spec.rb +575 -140
- data/spec/unit/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +115 -15
- data/spec/unit/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +42 -4
- data/spec/unit/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +92 -6
- data/spec/unit/shoulda/matchers/active_model/validate_exclusion_of_matcher_spec.rb +122 -10
- data/spec/unit/shoulda/matchers/active_model/validate_inclusion_of_matcher_spec.rb +306 -58
- data/spec/unit/shoulda/matchers/active_model/validate_length_of_matcher_spec.rb +122 -3
- data/spec/unit/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +805 -131
- data/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +196 -29
- data/spec/unit/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb +82 -40
- data/spec/unit/shoulda/matchers/active_record/validate_uniqueness_of_matcher_spec.rb +600 -101
- data/spec/unit/shoulda/matchers/util/word_wrap_spec.rb +88 -33
- data/spec/unit_spec_helper.rb +10 -22
- data/zeus.json +11 -0
- metadata +64 -23
- data/lib/shoulda/matchers/active_model/strict_validator.rb +0 -51
- data/spec/support/unit/shared_examples/numerical_type_submatcher.rb +0 -15
- data/spec/unit/shoulda/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +0 -288
- data/spec/unit/shoulda/matchers/active_model/numericality_matchers/even_number_matcher_spec.rb +0 -100
- data/spec/unit/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher_spec.rb +0 -100
- data/spec/unit/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher_spec.rb +0 -100
@@ -0,0 +1,19 @@
|
|
1
|
+
module UnitTests
|
2
|
+
module ModelCreators
|
3
|
+
class << self
|
4
|
+
def register(name, klass)
|
5
|
+
registrations[name] = klass
|
6
|
+
end
|
7
|
+
|
8
|
+
def retrieve(name)
|
9
|
+
registrations[name]
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def registrations
|
15
|
+
@_registrations ||= {}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative '../model_creators'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module UnitTests
|
5
|
+
module ModelCreators
|
6
|
+
class ActiveModel
|
7
|
+
def self.call(args)
|
8
|
+
new(args).call
|
9
|
+
end
|
10
|
+
|
11
|
+
extend Forwardable
|
12
|
+
|
13
|
+
def_delegators(
|
14
|
+
:arguments,
|
15
|
+
:attribute_name,
|
16
|
+
:attribute_default_values_by_name,
|
17
|
+
)
|
18
|
+
|
19
|
+
def initialize(args)
|
20
|
+
@arguments = CreateModelArguments::Basic.wrap(
|
21
|
+
args.merge(
|
22
|
+
model_creation_strategy: UnitTests::ModelCreationStrategies::ActiveModel
|
23
|
+
)
|
24
|
+
)
|
25
|
+
@model_creator = Basic.new(arguments)
|
26
|
+
end
|
27
|
+
|
28
|
+
def call
|
29
|
+
model_creator.call
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
attr_reader :arguments, :model_creator
|
35
|
+
end
|
36
|
+
|
37
|
+
register(:active_model, ActiveModel)
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require_relative '../model_creators'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module UnitTests
|
5
|
+
module ModelCreators
|
6
|
+
class ActiveRecord
|
7
|
+
def self.call(args)
|
8
|
+
new(args).call
|
9
|
+
end
|
10
|
+
|
11
|
+
extend Forwardable
|
12
|
+
|
13
|
+
def_delegators(
|
14
|
+
:arguments,
|
15
|
+
:attribute_default_values_by_name,
|
16
|
+
:attribute_name,
|
17
|
+
:customize_model,
|
18
|
+
:model_name,
|
19
|
+
)
|
20
|
+
|
21
|
+
def_delegators :model_creator, :customize_model
|
22
|
+
|
23
|
+
def initialize(args)
|
24
|
+
@arguments = CreateModelArguments::Basic.wrap(
|
25
|
+
args.merge(
|
26
|
+
model_creation_strategy: UnitTests::ModelCreationStrategies::ActiveRecord
|
27
|
+
)
|
28
|
+
)
|
29
|
+
@model_creator = Basic.new(arguments)
|
30
|
+
end
|
31
|
+
|
32
|
+
def call
|
33
|
+
model_creator.call
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
attr_reader :arguments, :model_creator
|
39
|
+
end
|
40
|
+
|
41
|
+
register(:active_record, ActiveRecord)
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require_relative '../../model_creators'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module UnitTests
|
5
|
+
module ModelCreators
|
6
|
+
class ActiveRecord
|
7
|
+
class HasAndBelongsToMany
|
8
|
+
def self.call(args)
|
9
|
+
new(args).call
|
10
|
+
end
|
11
|
+
|
12
|
+
extend Forwardable
|
13
|
+
|
14
|
+
def_delegators(
|
15
|
+
:arguments,
|
16
|
+
:attribute_name,
|
17
|
+
:attribute_default_values_by_name,
|
18
|
+
)
|
19
|
+
|
20
|
+
def initialize(args)
|
21
|
+
@arguments = CreateModelArguments::HasMany.wrap(args)
|
22
|
+
end
|
23
|
+
|
24
|
+
def call
|
25
|
+
parent_child_table_creator.call
|
26
|
+
child_model_creator.call
|
27
|
+
parent_model_creator.call
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
attr_reader :arguments
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
alias_method :association_name, :attribute_name
|
37
|
+
alias_method :parent_model_creator_arguments, :arguments
|
38
|
+
|
39
|
+
def parent_child_table_creator
|
40
|
+
@_parent_child_table_creator ||=
|
41
|
+
UnitTests::ActiveRecord::CreateTable.new(
|
42
|
+
parent_child_table_name,
|
43
|
+
foreign_key_for_child_model => :integer,
|
44
|
+
foreign_key_for_parent_model => :integer,
|
45
|
+
:id => false
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
def child_model_creator
|
50
|
+
@_child_model_creator ||=
|
51
|
+
UnitTests::ModelCreationStrategies::ActiveRecord.new(
|
52
|
+
child_model_name
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
def parent_model_creator
|
57
|
+
@_parent_model_creator ||= begin
|
58
|
+
model_creator = UnitTests::ModelCreators::ActiveRecord.new(
|
59
|
+
parent_model_creator_arguments
|
60
|
+
)
|
61
|
+
|
62
|
+
# TODO: doesn't this need to be a has_many :through?
|
63
|
+
model_creator.customize_model do |model|
|
64
|
+
model.has_many(association_name)
|
65
|
+
end
|
66
|
+
|
67
|
+
model_creator
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def foreign_key_for_child_model
|
72
|
+
child_model_name.foreign_key
|
73
|
+
end
|
74
|
+
|
75
|
+
def foreign_key_for_parent_model
|
76
|
+
parent_model_name.foreign_key
|
77
|
+
end
|
78
|
+
|
79
|
+
def parent_child_table_name
|
80
|
+
"#{child_model_name.pluralize}#{parent_model_name}".tableize
|
81
|
+
end
|
82
|
+
|
83
|
+
def parent_model_name
|
84
|
+
parent_model_creator.model_name
|
85
|
+
end
|
86
|
+
|
87
|
+
def child_model_name
|
88
|
+
association_name.to_s.classify
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
register(:"active_record/habtm", ActiveRecord::HasAndBelongsToMany)
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require_relative '../../model_creators'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module UnitTests
|
5
|
+
module ModelCreators
|
6
|
+
class ActiveRecord
|
7
|
+
class HasMany
|
8
|
+
def self.call(args)
|
9
|
+
new(args).call
|
10
|
+
end
|
11
|
+
|
12
|
+
extend Forwardable
|
13
|
+
|
14
|
+
def_delegators(
|
15
|
+
:arguments,
|
16
|
+
:attribute_name,
|
17
|
+
:attribute_default_values_by_name,
|
18
|
+
)
|
19
|
+
|
20
|
+
def initialize(args)
|
21
|
+
@arguments = CreateModelArguments::HasMany.wrap(args)
|
22
|
+
end
|
23
|
+
|
24
|
+
def call
|
25
|
+
child_model_creator.call
|
26
|
+
parent_model_creator.call
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
attr_reader :arguments
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
alias_method :association_name, :attribute_name
|
36
|
+
alias_method :parent_model_creator_arguments, :arguments
|
37
|
+
|
38
|
+
def child_model_creator
|
39
|
+
@_child_model_creator ||=
|
40
|
+
UnitTests::ModelCreationStrategies::ActiveRecord.new(
|
41
|
+
child_model_name
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def parent_model_creator
|
46
|
+
@_parent_model_creator ||= begin
|
47
|
+
model_creator = UnitTests::ModelCreators::ActiveRecord.new(
|
48
|
+
parent_model_creator_arguments
|
49
|
+
)
|
50
|
+
|
51
|
+
model_creator.customize_model do |model|
|
52
|
+
model.has_many(association_name)
|
53
|
+
end
|
54
|
+
|
55
|
+
model_creator
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def child_model_name
|
60
|
+
association_name.to_s.classify
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
register(:"active_record/has_many", ActiveRecord::HasMany)
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require_relative '../../model_creators'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module UnitTests
|
5
|
+
module ModelCreators
|
6
|
+
class ActiveRecord
|
7
|
+
class UniquenessMatcher
|
8
|
+
def self.call(args)
|
9
|
+
new(args).call
|
10
|
+
end
|
11
|
+
|
12
|
+
extend Forwardable
|
13
|
+
|
14
|
+
def_delegators(
|
15
|
+
:arguments,
|
16
|
+
:attribute_name,
|
17
|
+
:attribute_default_values_by_name,
|
18
|
+
)
|
19
|
+
|
20
|
+
def initialize(args)
|
21
|
+
@arguments = CreateModelArguments::UniquenessMatcher.wrap(args)
|
22
|
+
@model_creator = UnitTests::ModelCreators::ActiveRecord.new(
|
23
|
+
arguments
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def call
|
28
|
+
model_creator.call
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
attr_reader :arguments, :model_creator
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
register(
|
38
|
+
:"active_record/uniqueness_matcher",
|
39
|
+
ActiveRecord::UniquenessMatcher
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module UnitTests
|
4
|
+
module ModelCreators
|
5
|
+
class Basic
|
6
|
+
def self.call(args)
|
7
|
+
new(args).call
|
8
|
+
end
|
9
|
+
|
10
|
+
extend Forwardable
|
11
|
+
|
12
|
+
def_delegators :arguments, :attribute_name, :model_name
|
13
|
+
def_delegators :model_creator, :customize_model
|
14
|
+
|
15
|
+
def initialize(arguments)
|
16
|
+
@arguments = arguments
|
17
|
+
@model_creator = build_model_creator
|
18
|
+
end
|
19
|
+
|
20
|
+
def call
|
21
|
+
model_creator.call
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
attr_reader :arguments, :model_creator
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def_delegators(
|
31
|
+
:arguments,
|
32
|
+
:additional_model_creation_strategy_args,
|
33
|
+
:all_attribute_overrides,
|
34
|
+
:columns,
|
35
|
+
:custom_validation?,
|
36
|
+
:model_creation_strategy,
|
37
|
+
:validation_name,
|
38
|
+
:validation_options,
|
39
|
+
:column_type,
|
40
|
+
)
|
41
|
+
|
42
|
+
def build_model_creator
|
43
|
+
model_creator = model_creation_strategy.new(
|
44
|
+
model_name,
|
45
|
+
columns,
|
46
|
+
arguments
|
47
|
+
)
|
48
|
+
|
49
|
+
model_creator.customize_model do |model|
|
50
|
+
add_validation_to(model)
|
51
|
+
possibly_override_attribute_writer_method_for(model)
|
52
|
+
end
|
53
|
+
|
54
|
+
model_creator
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_validation_to(model)
|
58
|
+
if custom_validation?
|
59
|
+
_attribute_name = attribute_name
|
60
|
+
|
61
|
+
model.send(:define_method, :custom_validation) do
|
62
|
+
custom_validation.call(self, _attribute_name)
|
63
|
+
end
|
64
|
+
|
65
|
+
model.validate(:custom_validation)
|
66
|
+
else
|
67
|
+
model.public_send(validation_name, attribute_name, validation_options)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def possibly_override_attribute_writer_method_for(model)
|
72
|
+
all_attribute_overrides.each do |attribute_name, overrides|
|
73
|
+
if overrides.key?(:changing_values_with)
|
74
|
+
_change_value = method(:change_value)
|
75
|
+
|
76
|
+
model.send(:define_method, "#{attribute_name}=") do |value|
|
77
|
+
new_value = _change_value.call(
|
78
|
+
value,
|
79
|
+
overrides[:changing_values_with]
|
80
|
+
)
|
81
|
+
|
82
|
+
if respond_to?(:write_attribute)
|
83
|
+
write_attribute(new_value)
|
84
|
+
else
|
85
|
+
super(new_value)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def change_value(value, value_changer)
|
93
|
+
UnitTests::ChangeValue.call(column_type, value, value_changer)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -25,9 +25,8 @@ module UnitTests
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def attribute_to_confirm
|
28
|
-
:attribute_to_confirm
|
28
|
+
options.fetch(:attribute, :attribute_to_confirm)
|
29
29
|
end
|
30
|
-
alias_method :attribute, :attribute_to_confirm
|
31
30
|
|
32
31
|
def confirmation_attribute
|
33
32
|
:"#{attribute_to_confirm}_confirmation"
|
@@ -44,11 +43,8 @@ module UnitTests
|
|
44
43
|
private
|
45
44
|
|
46
45
|
def create_model
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
define_model(model_name, _attribute => :string) do
|
51
|
-
validates_confirmation_of(_attribute, _options)
|
46
|
+
define_model(model_name, attribute_to_confirm => :string) do |model|
|
47
|
+
model.validates_confirmation_of(attribute_to_confirm, options)
|
52
48
|
end
|
53
49
|
end
|
54
50
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
shared_examples_for 'ignoring_interference_by_writer' do |common_config|
|
2
|
+
valid_tests = [
|
3
|
+
:accept_if_qualified_but_changing_value_does_not_interfere,
|
4
|
+
:reject_if_qualified_but_changing_value_interferes
|
5
|
+
]
|
6
|
+
tests = common_config.fetch(:tests)
|
7
|
+
tests.assert_valid_keys(valid_tests)
|
8
|
+
|
9
|
+
define_method(:common_config) { common_config }
|
10
|
+
|
11
|
+
context 'when the writer method for the attribute changes incoming values' do
|
12
|
+
context 'and the value change does not cause a test failure' do
|
13
|
+
config_for_test = tests[:accept_if_qualified_but_changing_value_does_not_interfere]
|
14
|
+
|
15
|
+
if config_for_test
|
16
|
+
it 'accepts (and does not raise an error)' do
|
17
|
+
args = build_args(config_for_test)
|
18
|
+
scenario = build_scenario_for_validation_matcher(args)
|
19
|
+
matcher = matcher_from(scenario)
|
20
|
+
|
21
|
+
expect(scenario.record).to matcher
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'and the value change causes a test failure' do
|
27
|
+
config_for_test = tests[:reject_if_qualified_but_changing_value_interferes]
|
28
|
+
|
29
|
+
if config_for_test
|
30
|
+
it 'lists how the value got changed in the failure message' do
|
31
|
+
args = build_args(config_for_test)
|
32
|
+
scenario = build_scenario_for_validation_matcher(args)
|
33
|
+
matcher = matcher_from(scenario)
|
34
|
+
|
35
|
+
assertion = lambda do
|
36
|
+
expect(scenario.record).to matcher
|
37
|
+
end
|
38
|
+
|
39
|
+
if config_for_test.key?(:expected_message_includes)
|
40
|
+
message = config_for_test[:expected_message_includes]
|
41
|
+
expect(&assertion).to fail_with_message_including(message)
|
42
|
+
else
|
43
|
+
message = config_for_test.fetch(:expected_message)
|
44
|
+
expect(&assertion).to fail_with_message(message)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def build_args(config_for_test)
|
52
|
+
args_from_common_config.merge(args_from_config_for_test(config_for_test))
|
53
|
+
end
|
54
|
+
|
55
|
+
def args_from_common_config
|
56
|
+
common_config.slice(
|
57
|
+
:column_type,
|
58
|
+
:model_creator,
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
def args_from_config_for_test(config)
|
63
|
+
config.slice(
|
64
|
+
:attribute_name,
|
65
|
+
:attribute_overrides,
|
66
|
+
:changing_values_with,
|
67
|
+
:default_value,
|
68
|
+
:model_name,
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
def matcher_from(scenario)
|
73
|
+
scenario.matcher.tap do |matcher|
|
74
|
+
if respond_to?(:configure_validation_matcher)
|
75
|
+
configure_validation_matcher(matcher)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|