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.
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
@@ -9,11 +9,49 @@ describe Shoulda::Matchers::ActiveModel::ValidatePresenceOfMatcher, type: :model
9
9
  it 'does not override the default message with a blank' do
10
10
  expect(validating_presence).to matcher.with_message(nil)
11
11
  end
12
+
13
+ it_supports(
14
+ 'ignoring_interference_by_writer',
15
+ tests: {
16
+ accept_if_qualified_but_changing_value_does_not_interfere: {
17
+ changing_values_with: :nil_to_blank
18
+ },
19
+ reject_if_qualified_but_changing_value_interferes: {
20
+ model_name: 'Example',
21
+ attribute_name: :attr,
22
+ changing_values_with: :never_falsy,
23
+ expected_message: <<-MESSAGE
24
+ Example did not properly validate that :attr cannot be empty/falsy.
25
+ After setting :attr to ‹nil› -- which was read back as ‹"dummy value"›
26
+ -- the matcher expected the Example to be invalid, but it was valid
27
+ instead.
28
+
29
+ As indicated in the message above, :attr seems to be changing certain
30
+ values as they are set, and this could have something to do with why
31
+ this test is failing. If you've overridden the writer method for this
32
+ attribute, then you may need to change it to make this test pass, or
33
+ do something else entirely.
34
+ MESSAGE
35
+ }
36
+ }
37
+ )
12
38
  end
13
39
 
14
40
  context 'a model without a presence validation' do
15
- it 'rejects' do
16
- expect(define_model(:example, attr: :string).new).not_to matcher
41
+ it 'rejects with the correct failure message' do
42
+ record = define_model(:example, attr: :string).new
43
+
44
+ assertion = lambda do
45
+ expect(record).to matcher
46
+ end
47
+
48
+ message = <<-MESSAGE
49
+ Example did not properly validate that :attr cannot be empty/falsy.
50
+ After setting :attr to ‹nil›, the matcher expected the Example to be
51
+ invalid, but it was valid instead.
52
+ MESSAGE
53
+
54
+ expect(&assertion).to fail_with_message(message)
17
55
  end
18
56
  end
19
57
 
@@ -25,17 +63,51 @@ describe Shoulda::Matchers::ActiveModel::ValidatePresenceOfMatcher, type: :model
25
63
  it 'does not override the default message with a blank' do
26
64
  expect(active_model_validating_presence).to matcher.with_message(nil)
27
65
  end
66
+
67
+ it_supports(
68
+ 'ignoring_interference_by_writer',
69
+ tests: {
70
+ accept_if_qualified_but_changing_value_does_not_interfere: {
71
+ changing_values_with: :nil_to_blank
72
+ },
73
+ reject_if_qualified_but_changing_value_interferes: {
74
+ model_name: 'Example',
75
+ attribute_name: :attr,
76
+ changing_values_with: :never_falsy,
77
+ expected_message: <<-MESSAGE
78
+ Example did not properly validate that :attr cannot be empty/falsy.
79
+ After setting :attr to ‹nil› -- which was read back as ‹"dummy value"›
80
+ -- the matcher expected the Example to be invalid, but it was valid
81
+ instead.
82
+
83
+ As indicated in the message above, :attr seems to be changing certain
84
+ values as they are set, and this could have something to do with why
85
+ this test is failing. If you've overridden the writer method for this
86
+ attribute, then you may need to change it to make this test pass, or
87
+ do something else entirely.
88
+ MESSAGE
89
+ }
90
+ }
91
+ )
92
+
93
+ def model_creator
94
+ :active_model
95
+ end
28
96
  end
29
97
 
30
98
  context 'an ActiveModel class without a presence validation' do
31
- it 'rejects' do
32
- expect(active_model).not_to matcher
33
- end
99
+ it 'rejects with the correct failure message' do
100
+ assertion = lambda do
101
+ expect(active_model).to matcher
102
+ end
34
103
 
35
- it 'provides the correct failure message' do
36
- message = %{Expected errors to include "can't be blank" when attr is set to nil,\ngot no errors}
104
+ message = <<-MESSAGE
105
+ Example did not properly validate that :attr cannot be empty/falsy.
106
+ After setting :attr to ‹nil›, the matcher expected the Example to be
107
+ invalid, but it was valid instead.
108
+ MESSAGE
37
109
 
38
- expect { expect(active_model).to matcher }.to fail_with_message(message)
110
+ expect(&assertion).to fail_with_message(message)
39
111
  end
40
112
  end
41
113
 
@@ -43,6 +115,36 @@ describe Shoulda::Matchers::ActiveModel::ValidatePresenceOfMatcher, type: :model
43
115
  it 'requires the attribute to be set' do
44
116
  expect(has_many_children(presence: true)).to validate_presence_of(:children)
45
117
  end
118
+
119
+ it_supports(
120
+ 'ignoring_interference_by_writer',
121
+ tests: {
122
+ accept_if_qualified_but_changing_value_does_not_interfere: {
123
+ changing_values_with: :nil_to_blank
124
+ },
125
+ reject_if_qualified_but_changing_value_interferes: {
126
+ model_name: 'Example',
127
+ attribute_name: :attr,
128
+ changing_values_with: :never_falsy,
129
+ expected_message: <<-MESSAGE
130
+ Example did not properly validate that :attr cannot be empty/falsy.
131
+ After setting :attr to ‹nil› -- which was read back as ‹"dummy value"›
132
+ -- the matcher expected the Example to be invalid, but it was valid
133
+ instead.
134
+
135
+ As indicated in the message above, :attr seems to be changing certain
136
+ values as they are set, and this could have something to do with why
137
+ this test is failing. If you've overridden the writer method for this
138
+ attribute, then you may need to change it to make this test pass, or
139
+ do something else entirely.
140
+ MESSAGE
141
+ }
142
+ }
143
+ )
144
+
145
+ def model_creator
146
+ :"active_record/has_many"
147
+ end
46
148
  end
47
149
 
48
150
  context 'a has_many association without a presence validation' do
@@ -53,20 +155,53 @@ describe Shoulda::Matchers::ActiveModel::ValidatePresenceOfMatcher, type: :model
53
155
  end
54
156
 
55
157
  context 'a required has_and_belongs_to_many association' do
56
- before do
57
- define_model :child
58
- @model = define_model :parent do
59
- has_and_belongs_to_many :children
60
- validates_presence_of :children
61
- end.new
158
+ it 'accepts' do
159
+ expect(build_record_having_and_belonging_to_many).
160
+ to validate_presence_of(:children)
161
+ end
162
+
163
+ def build_record_having_and_belonging_to_many
62
164
  create_table 'children_parents', id: false do |t|
63
165
  t.integer :child_id
64
166
  t.integer :parent_id
65
167
  end
168
+
169
+ define_model :child
170
+
171
+ define_model :parent do
172
+ has_and_belongs_to_many :children
173
+ validates_presence_of :children
174
+ end.new
66
175
  end
67
176
 
68
- it 'accepts' do
69
- expect(@model).to validate_presence_of(:children)
177
+ it_supports(
178
+ 'ignoring_interference_by_writer',
179
+ tests: {
180
+ accept_if_qualified_but_changing_value_does_not_interfere: {
181
+ changing_values_with: :nil_to_blank
182
+ },
183
+ reject_if_qualified_but_changing_value_interferes: {
184
+ model_name: 'Example',
185
+ attribute_name: :attr,
186
+ changing_values_with: :never_falsy,
187
+ expected_message: <<-MESSAGE
188
+ Example did not properly validate that :attr cannot be empty/falsy.
189
+ After setting :attr to ‹nil› -- which was read back as ‹"dummy value"›
190
+ -- the matcher expected the Example to be invalid, but it was valid
191
+ instead.
192
+
193
+ As indicated in the message above, :attr seems to be changing certain
194
+ values as they are set, and this could have something to do with why
195
+ this test is failing. If you've overridden the writer method for this
196
+ attribute, then you may need to change it to make this test pass, or
197
+ do something else entirely.
198
+ MESSAGE
199
+ }
200
+ }
201
+ )
202
+
203
+ def model_creator
204
+ :"active_record/has_and_belongs_to_many"
70
205
  end
71
206
  end
72
207
 
@@ -82,8 +217,18 @@ describe Shoulda::Matchers::ActiveModel::ValidatePresenceOfMatcher, type: :model
82
217
  end
83
218
  end
84
219
 
85
- it 'rejects' do
86
- expect(@model).not_to validate_presence_of(:children)
220
+ it 'rejects with the correct failure message' do
221
+ assertion = lambda do
222
+ expect(@model).to validate_presence_of(:children)
223
+ end
224
+
225
+ message = <<-MESSAGE
226
+ Parent did not properly validate that :children cannot be empty/falsy.
227
+ After setting :children to ‹[]›, the matcher expected the Parent to be
228
+ invalid, but it was valid instead.
229
+ MESSAGE
230
+
231
+ expect(&assertion).to fail_with_message(message)
87
232
  end
88
233
  end
89
234
 
@@ -109,8 +254,20 @@ describe Shoulda::Matchers::ActiveModel::ValidatePresenceOfMatcher, type: :model
109
254
  expect(validating_presence(strict: true)).to matcher.strict
110
255
  end
111
256
 
112
- it 'rejects when the :strict options do not match' do
113
- expect(validating_presence(strict: false)).not_to matcher.strict
257
+ it 'rejects with the correct failure message when the :strict options do not match' do
258
+ assertion = lambda do
259
+ expect(validating_presence(strict: false)).to matcher.strict
260
+ end
261
+
262
+ message = <<-MESSAGE
263
+ Example did not properly validate that :attr cannot be empty/falsy,
264
+ raising a validation exception on failure.
265
+ After setting :attr to ‹nil›, the matcher expected the Example to be
266
+ invalid and to raise a validation exception, but the record produced
267
+ validation errors instead.
268
+ MESSAGE
269
+
270
+ expect(&assertion).to fail_with_message(message)
114
271
  end
115
272
  end
116
273
 
@@ -146,7 +303,7 @@ describe Shoulda::Matchers::ActiveModel::ValidatePresenceOfMatcher, type: :model
146
303
 
147
304
  if rails_4_x?
148
305
  context 'against a pre-set password in a model that has_secure_password' do
149
- it 'raises a CouldNotSetPasswordError exception' do
306
+ it 'raises a CouldNotSetPasswordError' do
150
307
  user_class = define_model :user, password_digest: :string do
151
308
  has_secure_password validations: false
152
309
  validates_presence_of :password
@@ -155,21 +312,24 @@ describe Shoulda::Matchers::ActiveModel::ValidatePresenceOfMatcher, type: :model
155
312
  user = user_class.new
156
313
  user.password = 'something'
157
314
 
158
- error_class = Shoulda::Matchers::ActiveModel::CouldNotSetPasswordError
159
- expect do
315
+ assertion = lambda do
160
316
  expect(user).to validate_presence_of(:password)
161
- end.to raise_error(error_class)
317
+ end
318
+
319
+ expect(&assertion).to raise_error(
320
+ Shoulda::Matchers::ActiveModel::CouldNotSetPasswordError
321
+ )
162
322
  end
163
323
  end
164
324
  end
165
325
 
166
- context 'when the attribute typecasts nil to an empty array' do
167
- it 'accepts' do
168
- model = define_active_model_class :example do
169
- attr_reader :foo
326
+ context 'when the attribute typecasts nil to another blank value, such as an empty array' do
327
+ it 'accepts (and does not raise an AttributeChangedValueError)' do
328
+ model = define_active_model_class :example, accessors: [:foo] do
329
+ validates_presence_of :foo
170
330
 
171
331
  def foo=(value)
172
- @foo = Array.wrap(value)
332
+ super(Array.wrap(value))
173
333
  end
174
334
  end
175
335
 
@@ -210,4 +370,11 @@ describe Shoulda::Matchers::ActiveModel::ValidatePresenceOfMatcher, type: :model
210
370
  validates_presence_of :attr
211
371
  end.new
212
372
  end
373
+
374
+ def validation_matcher_scenario_args
375
+ super.deep_merge(
376
+ matcher_name: :validate_presence_of,
377
+ model_creator: :active_record
378
+ )
379
+ end
213
380
  end
@@ -6,10 +6,12 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
6
6
  it 'rejects' do
7
7
  record = record_with_array_values
8
8
  plural_enum_attribute = enum_attribute.to_s.pluralize
9
- message = "Expected #{record.class} to define :#{plural_enum_attribute} as an enum"
10
- assertion = -> {
9
+ message = "Expected #{record.class} to define :#{plural_enum_attribute} as an enum and store the value in a column with an integer type"
10
+
11
+ assertion = lambda do
11
12
  expect(record).to define_enum_for(plural_enum_attribute)
12
- }
13
+ end
14
+
13
15
  expect(&assertion).to fail_with_message(message)
14
16
  end
15
17
  end
@@ -19,10 +21,13 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
19
21
  model = define_model :example do
20
22
  def self.statuses; end
21
23
  end
22
- message = "Expected #{model} to define :statuses as an enum"
23
- assertion = -> {
24
+
25
+ message = "Expected #{model} to define :statuses as an enum and store the value in a column with an integer type"
26
+
27
+ assertion = lambda do
24
28
  expect(model.new).to define_enum_for(:statuses)
25
- }
29
+ end
30
+
26
31
  expect(&assertion).to fail_with_message(message)
27
32
  end
28
33
  end
@@ -33,19 +38,38 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
33
38
  end
34
39
 
35
40
  it "rejects a record where the attribute is not defined as an enum" do
36
- message = "Expected #{record_with_array_values.class} to define :#{non_enum_attribute} as an enum"
41
+ message = "Expected #{record_with_array_values.class} to define :#{non_enum_attribute} as an enum and store the value in a column with an integer type"
42
+
43
+ assertion = lambda do
44
+ expect(record_with_array_values).
45
+ to define_enum_for(non_enum_attribute)
46
+ end
37
47
 
38
- expect do
39
- expect(record_with_array_values).to define_enum_for(non_enum_attribute)
40
- end.to fail_with_message(message)
48
+ expect(&assertion).to fail_with_message(message)
41
49
  end
42
50
 
43
51
  it "rejects a record where the attribute is not defined as an enum with should not" do
44
- message = "Did not expect #{record_with_array_values.class} to define :#{enum_attribute} as an enum"
52
+ message = "Did not expect #{record_with_array_values.class} to define :#{enum_attribute} as an enum and store the value in a column with an integer type"
53
+
54
+ assertion = lambda do
55
+ expect(record_with_array_values).
56
+ not_to define_enum_for(enum_attribute)
57
+ end
45
58
 
46
- expect do
47
- expect(record_with_array_values).to_not define_enum_for(enum_attribute)
48
- end.to fail_with_message(message)
59
+ expect(&assertion).to fail_with_message(message)
60
+ end
61
+
62
+ context 'if the column storing the attribute is not an integer type' do
63
+ it 'rejects' do
64
+ record = record_with_array_values(column_type: :string)
65
+ message = "Expected #{record.class} to define :statuses as an enum and store the value in a column with an integer type"
66
+
67
+ assertion = lambda do
68
+ expect(record).to define_enum_for(:statuses)
69
+ end
70
+
71
+ expect(&assertion).to fail_with_message(message)
72
+ end
49
73
  end
50
74
  end
51
75
 
@@ -57,19 +81,26 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
57
81
  end
58
82
 
59
83
  it "accepts a record where the attribute is not defined as an enum" do
60
- message = %{Expected #{record_with_array_values.class} to define :#{non_enum_attribute} as an enum with ["open", "close"]}
84
+ message = %{Expected #{record_with_array_values.class} to define :#{non_enum_attribute} as an enum with ["open", "close"] and store the value in a column with an integer type}
85
+
86
+ assertion = lambda do
87
+ expect(record_with_array_values).
88
+ to define_enum_for(non_enum_attribute).with(['open', 'close'])
89
+ end
61
90
 
62
- expect do
63
- expect(record_with_array_values).to define_enum_for(non_enum_attribute).with(["open", "close"])
64
- end.to fail_with_message(message)
91
+ expect(&assertion).to fail_with_message(message)
65
92
  end
66
93
 
67
94
  it "accepts a record where the attribute is defined as an enum but the enum values do not match" do
68
- message = %{Expected #{record_with_array_values.class} to define :#{enum_attribute} as an enum with ["open", "close"]}
95
+ message = %{Expected #{record_with_array_values.class} to define :#{enum_attribute} as an enum with ["open", "close"] and store the value in a column with an integer type}
96
+
97
+ assertion = lambda do
98
+ expect(record_with_array_values).
99
+ to define_enum_for(enum_attribute).
100
+ with(["open", "close"])
101
+ end
69
102
 
70
- expect do
71
- expect(record_with_array_values).to define_enum_for(enum_attribute).with(["open", "close"])
72
- end.to fail_with_message(message)
103
+ expect(&assertion).to fail_with_message(message)
73
104
  end
74
105
  end
75
106
 
@@ -83,20 +114,27 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
83
114
  end
84
115
 
85
116
  it "accepts a record where the attribute is defined as an enum but the enum values do not match" do
86
- message = %{Expected #{record_with_hash_values.class} to define :#{enum_attribute} as an enum with {:active=>5, :archived=>10}}
117
+ message = %{Expected #{record_with_hash_values.class} to define :#{enum_attribute} as an enum with {:active=>5, :archived=>10} and store the value in a column with an integer type}
87
118
 
88
- expect do
89
- expect(record_with_hash_values).to define_enum_for(enum_attribute).with(active: 5, archived: 10)
90
- end.to fail_with_message(message)
119
+ assertion = lambda do
120
+ expect(record_with_hash_values).
121
+ to define_enum_for(enum_attribute).
122
+ with(active: 5, archived: 10)
123
+ end
124
+
125
+ expect(&assertion).to fail_with_message(message)
91
126
  end
92
127
 
93
128
  it "rejects a record where the attribute is not defined as an enum" do
94
- message = %{Expected #{record_with_hash_values.class} to define :record_with_hash_values as an enum with {:active=>5, :archived=>10}}
129
+ message = %{Expected #{record_with_hash_values.class} to define :record_with_hash_values as an enum with {:active=>5, :archived=>10} and store the value in a column with an integer type}
130
+
131
+ assertion = lambda do
132
+ expect(record_with_hash_values).
133
+ to define_enum_for(:record_with_hash_values).
134
+ with(active: 5, archived: 10)
135
+ end
95
136
 
96
- expect do
97
- expect(record_with_hash_values)
98
- .to define_enum_for(:record_with_hash_values).with(active: 5, archived: 10)
99
- end.to fail_with_message(message)
137
+ expect(&assertion).to fail_with_message(message)
100
138
  end
101
139
  end
102
140
  end
@@ -109,18 +147,22 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
109
147
  :condition
110
148
  end
111
149
 
112
- def record_with_array_values
113
- _enum_attribute = enum_attribute
114
- define_model :record_with_array_values do
115
- enum(_enum_attribute => %w(published unpublished draft))
116
- end.new
150
+ def record_with_array_values(column_type: :integer)
151
+ model = define_model(
152
+ :record_with_array_values,
153
+ enum_attribute => { type: column_type },
154
+ )
155
+ model.enum(enum_attribute => ['published', 'unpublished', 'draft'])
156
+ model.new
117
157
  end
118
158
 
119
159
  def record_with_hash_values
120
- _enum_attribute = enum_attribute
121
- define_model :record_with_hash_values do
122
- enum(_enum_attribute => { active: 0, archived: 1 })
123
- end.new
160
+ model = define_model(
161
+ :record_with_hash_values,
162
+ enum_attribute => { type: :integer },
163
+ )
164
+ model.enum(enum_attribute => { active: 0, archived: 1 })
165
+ model.new
124
166
  end
125
167
  end
126
168
  end