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.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +3 -3
  4. data/CONTRIBUTING.md +60 -28
  5. data/Gemfile +1 -0
  6. data/Gemfile.lock +15 -12
  7. data/NEWS.md +111 -0
  8. data/README.md +94 -6
  9. data/Rakefile +10 -8
  10. data/custom_plan.rb +88 -0
  11. data/gemfiles/4.0.0.gemfile +1 -0
  12. data/gemfiles/4.0.0.gemfile.lock +21 -18
  13. data/gemfiles/4.0.1.gemfile +1 -0
  14. data/gemfiles/4.0.1.gemfile.lock +21 -18
  15. data/gemfiles/4.1.gemfile +1 -0
  16. data/gemfiles/4.1.gemfile.lock +21 -18
  17. data/gemfiles/4.2.gemfile +1 -0
  18. data/gemfiles/4.2.gemfile.lock +24 -21
  19. data/lib/shoulda/matchers/action_controller/permit_matcher.rb +6 -11
  20. data/lib/shoulda/matchers/active_model.rb +10 -1
  21. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +258 -180
  22. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb +45 -0
  23. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_does_not_exist_error.rb +23 -0
  24. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +236 -0
  25. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator.rb +62 -0
  26. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters.rb +40 -0
  27. data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb +48 -0
  28. data/lib/shoulda/matchers/active_model/allow_value_matcher/successful_check.rb +14 -0
  29. data/lib/shoulda/matchers/active_model/allow_value_matcher/successful_setting.rb +14 -0
  30. data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +34 -14
  31. data/lib/shoulda/matchers/active_model/helpers.rb +9 -17
  32. data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +13 -6
  33. data/lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb +13 -2
  34. data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +19 -35
  35. data/lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb +13 -2
  36. data/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +12 -2
  37. data/lib/shoulda/matchers/active_model/qualifiers.rb +12 -0
  38. data/lib/shoulda/matchers/active_model/qualifiers/ignore_interference_by_writer.rb +101 -0
  39. data/lib/shoulda/matchers/active_model/qualifiers/ignoring_interference_by_writer.rb +21 -0
  40. data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +30 -32
  41. data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +5 -8
  42. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +22 -22
  43. data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +27 -16
  44. data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +58 -15
  45. data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +22 -12
  46. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +165 -87
  47. data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +7 -9
  48. data/lib/shoulda/matchers/active_model/validation_matcher.rb +111 -49
  49. data/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +60 -0
  50. data/lib/shoulda/matchers/active_model/validator.rb +71 -52
  51. data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +19 -5
  52. data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +450 -124
  53. data/lib/shoulda/matchers/util.rb +43 -0
  54. data/lib/shoulda/matchers/util/word_wrap.rb +59 -31
  55. data/lib/shoulda/matchers/version.rb +1 -1
  56. data/script/update_gem_in_all_appraisals +1 -1
  57. data/script/update_gems_in_all_appraisals +1 -1
  58. data/spec/acceptance/multiple_libraries_integration_spec.rb +5 -2
  59. data/spec/acceptance/rails_integration_spec.rb +6 -2
  60. data/spec/spec_helper.rb +1 -3
  61. data/spec/support/acceptance/helpers/step_helpers.rb +4 -1
  62. data/spec/support/tests/current_bundle.rb +21 -7
  63. data/spec/support/unit/active_record/create_table.rb +54 -0
  64. data/spec/support/unit/attribute.rb +47 -0
  65. data/spec/support/unit/capture.rb +6 -0
  66. data/spec/support/unit/change_value.rb +111 -0
  67. data/spec/support/unit/create_model_arguments/basic.rb +135 -0
  68. data/spec/support/unit/create_model_arguments/has_many.rb +15 -0
  69. data/spec/support/unit/create_model_arguments/uniqueness_matcher.rb +74 -0
  70. data/spec/support/unit/helpers/active_record_versions.rb +1 -1
  71. data/spec/support/unit/helpers/class_builder.rb +61 -47
  72. data/spec/support/unit/helpers/database_helpers.rb +5 -3
  73. data/spec/support/unit/helpers/model_builder.rb +77 -97
  74. data/spec/support/unit/helpers/validation_matcher_scenario_helpers.rb +44 -0
  75. data/spec/support/unit/load_environment.rb +12 -0
  76. data/spec/support/unit/matchers/fail_with_message_including_matcher.rb +2 -2
  77. data/spec/support/unit/matchers/fail_with_message_matcher.rb +12 -1
  78. data/spec/support/unit/model_creation_strategies/active_model.rb +111 -0
  79. data/spec/support/unit/model_creation_strategies/active_record.rb +77 -0
  80. data/spec/support/unit/model_creators.rb +19 -0
  81. data/spec/support/unit/model_creators/active_model.rb +39 -0
  82. data/spec/support/unit/model_creators/active_record.rb +43 -0
  83. data/spec/support/unit/model_creators/active_record/has_and_belongs_to_many.rb +95 -0
  84. data/spec/support/unit/model_creators/active_record/has_many.rb +67 -0
  85. data/spec/support/unit/model_creators/active_record/uniqueness_matcher.rb +42 -0
  86. data/spec/support/unit/model_creators/basic.rb +97 -0
  87. data/spec/support/unit/rails_application.rb +1 -1
  88. data/spec/support/unit/record_validating_confirmation_builder.rb +3 -7
  89. data/spec/support/unit/shared_examples/ignoring_interference_by_writer.rb +79 -0
  90. data/spec/support/unit/validation_matcher_scenario.rb +62 -0
  91. data/spec/unit/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +4 -0
  92. data/spec/unit/shoulda/matchers/active_model/allow_value_matcher_spec.rb +575 -140
  93. data/spec/unit/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +115 -15
  94. data/spec/unit/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +42 -4
  95. data/spec/unit/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +92 -6
  96. data/spec/unit/shoulda/matchers/active_model/validate_exclusion_of_matcher_spec.rb +122 -10
  97. data/spec/unit/shoulda/matchers/active_model/validate_inclusion_of_matcher_spec.rb +306 -58
  98. data/spec/unit/shoulda/matchers/active_model/validate_length_of_matcher_spec.rb +122 -3
  99. data/spec/unit/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +805 -131
  100. data/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +196 -29
  101. data/spec/unit/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb +82 -40
  102. data/spec/unit/shoulda/matchers/active_record/validate_uniqueness_of_matcher_spec.rb +600 -101
  103. data/spec/unit/shoulda/matchers/util/word_wrap_spec.rb +88 -33
  104. data/spec/unit_spec_helper.rb +10 -22
  105. data/zeus.json +11 -0
  106. metadata +64 -23
  107. data/lib/shoulda/matchers/active_model/strict_validator.rb +0 -51
  108. data/spec/support/unit/shared_examples/numerical_type_submatcher.rb +0 -15
  109. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +0 -288
  110. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/even_number_matcher_spec.rb +0 -100
  111. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher_spec.rb +0 -100
  112. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher_spec.rb +0 -100
@@ -1,51 +0,0 @@
1
- module Shoulda
2
- module Matchers
3
- module ActiveModel
4
- # @private
5
- module StrictValidator
6
- def allow_description(allowed_values)
7
- "doesn't raise when #{attribute} is set to #{allowed_values}"
8
- end
9
-
10
- def expected_message_from(attribute_message)
11
- "#{human_attribute_name} #{attribute_message}"
12
- end
13
-
14
- def formatted_messages
15
- [messages.first.message]
16
- end
17
-
18
- def messages_description
19
- if has_messages?
20
- ': ' + messages.first.message.inspect
21
- else
22
- ' no exception'
23
- end
24
- end
25
-
26
- def expected_messages_description(expected_message)
27
- if expected_message
28
- "exception to include #{expected_message.inspect}"
29
- else
30
- 'an exception to have been raised'
31
- end
32
- end
33
-
34
- protected
35
-
36
- def collect_messages
37
- validation_exceptions
38
- end
39
-
40
- private
41
-
42
- def validation_exceptions
43
- record.valid?(context)
44
- []
45
- rescue ::ActiveModel::StrictValidationFailed => exception
46
- [exception]
47
- end
48
- end
49
- end
50
- end
51
- end
@@ -1,15 +0,0 @@
1
- shared_examples 'a numerical type submatcher' do
2
- it 'implements the allowed_type method' do
3
- expect(subject).to respond_to(:allowed_type).with(0).arguments
4
- expect { subject.allowed_type }.not_to raise_error
5
- end
6
-
7
- it 'implements the diff_to_compare' do
8
- expect(subject).to respond_to(:diff_to_compare).with(0).arguments
9
- expect { subject.diff_to_compare }.not_to raise_error
10
- end
11
-
12
- it 'returns itself when given a message' do
13
- expect(subject.with_message('some message')).to eq subject
14
- end
15
- end
@@ -1,288 +0,0 @@
1
- require 'unit_spec_helper'
2
-
3
- describe Shoulda::Matchers::ActiveModel::NumericalityMatchers::ComparisonMatcher do
4
- it_behaves_like 'a numerical submatcher' do
5
- subject { build_matcher }
6
- end
7
-
8
- shared_examples_for 'strict qualifier' do
9
- context 'asserting strict validation when validating strictly' do
10
- it 'accepts' do
11
- record = instance_with_validations(
12
- validation_qualifier => 1,
13
- strict: true
14
- )
15
- matcher = build_matcher(operator: operator, value: 1).strict
16
- expect(record).to matcher
17
- end
18
- end
19
-
20
- context 'asserting non-strict validation when validating strictly' do
21
- it 'rejects' do
22
- pending 'This needs to be fixed'
23
- record = instance_with_validations(
24
- validation_qualifier => 1,
25
- strict: true
26
- )
27
- matcher = build_matcher(operator: operator, value: 1)
28
- expect(record).not_to matcher
29
- end
30
- end
31
-
32
- context 'asserting strict validation when not validating strictly' do
33
- it 'rejects' do
34
- record = instance_with_validations(validation_qualifier => 1)
35
- matcher = build_matcher(operator: operator, value: 1).strict
36
- expect(record).not_to matcher
37
- end
38
- end
39
- end
40
-
41
- context 'when initialized without correct numerical matcher' do
42
- it 'raises an ArgumentError' do
43
- numericality_matcher = double
44
- expect { described_class.new(numericality_matcher, 0, :>) }.
45
- to raise_error(ArgumentError)
46
- end
47
- end
48
-
49
- describe 'is_greater_than' do
50
- include_examples 'strict qualifier'
51
-
52
- it do
53
- record = instance_with_validations(greater_than: 1.5)
54
- matcher = build_matcher(operator: :>, value: 2)
55
- expect(record).not_to matcher
56
- end
57
-
58
- it do
59
- record = instance_with_validations(greater_than: 2)
60
- matcher = build_matcher(operator: :>, value: 2)
61
- expect(record).to matcher
62
- end
63
-
64
- it do
65
- record = instance_with_validations(greater_than: 2.5)
66
- matcher = build_matcher(operator: :>, value: 2)
67
- expect(record).not_to matcher
68
- end
69
-
70
- it do
71
- record = instance_without_validations
72
- matcher = build_matcher(operator: :>, value: 2)
73
- expect(record).not_to matcher
74
- end
75
-
76
- def operator
77
- :>
78
- end
79
-
80
- def validation_qualifier
81
- :greater_than
82
- end
83
- end
84
-
85
- describe 'is_greater_than_or_equal_to' do
86
- include_examples 'strict qualifier'
87
-
88
- it do
89
- record = instance_with_validations(greater_than_or_equal_to: 1.5)
90
- matcher = build_matcher(operator: :>=, value: 2)
91
- expect(record).not_to matcher
92
- end
93
-
94
- it do
95
- record = instance_with_validations(greater_than_or_equal_to: 2)
96
- matcher = build_matcher(operator: :>=, value: 2)
97
- expect(record).to matcher
98
- end
99
-
100
- it do
101
- record = instance_with_validations(greater_than_or_equal_to: 2.5)
102
- matcher = build_matcher(operator: :>=, value: 2)
103
- expect(record).not_to matcher
104
- end
105
-
106
- it do
107
- record = instance_without_validations
108
- matcher = build_matcher(operator: :>=, value: 2)
109
- expect(record).not_to matcher
110
- end
111
-
112
- def operator
113
- :>=
114
- end
115
-
116
- def validation_qualifier
117
- :greater_than_or_equal_to
118
- end
119
- end
120
-
121
- describe 'is_less_than' do
122
- include_examples 'strict qualifier'
123
-
124
- it do
125
- record = instance_with_validations(less_than: 1.5)
126
- matcher = build_matcher(operator: :<, value: 2)
127
- expect(record).not_to matcher
128
- end
129
-
130
- it do
131
- record = instance_with_validations(less_than: 2)
132
- matcher = build_matcher(operator: :<, value: 2)
133
- expect(record).to matcher
134
- end
135
-
136
- it do
137
- record = instance_with_validations(less_than: 2.5)
138
- matcher = build_matcher(operator: :<, value: 2)
139
- expect(record).not_to matcher
140
- end
141
-
142
- it do
143
- record = instance_without_validations
144
- matcher = build_matcher(operator: :<, value: 2)
145
- expect(record).not_to matcher
146
- end
147
-
148
- def operator
149
- :<
150
- end
151
-
152
- def validation_qualifier
153
- :less_than
154
- end
155
- end
156
-
157
- describe 'is_less_than_or_equal_to' do
158
- include_examples 'strict qualifier'
159
-
160
- it do
161
- record = instance_with_validations(less_than_or_equal_to: 1.5)
162
- matcher = build_matcher(operator: :<=, value: 2)
163
- expect(record).not_to matcher
164
- end
165
-
166
- it do
167
- record = instance_with_validations(less_than_or_equal_to: 2)
168
- matcher = build_matcher(operator: :<=, value: 2)
169
- expect(record).to matcher
170
- end
171
-
172
- it do
173
- record = instance_with_validations(less_than_or_equal_to: 2.5)
174
- matcher = build_matcher(operator: :<=, value: 2)
175
- expect(record).not_to matcher
176
- end
177
-
178
- it do
179
- record = instance_without_validations
180
- matcher = build_matcher(operator: :<=, value: 2)
181
- expect(record).not_to matcher
182
- end
183
-
184
- def operator
185
- :<=
186
- end
187
-
188
- def validation_qualifier
189
- :less_than_or_equal_to
190
- end
191
- end
192
-
193
- describe 'is_equal_to' do
194
- include_examples 'strict qualifier'
195
-
196
- it do
197
- record = instance_with_validations(equal_to: 1.5)
198
- matcher = build_matcher(operator: :==, value: 2)
199
- expect(record).not_to matcher
200
- end
201
-
202
- it do
203
- record = instance_with_validations(equal_to: 2)
204
- matcher = build_matcher(operator: :==, value: 2)
205
- expect(record).to matcher
206
- end
207
-
208
- it do
209
- record = instance_with_validations(equal_to: 2.5)
210
- matcher = build_matcher(operator: :==, value: 2)
211
- expect(record).not_to matcher
212
- end
213
-
214
- it do
215
- record = instance_without_validations
216
- matcher = build_matcher(operator: :==, value: 2)
217
- expect(record).not_to matcher
218
- end
219
-
220
- def operator
221
- :==
222
- end
223
-
224
- def validation_qualifier
225
- :equal_to
226
- end
227
- end
228
-
229
- describe 'with_message' do
230
- it 'verifies the message for the validation' do
231
- instance = instance_with_validations(equal_to: 0, message: 'Must be zero')
232
- matcher = build_matcher.with_message('Must be zero')
233
- expect(instance).to matcher
234
- end
235
- end
236
-
237
- describe '#comparison_description' do
238
- tests = [
239
- { operator: :>, value: 0, expectation: 'greater than 0' },
240
- { operator: :>=, value: -1.0, expectation: 'greater than or equal to -1.0' },
241
- { operator: :==, value: 2.2, expectation: 'equal to 2.2' },
242
- { operator: :<, value: -3, expectation: 'less than -3' },
243
- { operator: :<=, value: 4, expectation: 'less than or equal to 4' },
244
- ]
245
-
246
- tests.each do |test|
247
- context "with :#{test[:operator]} as operator and #{test[:value]} as value" do
248
- it do
249
- matcher = build_matcher(operator: test[:operator], value: test[:value])
250
- expect(matcher.comparison_description).to eq test[:expectation]
251
- end
252
- end
253
- end
254
- end
255
-
256
- def model_with_validations(options = {})
257
- define_model :example, attribute_name => :string do |model|
258
- model.validates_numericality_of(attribute_name, options)
259
- model.attr_accessible(attribute_name)
260
- end
261
- end
262
-
263
- def instance_with_validations(options = {})
264
- model_with_validations(options).new(attribute_name => '1')
265
- end
266
-
267
- def model_without_validations
268
- define_model :example, attribute_name => :string do |model|
269
- model.attr_accessible(attribute_name)
270
- end
271
- end
272
-
273
- def instance_without_validations
274
- model_without_validations.new
275
- end
276
-
277
- def attribute_name
278
- :attr
279
- end
280
-
281
- def build_matcher(operator: :==, value: 0)
282
- described_class.new(numericality_matcher, value, operator).for(attribute_name)
283
- end
284
-
285
- def numericality_matcher
286
- double(diff_to_compare: 1, given_numeric_column?: nil)
287
- end
288
- end
@@ -1,100 +0,0 @@
1
- require 'unit_spec_helper'
2
-
3
- describe Shoulda::Matchers::ActiveModel::NumericalityMatchers::EvenNumberMatcher do
4
- subject { described_class.new(numericality_matcher, :attr) }
5
-
6
- it_behaves_like 'a numerical submatcher'
7
- it_behaves_like 'a numerical type submatcher'
8
-
9
- it 'allows even number' do
10
- expect(subject.allowed_type).to eq 'even numbers'
11
- end
12
-
13
- describe '#diff_to_compare' do
14
- it { expect(subject.diff_to_compare).to eq 2 }
15
- end
16
-
17
- context 'when the model has an even validation' do
18
- it 'matches' do
19
- match = subject
20
- expect(validating_even_number).to match
21
- end
22
- end
23
-
24
- context 'when the model does not have an even validation' do
25
- it 'does not match' do
26
- match = subject
27
- expect(not_validating_even_number).not_to match
28
- end
29
-
30
- it 'fails with the ActiveRecord :even message' do
31
- match = subject
32
- expect {
33
- expect(not_validating_even_number).to match
34
- }.to fail_with_message_including('Expected errors to include "must be even"')
35
- end
36
- end
37
-
38
- context 'with custom validation message' do
39
- it 'only accepts even number values for that attribute with that message' do
40
- expect(validating_even_number(message: 'custom')).to subject.with_message(/custom/)
41
- end
42
-
43
- it 'fails even number values for that attribute with another message' do
44
- expect(validating_even_number(message: 'custom')).not_to subject.with_message(/wrong/)
45
- end
46
- end
47
-
48
- context 'asserting strict validation when validating strictly' do
49
- it 'accepts' do
50
- expect(validating_even_number(strict: true)).to subject.strict
51
- end
52
- end
53
-
54
- context 'asserting non-strict validation when validating strictly' do
55
- it 'rejects' do
56
- pending 'This needs to be fixed'
57
- expect(validating_even_number(strict: true)).not_to subject
58
- end
59
- end
60
-
61
- context 'asserting strict validation when not validating strictly' do
62
- it 'rejects' do
63
- expect(validating_even_number).not_to subject.strict
64
- end
65
- end
66
-
67
- context 'qualified with on and validating with on' do
68
- it 'accepts' do
69
- expect(validating_even_number(on: :customizable)).
70
- to subject.on(:customizable)
71
- end
72
- end
73
-
74
- context 'qualified with on but not validating with on' do
75
- it 'accepts since the validation never considers a context' do
76
- expect(validating_even_number).to subject.on(:customizable)
77
- end
78
- end
79
-
80
- context 'not qualified with on but validating with on' do
81
- it 'rejects since the validation never runs' do
82
- expect(validating_even_number(on: :customizable)).
83
- not_to subject
84
- end
85
- end
86
-
87
- def numericality_matcher
88
- double(:numericality_matcher, given_numeric_column?: nil)
89
- end
90
-
91
- def validating_even_number(options = {})
92
- define_model :example, attr: :string do
93
- validates_numericality_of :attr, { even: true }.merge(options)
94
- end.new
95
- end
96
-
97
- def not_validating_even_number
98
- define_model(:example, attr: :string).new
99
- end
100
- end