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
@@ -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 {}
|