mcmire-shoulda-matchers 2.5.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 +7 -0
- data/.gitignore +12 -0
- data/.travis.yml +32 -0
- data/.yardopts +7 -0
- data/Appraisals +45 -0
- data/CONTRIBUTING.md +41 -0
- data/Gemfile +31 -0
- data/Gemfile.lock +166 -0
- data/MIT-LICENSE +22 -0
- data/NEWS.md +299 -0
- data/README.md +163 -0
- data/Rakefile +116 -0
- data/doc_config/gh-pages/index.html.erb +9 -0
- data/doc_config/yard/setup.rb +22 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/bootstrap.css +5967 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/full_list.css +12 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/global.css +45 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/solarized.css +69 -0
- data/doc_config/yard/templates/default/fulldoc/html/css/style.css +283 -0
- data/doc_config/yard/templates/default/fulldoc/html/full_list.erb +32 -0
- data/doc_config/yard/templates/default/fulldoc/html/full_list_class.erb +1 -0
- data/doc_config/yard/templates/default/fulldoc/html/full_list_method.erb +8 -0
- data/doc_config/yard/templates/default/fulldoc/html/js/app.js +300 -0
- data/doc_config/yard/templates/default/fulldoc/html/js/full_list.js +1 -0
- data/doc_config/yard/templates/default/fulldoc/html/js/jquery.stickyheaders.js +289 -0
- data/doc_config/yard/templates/default/fulldoc/html/js/underscore.min.js +6 -0
- data/doc_config/yard/templates/default/fulldoc/html/setup.rb +8 -0
- data/doc_config/yard/templates/default/layout/html/breadcrumb.erb +14 -0
- data/doc_config/yard/templates/default/layout/html/fonts.erb +1 -0
- data/doc_config/yard/templates/default/layout/html/layout.erb +23 -0
- data/doc_config/yard/templates/default/layout/html/search.erb +13 -0
- data/doc_config/yard/templates/default/layout/html/setup.rb +8 -0
- data/doc_config/yard/templates/default/method_details/html/source.erb +10 -0
- data/doc_config/yard/templates/default/module/html/box_info.erb +31 -0
- data/features/rails_integration.feature +113 -0
- data/features/step_definitions/rails_steps.rb +162 -0
- data/features/support/env.rb +5 -0
- data/gemfiles/3.0.gemfile +24 -0
- data/gemfiles/3.0.gemfile.lock +150 -0
- data/gemfiles/3.1.gemfile +27 -0
- data/gemfiles/3.1.gemfile.lock +173 -0
- data/gemfiles/3.2.gemfile +27 -0
- data/gemfiles/3.2.gemfile.lock +171 -0
- data/gemfiles/4.0.0.gemfile +28 -0
- data/gemfiles/4.0.0.gemfile.lock +172 -0
- data/gemfiles/4.0.1.gemfile +28 -0
- data/gemfiles/4.0.1.gemfile.lock +172 -0
- data/lib/shoulda-matchers.rb +1 -0
- data/lib/shoulda/matchers.rb +11 -0
- data/lib/shoulda/matchers/action_controller.rb +17 -0
- data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +64 -0
- data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +97 -0
- data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +81 -0
- data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +117 -0
- data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +114 -0
- data/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +154 -0
- data/lib/shoulda/matchers/action_controller/route_matcher.rb +116 -0
- data/lib/shoulda/matchers/action_controller/route_params.rb +48 -0
- data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +164 -0
- data/lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb +296 -0
- data/lib/shoulda/matchers/active_model.rb +30 -0
- data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +167 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +314 -0
- data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +46 -0
- data/lib/shoulda/matchers/active_model/ensure_exclusion_of_matcher.rb +160 -0
- data/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb +417 -0
- data/lib/shoulda/matchers/active_model/ensure_length_of_matcher.rb +337 -0
- data/lib/shoulda/matchers/active_model/errors.rb +10 -0
- data/lib/shoulda/matchers/active_model/exception_message_finder.rb +58 -0
- data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +92 -0
- data/lib/shoulda/matchers/active_model/helpers.rb +46 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers.rb +9 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +75 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb +27 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +41 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb +27 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +26 -0
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +112 -0
- data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +77 -0
- data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +121 -0
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +380 -0
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +89 -0
- data/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb +372 -0
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +97 -0
- data/lib/shoulda/matchers/active_model/validation_message_finder.rb +69 -0
- data/lib/shoulda/matchers/active_record.rb +22 -0
- data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +204 -0
- data/lib/shoulda/matchers/active_record/association_matcher.rb +901 -0
- data/lib/shoulda/matchers/active_record/association_matchers.rb +9 -0
- data/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +41 -0
- data/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +41 -0
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +81 -0
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +65 -0
- data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +94 -0
- data/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +41 -0
- data/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +41 -0
- data/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +63 -0
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +261 -0
- data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +149 -0
- data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +72 -0
- data/lib/shoulda/matchers/active_record/serialize_matcher.rb +181 -0
- data/lib/shoulda/matchers/assertion_error.rb +19 -0
- data/lib/shoulda/matchers/error.rb +6 -0
- data/lib/shoulda/matchers/integrations/rspec.rb +20 -0
- data/lib/shoulda/matchers/integrations/test_unit.rb +30 -0
- data/lib/shoulda/matchers/rails_shim.rb +50 -0
- data/lib/shoulda/matchers/version.rb +6 -0
- data/lib/shoulda/matchers/warn.rb +8 -0
- data/shoulda-matchers.gemspec +23 -0
- data/spec/shoulda/matchers/action_controller/filter_param_matcher_spec.rb +22 -0
- data/spec/shoulda/matchers/action_controller/redirect_to_matcher_spec.rb +42 -0
- data/spec/shoulda/matchers/action_controller/render_template_matcher_spec.rb +78 -0
- data/spec/shoulda/matchers/action_controller/render_with_layout_matcher_spec.rb +63 -0
- data/spec/shoulda/matchers/action_controller/rescue_from_matcher_spec.rb +63 -0
- data/spec/shoulda/matchers/action_controller/respond_with_matcher_spec.rb +31 -0
- data/spec/shoulda/matchers/action_controller/route_matcher_spec.rb +70 -0
- data/spec/shoulda/matchers/action_controller/route_params_spec.rb +30 -0
- data/spec/shoulda/matchers/action_controller/set_session_matcher_spec.rb +51 -0
- data/spec/shoulda/matchers/action_controller/set_the_flash_matcher_spec.rb +153 -0
- data/spec/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +111 -0
- data/spec/shoulda/matchers/active_model/allow_value_matcher_spec.rb +170 -0
- data/spec/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +81 -0
- data/spec/shoulda/matchers/active_model/ensure_exclusion_of_matcher_spec.rb +95 -0
- data/spec/shoulda/matchers/active_model/ensure_inclusion_of_matcher_spec.rb +320 -0
- data/spec/shoulda/matchers/active_model/ensure_length_of_matcher_spec.rb +166 -0
- data/spec/shoulda/matchers/active_model/exception_message_finder_spec.rb +111 -0
- data/spec/shoulda/matchers/active_model/have_secure_password_matcher_spec.rb +20 -0
- data/spec/shoulda/matchers/active_model/helpers_spec.rb +158 -0
- data/spec/shoulda/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +169 -0
- data/spec/shoulda/matchers/active_model/numericality_matchers/even_number_matcher_spec.rb +59 -0
- data/spec/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher_spec.rb +59 -0
- data/spec/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher_spec.rb +57 -0
- data/spec/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +139 -0
- data/spec/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +41 -0
- data/spec/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +47 -0
- data/spec/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +331 -0
- data/spec/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +180 -0
- data/spec/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +398 -0
- data/spec/shoulda/matchers/active_model/validation_message_finder_spec.rb +127 -0
- data/spec/shoulda/matchers/active_record/accept_nested_attributes_for_matcher_spec.rb +107 -0
- data/spec/shoulda/matchers/active_record/association_matcher_spec.rb +860 -0
- data/spec/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +247 -0
- data/spec/shoulda/matchers/active_record/have_db_column_matcher_spec.rb +111 -0
- data/spec/shoulda/matchers/active_record/have_db_index_matcher_spec.rb +78 -0
- data/spec/shoulda/matchers/active_record/have_readonly_attributes_matcher_spec.rb +41 -0
- data/spec/shoulda/matchers/active_record/serialize_matcher_spec.rb +86 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/support/active_model_versions.rb +13 -0
- data/spec/support/active_resource_builder.rb +29 -0
- data/spec/support/activemodel_helpers.rb +19 -0
- data/spec/support/capture_helpers.rb +19 -0
- data/spec/support/class_builder.rb +42 -0
- data/spec/support/controller_builder.rb +74 -0
- data/spec/support/fail_with_message_including_matcher.rb +33 -0
- data/spec/support/fail_with_message_matcher.rb +32 -0
- data/spec/support/i18n_faker.rb +10 -0
- data/spec/support/mailer_builder.rb +10 -0
- data/spec/support/model_builder.rb +81 -0
- data/spec/support/rails_versions.rb +18 -0
- data/spec/support/shared_examples/numerical_submatcher.rb +19 -0
- data/spec/support/shared_examples/numerical_type_submatcher.rb +17 -0
- data/spec/support/test_application.rb +120 -0
- data/yard.watchr +5 -0
- metadata +281 -0
@@ -0,0 +1,320 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Shoulda::Matchers::ActiveModel::EnsureInclusionOfMatcher do
|
4
|
+
context 'with no validations' do
|
5
|
+
it 'rejects an array which does not have a validator defined' do
|
6
|
+
expect(define_model(:example, attr: :string).new).
|
7
|
+
not_to ensure_inclusion_of(:attr).in_array(%w(Yes No))
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'with an integer column' do
|
12
|
+
it 'can verify a zero in the array' do
|
13
|
+
model = define_model(:example, attr: :integer) do
|
14
|
+
validates_inclusion_of :attr, in: [0, 1, 2]
|
15
|
+
end.new
|
16
|
+
|
17
|
+
expect(model).to ensure_inclusion_of(:attr).in_array([0,1,2])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with an decimal column' do
|
22
|
+
it 'can verify decimal values' do
|
23
|
+
model = define_model(:example, attr: :decimal) do
|
24
|
+
validates_inclusion_of :attr, in: [0.0, 0.1]
|
25
|
+
end.new
|
26
|
+
|
27
|
+
expect(model).to ensure_inclusion_of(:attr).in_array([0.0, 0.1])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with true/false values' do
|
32
|
+
it 'can verify outside values to ensure the negative case' do
|
33
|
+
expect(define_model(:example, attr: :string).new).
|
34
|
+
not_to ensure_inclusion_of(:attr).in_array([true, false])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'where we cannot determine a value outside the array' do
|
39
|
+
it 'raises a custom exception' do
|
40
|
+
model = define_model(:example, attr: :string).new
|
41
|
+
|
42
|
+
arbitrary_string = described_class::ARBITRARY_OUTSIDE_STRING
|
43
|
+
expect { expect(model).to ensure_inclusion_of(:attr).in_array([arbitrary_string]) }.to raise_error Shoulda::Matchers::ActiveModel::CouldNotDetermineValueOutsideOfArray
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'an attribute which must be included in a range' do
|
48
|
+
it 'accepts ensuring the correct range' do
|
49
|
+
expect(validating_inclusion(in: 2..5)).
|
50
|
+
to ensure_inclusion_of(:attr).in_range(2..5)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'rejects ensuring a lower minimum value' do
|
54
|
+
expect(validating_inclusion(in: 2..5)).
|
55
|
+
not_to ensure_inclusion_of(:attr).in_range(1..5)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'rejects ensuring a higher minimum value' do
|
59
|
+
expect(validating_inclusion(in: 2..5)).
|
60
|
+
not_to ensure_inclusion_of(:attr).in_range(3..5)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'rejects ensuring a lower maximum value' do
|
64
|
+
expect(validating_inclusion(in: 2..5)).
|
65
|
+
not_to ensure_inclusion_of(:attr).in_range(2..4)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'rejects ensuring a higher maximum value' do
|
69
|
+
expect(validating_inclusion(in: 2..5)).
|
70
|
+
not_to ensure_inclusion_of(:attr).in_range(2..6)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'does not override the default message with a blank' do
|
74
|
+
expect(validating_inclusion(in: 2..5)).
|
75
|
+
to ensure_inclusion_of(:attr).in_range(2..5).with_message(nil)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'an attribute which must be included in a range with excluded end' do
|
80
|
+
it 'accepts ensuring the correct range' do
|
81
|
+
expect(validating_inclusion(in: 2...5)).
|
82
|
+
to ensure_inclusion_of(:attr).in_range(2...5)
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'rejects ensuring a lower maximum value' do
|
86
|
+
expect(validating_inclusion(in: 2...5)).
|
87
|
+
not_to ensure_inclusion_of(:attr).in_range(2...4)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'an attribute with a custom ranged value validation' do
|
92
|
+
it 'accepts ensuring the correct range' do
|
93
|
+
expect(validating_inclusion(in: 2..4, message: 'not good')).
|
94
|
+
to ensure_inclusion_of(:attr).in_range(2..4).with_message(/not good/)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'an attribute with custom range validations' do
|
99
|
+
it 'accepts ensuring the correct range and messages' do
|
100
|
+
model = custom_validation do
|
101
|
+
if attr < 2
|
102
|
+
errors.add(:attr, 'too low')
|
103
|
+
elsif attr > 5
|
104
|
+
errors.add(:attr, 'too high')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
expect(model).to ensure_inclusion_of(:attr).in_range(2..5).
|
109
|
+
with_low_message(/low/).with_high_message(/high/)
|
110
|
+
|
111
|
+
model = custom_validation do
|
112
|
+
if attr < 2
|
113
|
+
errors.add(:attr, 'too low')
|
114
|
+
elsif attr > 4
|
115
|
+
errors.add(:attr, 'too high')
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
expect(model).to ensure_inclusion_of(:attr).in_range(2...5).
|
120
|
+
with_low_message(/low/).with_high_message(/high/)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'an attribute which must be included in an array' do
|
125
|
+
it 'accepts with correct array' do
|
126
|
+
expect(validating_inclusion(in: %w(one two))).
|
127
|
+
to ensure_inclusion_of(:attr).in_array(%w(one two))
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'rejects when only part of array matches' do
|
131
|
+
expect(validating_inclusion(in: %w(one two))).
|
132
|
+
not_to ensure_inclusion_of(:attr).in_array(%w(one wrong_value))
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'rejects when array does not match at all' do
|
136
|
+
expect(validating_inclusion(in: %w(one two))).
|
137
|
+
not_to ensure_inclusion_of(:attr).in_array(%w(cat dog))
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'has correct description' do
|
141
|
+
expect(ensure_inclusion_of(:attr).in_array([true, "dog"]).description).
|
142
|
+
to eq 'ensure inclusion of attr in [true, "dog"]'
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'rejects allow_blank' do
|
146
|
+
expect(validating_inclusion(in: %w(one two))).
|
147
|
+
not_to ensure_inclusion_of(:attr).in_array(%w(one two)).allow_blank(true)
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'accepts allow_blank(false)' do
|
151
|
+
expect(validating_inclusion(in: %w(one two))).
|
152
|
+
to ensure_inclusion_of(:attr).in_array(%w(one two)).allow_blank(false)
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'rejects allow_nil' do
|
156
|
+
expect(validating_inclusion(in: %w(one two))).
|
157
|
+
not_to ensure_inclusion_of(:attr).in_array(%w(one two)).allow_nil(true)
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'accepts allow_nil(false)' do
|
161
|
+
expect(validating_inclusion(in: %w(one two))).
|
162
|
+
to ensure_inclusion_of(:attr).in_array(%w(one two)).allow_nil(false)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'with allowed blank and allowed nil' do
|
167
|
+
it 'accepts allow_blank' do
|
168
|
+
expect(validating_inclusion(in: %w(one two), allow_blank: true)).
|
169
|
+
to ensure_inclusion_of(:attr).in_array(%w(one two)).allow_blank
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'rejects allow_blank(false)' do
|
173
|
+
expect(validating_inclusion(in: %w(one two), allow_blank: true)).
|
174
|
+
not_to ensure_inclusion_of(:attr).in_array(%w(one two)).allow_blank(false)
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'accepts allow_nil' do
|
178
|
+
expect(validating_inclusion(in: %w(one two), allow_nil: true)).
|
179
|
+
to ensure_inclusion_of(:attr).in_array(%w(one two)).allow_nil
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'rejects allow_nil' do
|
183
|
+
expect(validating_inclusion(in: %w(one two), allow_nil: true)).
|
184
|
+
not_to ensure_inclusion_of(:attr).in_array(%w(one two)).allow_nil(false)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context 'an attribute allowing some blank values but not others' do
|
189
|
+
it 'rejects allow_blank' do
|
190
|
+
expect(validating_inclusion(in: ['one', 'two', ''])).
|
191
|
+
not_to ensure_inclusion_of(:attr).in_array(['one', 'two', '']).allow_blank(true)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
if active_model_3_2?
|
196
|
+
context 'a strict attribute which must be included in a range' do
|
197
|
+
it 'accepts ensuring the correct range' do
|
198
|
+
expect(validating_inclusion(in: 2..5, strict: true)).
|
199
|
+
to ensure_inclusion_of(:attr).in_range(2..5).strict
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'rejects ensuring another range' do
|
203
|
+
expect(validating_inclusion(in: 2..5, strict: true)).
|
204
|
+
not_to ensure_inclusion_of(:attr).in_range(2..6).strict
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context 'against a boolean attribute' do
|
210
|
+
context 'which is nullable' do
|
211
|
+
context 'when ensuring inclusion of true' do
|
212
|
+
it "doesn't raise an error" do
|
213
|
+
record = validating_inclusion_of_boolean_in(:attr, [true], null: true)
|
214
|
+
expect(record).to ensure_inclusion_of(:attr).in_array([true])
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
context 'when ensuring inclusion of false' do
|
219
|
+
it "doesn't raise an error" do
|
220
|
+
record = validating_inclusion_of_boolean_in(:attr, [false], null: true)
|
221
|
+
expect(record).to ensure_inclusion_of(:attr).in_array([false])
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
context 'when ensuring inclusion of true and false' do
|
226
|
+
it "doesn't raise an error" do
|
227
|
+
record = validating_inclusion_of_boolean_in(:attr, [true, false], null: true)
|
228
|
+
capture(:stderr) do
|
229
|
+
expect(record).to ensure_inclusion_of(:attr).in_array([true, false])
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'prints a warning' do
|
234
|
+
record = validating_inclusion_of_boolean_in(:attr, [true, false], null: true)
|
235
|
+
stderr = capture(:stderr) do
|
236
|
+
expect(record).to ensure_inclusion_of(:attr).in_array([true, false])
|
237
|
+
end
|
238
|
+
expect(stderr.gsub(/\n+/, ' ')).
|
239
|
+
to include('You are using `ensure_inclusion_of` to assert that a boolean column allows boolean values and disallows non-boolean ones')
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
context 'when ensuring inclusion of nil' do
|
244
|
+
it "doesn't raise an error" do
|
245
|
+
record = validating_inclusion_of_boolean_in(:attr, [nil], null: true)
|
246
|
+
capture(:stderr) do
|
247
|
+
expect(record).to ensure_inclusion_of(:attr).in_array([nil])
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'prints a warning' do
|
252
|
+
record = validating_inclusion_of_boolean_in(:attr, [nil], null: true)
|
253
|
+
stderr = capture(:stderr) do
|
254
|
+
expect(record).to ensure_inclusion_of(:attr).in_array([nil])
|
255
|
+
end
|
256
|
+
expect(stderr.gsub(/\n+/, ' ')).
|
257
|
+
to include('You are using `ensure_inclusion_of` to assert that a boolean column allows nil')
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
context 'which is non-nullable' do
|
263
|
+
context 'when ensuring inclusion of true' do
|
264
|
+
it "doesn't raise an error" do
|
265
|
+
record = validating_inclusion_of_boolean_in(:attr, [true], null: false)
|
266
|
+
expect(record).to ensure_inclusion_of(:attr).in_array([true])
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
context 'when ensuring inclusion of false' do
|
271
|
+
it "doesn't raise an error" do
|
272
|
+
record = validating_inclusion_of_boolean_in(:attr, [false], null: false)
|
273
|
+
expect(record).to ensure_inclusion_of(:attr).in_array([false])
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
context 'when ensuring inclusion of true and false' do
|
278
|
+
it "doesn't raise an error" do
|
279
|
+
record = validating_inclusion_of_boolean_in(:attr, [true, false], null: false)
|
280
|
+
capture(:stderr) do
|
281
|
+
expect(record).to ensure_inclusion_of(:attr).in_array([true, false])
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
it 'prints a warning' do
|
286
|
+
record = validating_inclusion_of_boolean_in(:attr, [true, false], null: false)
|
287
|
+
stderr = capture(:stderr) do
|
288
|
+
expect(record).to ensure_inclusion_of(:attr).in_array([true, false])
|
289
|
+
end
|
290
|
+
expect(stderr.gsub(/\n+/, ' ')).
|
291
|
+
to include('You are using `ensure_inclusion_of` to assert that a boolean column allows boolean values and disallows non-boolean ones')
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
context 'when ensuring inclusion of nil' do
|
296
|
+
it 'raises a specific error' do
|
297
|
+
record = validating_inclusion_of_boolean_in(:attr, [nil], null: false)
|
298
|
+
error_class = Shoulda::Matchers::ActiveModel::NonNullableBooleanError
|
299
|
+
expect {
|
300
|
+
expect(record).to ensure_inclusion_of(:attr).in_array([nil])
|
301
|
+
}.to raise_error(error_class)
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def validating_inclusion(options)
|
308
|
+
define_model(:example, attr: :string) do
|
309
|
+
validates_inclusion_of :attr, options
|
310
|
+
end.new
|
311
|
+
end
|
312
|
+
|
313
|
+
def validating_inclusion_of_boolean_in(attribute, values, options = {})
|
314
|
+
null = options.fetch(:null, true)
|
315
|
+
column_options = { type: :boolean, options: { null: null } }
|
316
|
+
define_model(:example, attribute => column_options) do
|
317
|
+
validates_inclusion_of attribute, in: values
|
318
|
+
end.new
|
319
|
+
end
|
320
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Shoulda::Matchers::ActiveModel::EnsureLengthOfMatcher do
|
4
|
+
context 'an attribute with a non-zero minimum length validation' do
|
5
|
+
it 'accepts ensuring the correct minimum length' do
|
6
|
+
expect(validating_length(minimum: 4)).
|
7
|
+
to ensure_length_of(:attr).is_at_least(4)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'rejects ensuring a lower minimum length with any message' do
|
11
|
+
expect(validating_length(minimum: 4)).
|
12
|
+
not_to ensure_length_of(:attr).is_at_least(3).with_short_message(/.*/)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'rejects ensuring a higher minimum length with any message' do
|
16
|
+
expect(validating_length(minimum: 4)).
|
17
|
+
not_to ensure_length_of(:attr).is_at_least(5).with_short_message(/.*/)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'does not override the default message with a blank' do
|
21
|
+
expect(validating_length(minimum: 4)).
|
22
|
+
to ensure_length_of(:attr).is_at_least(4).with_short_message(nil)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'an attribute with a minimum length validation of 0' do
|
27
|
+
it 'accepts ensuring the correct minimum length' do
|
28
|
+
expect(validating_length(minimum: 0)).
|
29
|
+
to ensure_length_of(:attr).is_at_least(0)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'an attribute with a maximum length' do
|
34
|
+
it 'accepts ensuring the correct maximum length' do
|
35
|
+
expect(validating_length(maximum: 4)).
|
36
|
+
to ensure_length_of(:attr).is_at_most(4)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'rejects ensuring a lower maximum length with any message' do
|
40
|
+
expect(validating_length(maximum: 4)).
|
41
|
+
not_to ensure_length_of(:attr).is_at_most(3).with_long_message(/.*/)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'rejects ensuring a higher maximum length with any message' do
|
45
|
+
expect(validating_length(maximum: 4)).
|
46
|
+
not_to ensure_length_of(:attr).is_at_most(5).with_long_message(/.*/)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'does not override the default message with a blank' do
|
50
|
+
expect(validating_length(maximum: 4)).
|
51
|
+
to ensure_length_of(:attr).is_at_most(4).with_long_message(nil)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'an attribute with a required exact length' do
|
56
|
+
it 'accepts ensuring the correct length' do
|
57
|
+
expect(validating_length(is: 4)).to ensure_length_of(:attr).is_equal_to(4)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'rejects ensuring a lower maximum length with any message' do
|
61
|
+
expect(validating_length(is: 4)).
|
62
|
+
not_to ensure_length_of(:attr).is_equal_to(3).with_message(/.*/)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'rejects ensuring a higher maximum length with any message' do
|
66
|
+
expect(validating_length(is: 4)).
|
67
|
+
not_to ensure_length_of(:attr).is_equal_to(5).with_message(/.*/)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'does not override the default message with a blank' do
|
71
|
+
expect(validating_length(is: 4)).
|
72
|
+
to ensure_length_of(:attr).is_equal_to(4).with_message(nil)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'an attribute with a required exact length and another validation' do
|
77
|
+
it 'accepts ensuring the correct length' do
|
78
|
+
model = define_model(:example, attr: :string) do
|
79
|
+
validates_length_of :attr, is: 4
|
80
|
+
validates_numericality_of :attr
|
81
|
+
end.new
|
82
|
+
|
83
|
+
expect(model).to ensure_length_of(:attr).is_equal_to(4)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'an attribute with a custom minimum length validation' do
|
88
|
+
it 'accepts ensuring the correct minimum length' do
|
89
|
+
expect(validating_length(minimum: 4, too_short: 'foobar')).
|
90
|
+
to ensure_length_of(:attr).is_at_least(4).with_short_message(/foo/)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'an attribute with a custom maximum length validation' do
|
95
|
+
it 'accepts ensuring the correct minimum length' do
|
96
|
+
expect(validating_length(maximum: 4, too_long: 'foobar')).
|
97
|
+
to ensure_length_of(:attr).is_at_most(4).with_long_message(/foo/)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'an attribute with a custom equal validation' do
|
102
|
+
it 'accepts ensuring the correct exact length' do
|
103
|
+
expect(validating_length(is: 4, message: 'foobar')).
|
104
|
+
to ensure_length_of(:attr).is_equal_to(4).with_message(/foo/)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'an attribute without a length validation' do
|
109
|
+
it 'rejects ensuring a minimum length' do
|
110
|
+
expect(define_model(:example, attr: :string).new).
|
111
|
+
not_to ensure_length_of(:attr).is_at_least(1)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'using translations' do
|
116
|
+
after { I18n.backend.reload! }
|
117
|
+
|
118
|
+
context "a too_long translation containing %{attribute}, %{model}" do
|
119
|
+
before do
|
120
|
+
stub_translation(
|
121
|
+
"activerecord.errors.messages.too_long",
|
122
|
+
"The %{attribute} of your %{model} is too long (maximum is %{count} characters)")
|
123
|
+
end
|
124
|
+
|
125
|
+
it "does not raise an exception" do
|
126
|
+
expect {
|
127
|
+
expect(validating_length(maximum: 4)).to ensure_length_of(:attr).is_at_most(4)
|
128
|
+
}.to_not raise_exception
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context "a too_short translation containing %{attribute}, %{model}" do
|
133
|
+
before do
|
134
|
+
stub_translation(
|
135
|
+
"activerecord.errors.messages.too_short",
|
136
|
+
"The %{attribute} of your %{model} is too short (minimum is %{count} characters)")
|
137
|
+
end
|
138
|
+
|
139
|
+
it "does not raise an exception" do
|
140
|
+
expect {
|
141
|
+
expect(validating_length(minimum: 4)).to ensure_length_of(:attr).is_at_least(4)
|
142
|
+
}.to_not raise_exception
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context "a wrong_length translation containing %{attribute}, %{model}" do
|
147
|
+
before do
|
148
|
+
stub_translation(
|
149
|
+
"activerecord.errors.messages.wrong_length",
|
150
|
+
"The %{attribute} of your %{model} is the wrong length (should be %{count} characters)")
|
151
|
+
end
|
152
|
+
|
153
|
+
it "does not raise an exception" do
|
154
|
+
expect {
|
155
|
+
expect(validating_length(is: 4)).to ensure_length_of(:attr).is_equal_to(4)
|
156
|
+
}.to_not raise_exception
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def validating_length(options = {})
|
162
|
+
define_model(:example, attr: :string) do
|
163
|
+
validates_length_of :attr, options
|
164
|
+
end.new
|
165
|
+
end
|
166
|
+
end
|