shoulda-matchers 3.0.1 → 3.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/.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
@@ -3,13 +3,20 @@ module Shoulda
|
|
3
3
|
module ActiveModel
|
4
4
|
# @private
|
5
5
|
class ValidationMatcher
|
6
|
-
|
6
|
+
include Qualifiers::IgnoringInterferenceByWriter
|
7
7
|
|
8
8
|
def initialize(attribute)
|
9
|
+
super
|
9
10
|
@attribute = attribute
|
10
|
-
@
|
11
|
-
@
|
12
|
-
@
|
11
|
+
@expects_strict = false
|
12
|
+
@subject = nil
|
13
|
+
@last_submatcher_run = nil
|
14
|
+
@expected_message = nil
|
15
|
+
@expects_custom_validation_message = false
|
16
|
+
end
|
17
|
+
|
18
|
+
def description
|
19
|
+
ValidationMatcher::BuildDescription.call(self, simple_description)
|
13
20
|
end
|
14
21
|
|
15
22
|
def on(context)
|
@@ -18,12 +25,25 @@ module Shoulda
|
|
18
25
|
end
|
19
26
|
|
20
27
|
def strict
|
21
|
-
@
|
28
|
+
@expects_strict = true
|
22
29
|
self
|
23
30
|
end
|
24
31
|
|
25
|
-
def
|
26
|
-
@
|
32
|
+
def expects_strict?
|
33
|
+
@expects_strict
|
34
|
+
end
|
35
|
+
|
36
|
+
def with_message(expected_message)
|
37
|
+
if expected_message
|
38
|
+
@expects_custom_validation_message = true
|
39
|
+
@expected_message = expected_message
|
40
|
+
end
|
41
|
+
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
def expects_custom_validation_message?
|
46
|
+
@expects_custom_validation_message
|
27
47
|
end
|
28
48
|
|
29
49
|
def matches?(subject)
|
@@ -31,66 +51,108 @@ module Shoulda
|
|
31
51
|
false
|
32
52
|
end
|
33
53
|
|
34
|
-
|
54
|
+
def failure_message
|
55
|
+
overall_failure_message.dup.tap do |message|
|
56
|
+
if failure_reason.present?
|
57
|
+
message << "\n"
|
58
|
+
message << Shoulda::Matchers.word_wrap(
|
59
|
+
failure_reason,
|
60
|
+
indent: 2
|
61
|
+
)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
35
65
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
false
|
66
|
+
def failure_message_when_negated
|
67
|
+
overall_failure_message_when_negated.dup.tap do |message|
|
68
|
+
if failure_reason_when_negated.present?
|
69
|
+
message << "\n"
|
70
|
+
message << Shoulda::Matchers.word_wrap(
|
71
|
+
failure_reason_when_negated,
|
72
|
+
indent: 2
|
73
|
+
)
|
74
|
+
end
|
46
75
|
end
|
47
76
|
end
|
48
77
|
|
78
|
+
protected
|
79
|
+
|
80
|
+
attr_reader :attribute, :context, :subject, :last_submatcher_run
|
81
|
+
|
82
|
+
def model
|
83
|
+
subject.class
|
84
|
+
end
|
85
|
+
|
86
|
+
def allows_value_of(value, message = nil, &block)
|
87
|
+
matcher = allow_value_matcher(value, message, &block)
|
88
|
+
run_allow_or_disallow_matcher(matcher)
|
89
|
+
end
|
90
|
+
|
49
91
|
def disallows_value_of(value, message = nil, &block)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
if disallow.matches?(@subject)
|
54
|
-
@failure_message_when_negated = disallow.failure_message_when_negated
|
55
|
-
true
|
56
|
-
else
|
57
|
-
@failure_message = disallow.failure_message
|
58
|
-
false
|
59
|
-
end
|
92
|
+
matcher = disallow_value_matcher(value, message, &block)
|
93
|
+
run_allow_or_disallow_matcher(matcher)
|
60
94
|
end
|
61
95
|
|
62
|
-
def allow_value_matcher(value, message)
|
63
|
-
|
64
|
-
|
96
|
+
def allow_value_matcher(value, message = nil, &block)
|
97
|
+
build_allow_or_disallow_value_matcher(
|
98
|
+
matcher_class: AllowValueMatcher,
|
99
|
+
value: value,
|
100
|
+
message: message,
|
101
|
+
&block
|
102
|
+
)
|
103
|
+
end
|
65
104
|
|
66
|
-
|
67
|
-
|
68
|
-
|
105
|
+
def disallow_value_matcher(value, message = nil, &block)
|
106
|
+
build_allow_or_disallow_value_matcher(
|
107
|
+
matcher_class: DisallowValueMatcher,
|
108
|
+
value: value,
|
109
|
+
message: message,
|
110
|
+
&block
|
111
|
+
)
|
112
|
+
end
|
69
113
|
|
70
|
-
|
71
|
-
matcher.strict
|
72
|
-
end
|
114
|
+
private
|
73
115
|
|
74
|
-
|
116
|
+
def overall_failure_message
|
117
|
+
Shoulda::Matchers.word_wrap(
|
118
|
+
"#{model.name} did not properly #{description}."
|
119
|
+
)
|
75
120
|
end
|
76
121
|
|
77
|
-
def
|
78
|
-
|
79
|
-
|
122
|
+
def overall_failure_message_when_negated
|
123
|
+
Shoulda::Matchers.word_wrap(
|
124
|
+
"Expected #{model.name} not to #{description}, but it did."
|
125
|
+
)
|
126
|
+
end
|
80
127
|
|
81
|
-
|
82
|
-
|
83
|
-
|
128
|
+
def failure_reason
|
129
|
+
last_submatcher_run.try(:failure_message)
|
130
|
+
end
|
84
131
|
|
85
|
-
|
86
|
-
|
87
|
-
|
132
|
+
def failure_reason_when_negated
|
133
|
+
last_submatcher_run.try(:failure_message_when_negated)
|
134
|
+
end
|
135
|
+
|
136
|
+
def build_allow_or_disallow_value_matcher(args)
|
137
|
+
matcher_class = args.fetch(:matcher_class)
|
138
|
+
value = args.fetch(:value)
|
139
|
+
message = args[:message]
|
140
|
+
|
141
|
+
matcher = matcher_class.new(value).
|
142
|
+
for(attribute).
|
143
|
+
with_message(message).
|
144
|
+
on(context).
|
145
|
+
strict(expects_strict?).
|
146
|
+
ignoring_interference_by_writer(ignore_interference_by_writer)
|
147
|
+
|
148
|
+
yield matcher if block_given?
|
88
149
|
|
89
150
|
matcher
|
90
151
|
end
|
91
152
|
|
92
|
-
def
|
93
|
-
@
|
153
|
+
def run_allow_or_disallow_matcher(matcher)
|
154
|
+
@last_submatcher_run = matcher
|
155
|
+
matcher.matches?(subject)
|
94
156
|
end
|
95
157
|
end
|
96
158
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Shoulda
|
2
|
+
module Matchers
|
3
|
+
module ActiveModel
|
4
|
+
class ValidationMatcher
|
5
|
+
# @private
|
6
|
+
class BuildDescription
|
7
|
+
def self.call(matcher, main_description)
|
8
|
+
new(matcher, main_description).call
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(matcher, main_description)
|
12
|
+
@matcher = matcher
|
13
|
+
@main_description = main_description
|
14
|
+
end
|
15
|
+
|
16
|
+
def call
|
17
|
+
if description_clauses_for_qualifiers.any?
|
18
|
+
main_description +
|
19
|
+
', ' +
|
20
|
+
description_clauses_for_qualifiers.to_sentence
|
21
|
+
else
|
22
|
+
main_description
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
attr_reader :matcher, :main_description
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def description_clauses_for_qualifiers
|
33
|
+
description_clauses = []
|
34
|
+
|
35
|
+
if matcher.try(:expects_to_allow_blank?)
|
36
|
+
description_clauses << 'but only if it is not blank'
|
37
|
+
elsif matcher.try(:expects_to_allow_nil?)
|
38
|
+
description_clauses << 'but only if it is not nil'
|
39
|
+
end
|
40
|
+
|
41
|
+
if matcher.try(:expects_strict?)
|
42
|
+
description_clauses << 'raising a validation exception'
|
43
|
+
|
44
|
+
if matcher.try(:expects_custom_validation_message?)
|
45
|
+
description_clauses.last << ' with a custom message'
|
46
|
+
end
|
47
|
+
|
48
|
+
description_clauses.last << ' on failure'
|
49
|
+
elsif matcher.try(:expects_custom_validation_message?)
|
50
|
+
description_clauses <<
|
51
|
+
'producing a custom validation error on failure'
|
52
|
+
end
|
53
|
+
|
54
|
+
description_clauses
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -5,99 +5,118 @@ module Shoulda
|
|
5
5
|
class Validator
|
6
6
|
include Helpers
|
7
7
|
|
8
|
-
|
8
|
+
def initialize(record, attribute, options = {})
|
9
|
+
@record = record
|
10
|
+
@attribute = attribute
|
11
|
+
@context = options[:context]
|
12
|
+
@expects_strict = options[:expects_strict]
|
13
|
+
@expected_message = options[:expected_message]
|
9
14
|
|
10
|
-
|
11
|
-
|
15
|
+
@_validation_result = nil
|
16
|
+
@captured_validation_exception = false
|
17
|
+
@captured_range_error = false
|
12
18
|
end
|
13
19
|
|
14
|
-
def
|
15
|
-
|
20
|
+
def call
|
21
|
+
!messages_match? && !captured_range_error?
|
16
22
|
end
|
17
23
|
|
18
|
-
def
|
19
|
-
|
24
|
+
def has_messages?
|
25
|
+
messages.any?
|
26
|
+
end
|
20
27
|
|
21
|
-
|
22
|
-
|
23
|
-
end
|
28
|
+
def captured_validation_exception?
|
29
|
+
@captured_validation_exception
|
24
30
|
end
|
25
31
|
|
26
|
-
def
|
27
|
-
|
32
|
+
def type_of_message_matched?
|
33
|
+
expects_strict? == captured_validation_exception?
|
28
34
|
end
|
29
35
|
|
30
|
-
def
|
31
|
-
|
36
|
+
def all_formatted_validation_error_messages
|
37
|
+
format_validation_errors(all_validation_errors)
|
32
38
|
end
|
33
39
|
|
34
|
-
def
|
35
|
-
|
40
|
+
def validation_exception_message
|
41
|
+
validation_result[:validation_exception_message]
|
36
42
|
end
|
37
43
|
|
38
|
-
|
39
|
-
|
44
|
+
protected
|
45
|
+
|
46
|
+
attr_reader :attribute, :context, :record
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def expects_strict?
|
51
|
+
@expects_strict
|
40
52
|
end
|
41
53
|
|
42
|
-
def
|
43
|
-
|
54
|
+
def messages_match?
|
55
|
+
has_messages? &&
|
56
|
+
type_of_message_matched? &&
|
57
|
+
matched_messages.compact.any?
|
44
58
|
end
|
45
59
|
|
46
|
-
def
|
47
|
-
if
|
48
|
-
|
60
|
+
def messages
|
61
|
+
if expects_strict?
|
62
|
+
[validation_exception_message]
|
49
63
|
else
|
50
|
-
|
64
|
+
validation_error_messages
|
51
65
|
end
|
52
66
|
end
|
53
67
|
|
54
|
-
def
|
55
|
-
if expected_message
|
56
|
-
|
68
|
+
def matched_messages
|
69
|
+
if @expected_message
|
70
|
+
messages.grep(@expected_message)
|
57
71
|
else
|
58
|
-
|
72
|
+
messages
|
59
73
|
end
|
60
74
|
end
|
61
75
|
|
62
76
|
def captured_range_error?
|
63
|
-
|
77
|
+
!!@captured_range_error
|
64
78
|
end
|
65
79
|
|
66
|
-
|
67
|
-
|
68
|
-
attr_reader :attribute, :context, :strict, :record,
|
69
|
-
:captured_range_error
|
70
|
-
|
71
|
-
def collect_messages
|
72
|
-
validation_errors
|
80
|
+
def all_validation_errors
|
81
|
+
validation_result[:all_validation_errors]
|
73
82
|
end
|
74
83
|
|
75
|
-
|
76
|
-
|
77
|
-
def strict?
|
78
|
-
!!@strict
|
84
|
+
def validation_error_messages
|
85
|
+
validation_result[:validation_error_messages]
|
79
86
|
end
|
80
87
|
|
81
|
-
def
|
82
|
-
|
88
|
+
def validation_result
|
89
|
+
@_validation_result ||= perform_validation
|
83
90
|
end
|
84
91
|
|
85
|
-
def
|
92
|
+
def perform_validation
|
86
93
|
if context
|
87
94
|
record.valid?(context)
|
88
95
|
else
|
89
96
|
record.valid?
|
90
97
|
end
|
91
98
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
record.errors.
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
99
|
+
all_validation_errors = record.errors.dup
|
100
|
+
|
101
|
+
validation_error_messages =
|
102
|
+
if record.errors.respond_to?(:[])
|
103
|
+
record.errors[attribute]
|
104
|
+
else
|
105
|
+
record.errors.on(attribute)
|
106
|
+
end
|
107
|
+
|
108
|
+
{
|
109
|
+
all_validation_errors: all_validation_errors,
|
110
|
+
validation_error_messages: validation_error_messages,
|
111
|
+
validation_exception_message: nil
|
112
|
+
}
|
113
|
+
rescue ::ActiveModel::StrictValidationFailed => exception
|
114
|
+
@captured_validation_exception = true
|
115
|
+
{
|
116
|
+
all_validation_errors: nil,
|
117
|
+
validation_error_messages: [],
|
118
|
+
validation_exception_message: exception.message
|
119
|
+
}
|
101
120
|
end
|
102
121
|
end
|
103
122
|
end
|
@@ -63,8 +63,8 @@ module Shoulda
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def matches?(subject)
|
66
|
-
@
|
67
|
-
enum_defined? && enum_values_match?
|
66
|
+
@record = subject
|
67
|
+
enum_defined? && enum_values_match? && column_type_is_integer?
|
68
68
|
end
|
69
69
|
|
70
70
|
def failure_message
|
@@ -84,15 +84,17 @@ module Shoulda
|
|
84
84
|
desc << " with #{options[:expected_enum_values]}"
|
85
85
|
end
|
86
86
|
|
87
|
+
desc << " and store the value in a column with an integer type"
|
88
|
+
|
87
89
|
desc
|
88
90
|
end
|
89
91
|
|
90
92
|
protected
|
91
93
|
|
92
|
-
attr_reader :
|
94
|
+
attr_reader :record, :attribute_name, :options
|
93
95
|
|
94
96
|
def expectation
|
95
|
-
"#{model.
|
97
|
+
"#{model.name} to #{description}"
|
96
98
|
end
|
97
99
|
|
98
100
|
def expected_enum_values
|
@@ -100,7 +102,7 @@ module Shoulda
|
|
100
102
|
end
|
101
103
|
|
102
104
|
def actual_enum_values
|
103
|
-
model.
|
105
|
+
model.send(attribute_name.to_s.pluralize)
|
104
106
|
end
|
105
107
|
|
106
108
|
def enum_defined?
|
@@ -111,6 +113,18 @@ module Shoulda
|
|
111
113
|
expected_enum_values.empty? || actual_enum_values == expected_enum_values
|
112
114
|
end
|
113
115
|
|
116
|
+
def column_type_is_integer?
|
117
|
+
column.type == :integer
|
118
|
+
end
|
119
|
+
|
120
|
+
def column
|
121
|
+
model.columns_hash[attribute_name.to_s]
|
122
|
+
end
|
123
|
+
|
124
|
+
def model
|
125
|
+
record.class
|
126
|
+
end
|
127
|
+
|
114
128
|
def hashify(value)
|
115
129
|
if value.nil?
|
116
130
|
return {}
|