shoulda-matchers 4.0.0.rc1 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (209) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +72 -40
  4. data/lib/shoulda/matchers/action_controller.rb +2 -0
  5. data/lib/shoulda/matchers/active_model.rb +2 -3
  6. data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +1 -0
  7. data/lib/shoulda/matchers/active_record.rb +2 -0
  8. data/lib/shoulda/matchers/active_record/association_matcher.rb +34 -0
  9. data/lib/shoulda/matchers/active_record/association_matchers/optional_matcher.rb +27 -4
  10. data/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +27 -4
  11. data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +1 -1
  12. data/lib/shoulda/matchers/independent.rb +2 -1
  13. data/lib/shoulda/matchers/rails_shim.rb +5 -9
  14. data/lib/shoulda/matchers/version.rb +1 -1
  15. data/lib/shoulda/matchers/warn.rb +1 -0
  16. data/shoulda-matchers.gemspec +11 -3
  17. metadata +13 -340
  18. data/.gitignore +0 -12
  19. data/.hound.yml +0 -3
  20. data/.hound/ruby.yml +0 -1062
  21. data/.python-version +0 -1
  22. data/.rubocop.yml +0 -15
  23. data/.travis.yml +0 -21
  24. data/.yardopts +0 -10
  25. data/Appraisals +0 -105
  26. data/CONTRIBUTING.md +0 -172
  27. data/Gemfile +0 -15
  28. data/Gemfile.lock +0 -59
  29. data/MAINTAINING.md +0 -250
  30. data/NEWS.md +0 -1235
  31. data/Rakefile +0 -46
  32. data/bin/setup +0 -190
  33. data/custom_plan.rb +0 -104
  34. data/doc_config/gh-pages/index.html.erb +0 -9
  35. data/doc_config/yard/setup.rb +0 -22
  36. data/doc_config/yard/templates/default/fulldoc/html/css/bootstrap.css +0 -5967
  37. data/doc_config/yard/templates/default/fulldoc/html/css/full_list.css +0 -12
  38. data/doc_config/yard/templates/default/fulldoc/html/css/global.css +0 -66
  39. data/doc_config/yard/templates/default/fulldoc/html/css/solarized.css +0 -69
  40. data/doc_config/yard/templates/default/fulldoc/html/css/style.css +0 -312
  41. data/doc_config/yard/templates/default/fulldoc/html/full_list.erb +0 -26
  42. data/doc_config/yard/templates/default/fulldoc/html/full_list_class.erb +0 -1
  43. data/doc_config/yard/templates/default/fulldoc/html/full_list_method.erb +0 -8
  44. data/doc_config/yard/templates/default/fulldoc/html/js/app.js +0 -281
  45. data/doc_config/yard/templates/default/fulldoc/html/js/full_list.js +0 -1
  46. data/doc_config/yard/templates/default/fulldoc/html/js/jquery.stickyheaders.js +0 -289
  47. data/doc_config/yard/templates/default/fulldoc/html/js/underscore.min.js +0 -6
  48. data/doc_config/yard/templates/default/fulldoc/html/setup.rb +0 -35
  49. data/doc_config/yard/templates/default/layout/html/breadcrumb.erb +0 -14
  50. data/doc_config/yard/templates/default/layout/html/fonts.erb +0 -1
  51. data/doc_config/yard/templates/default/layout/html/footer.erb +0 -6
  52. data/doc_config/yard/templates/default/layout/html/layout.erb +0 -23
  53. data/doc_config/yard/templates/default/layout/html/search.erb +0 -13
  54. data/doc_config/yard/templates/default/layout/html/setup.rb +0 -40
  55. data/doc_config/yard/templates/default/method_details/html/source.erb +0 -10
  56. data/doc_config/yard/templates/default/module/html/box_info.erb +0 -31
  57. data/gemfiles/4.2.gemfile +0 -39
  58. data/gemfiles/4.2.gemfile.lock +0 -246
  59. data/gemfiles/5.0.gemfile +0 -37
  60. data/gemfiles/5.0.gemfile.lock +0 -238
  61. data/gemfiles/5.1.gemfile +0 -38
  62. data/gemfiles/5.1.gemfile.lock +0 -254
  63. data/gemfiles/5.2.gemfile +0 -40
  64. data/gemfiles/5.2.gemfile.lock +0 -273
  65. data/script/install_gems_in_all_appraisals +0 -16
  66. data/script/run_all_tests +0 -16
  67. data/script/supported_ruby_versions +0 -7
  68. data/script/update_gem_in_all_appraisals +0 -17
  69. data/script/update_gems_in_all_appraisals +0 -16
  70. data/spec/acceptance/active_model_integration_spec.rb +0 -23
  71. data/spec/acceptance/independent_matchers_spec.rb +0 -125
  72. data/spec/acceptance/multiple_libraries_integration_spec.rb +0 -55
  73. data/spec/acceptance/rails_integration_spec.rb +0 -156
  74. data/spec/acceptance_spec_helper.rb +0 -23
  75. data/spec/doublespeak_spec_helper.rb +0 -2
  76. data/spec/report_warnings.rb +0 -7
  77. data/spec/spec_helper.rb +0 -20
  78. data/spec/support/acceptance/adds_shoulda_matchers_to_project.rb +0 -133
  79. data/spec/support/acceptance/helpers.rb +0 -33
  80. data/spec/support/acceptance/helpers/active_model_helpers.rb +0 -11
  81. data/spec/support/acceptance/helpers/array_helpers.rb +0 -13
  82. data/spec/support/acceptance/helpers/base_helpers.rb +0 -19
  83. data/spec/support/acceptance/helpers/command_helpers.rb +0 -68
  84. data/spec/support/acceptance/helpers/file_helpers.rb +0 -19
  85. data/spec/support/acceptance/helpers/gem_helpers.rb +0 -31
  86. data/spec/support/acceptance/helpers/minitest_helpers.rb +0 -11
  87. data/spec/support/acceptance/helpers/n_unit_helpers.rb +0 -25
  88. data/spec/support/acceptance/helpers/pluralization_helpers.rb +0 -13
  89. data/spec/support/acceptance/helpers/rails_migration_helpers.rb +0 -21
  90. data/spec/support/acceptance/helpers/rails_version_helpers.rb +0 -11
  91. data/spec/support/acceptance/helpers/rspec_helpers.rb +0 -24
  92. data/spec/support/acceptance/helpers/ruby_version_helpers.rb +0 -9
  93. data/spec/support/acceptance/helpers/step_helpers.rb +0 -127
  94. data/spec/support/acceptance/matchers/have_output.rb +0 -31
  95. data/spec/support/acceptance/matchers/indicate_number_of_tests_was_run_matcher.rb +0 -55
  96. data/spec/support/acceptance/matchers/indicate_that_tests_were_run_matcher.rb +0 -103
  97. data/spec/support/tests/bundle.rb +0 -94
  98. data/spec/support/tests/command_runner.rb +0 -230
  99. data/spec/support/tests/current_bundle.rb +0 -55
  100. data/spec/support/tests/database.rb +0 -28
  101. data/spec/support/tests/database_adapters/postgresql.rb +0 -25
  102. data/spec/support/tests/database_adapters/sqlite3.rb +0 -26
  103. data/spec/support/tests/database_configuration.rb +0 -33
  104. data/spec/support/tests/database_configuration_registry.rb +0 -28
  105. data/spec/support/tests/filesystem.rb +0 -100
  106. data/spec/support/tests/version.rb +0 -45
  107. data/spec/support/unit/active_record/create_table.rb +0 -54
  108. data/spec/support/unit/attribute.rb +0 -45
  109. data/spec/support/unit/capture.rb +0 -46
  110. data/spec/support/unit/change_value.rb +0 -111
  111. data/spec/support/unit/create_model_arguments/basic.rb +0 -135
  112. data/spec/support/unit/create_model_arguments/has_many.rb +0 -15
  113. data/spec/support/unit/create_model_arguments/uniqueness_matcher.rb +0 -74
  114. data/spec/support/unit/helpers/action_pack_versions.rb +0 -22
  115. data/spec/support/unit/helpers/active_model_helpers.rb +0 -27
  116. data/spec/support/unit/helpers/active_model_versions.rb +0 -32
  117. data/spec/support/unit/helpers/active_record_versions.rb +0 -44
  118. data/spec/support/unit/helpers/active_resource_builder.rb +0 -27
  119. data/spec/support/unit/helpers/allow_value_matcher_helpers.rb +0 -15
  120. data/spec/support/unit/helpers/class_builder.rb +0 -90
  121. data/spec/support/unit/helpers/column_type_helpers.rb +0 -26
  122. data/spec/support/unit/helpers/confirmation_matcher_helpers.rb +0 -17
  123. data/spec/support/unit/helpers/controller_builder.rb +0 -63
  124. data/spec/support/unit/helpers/database_helpers.rb +0 -20
  125. data/spec/support/unit/helpers/i18n_faker.rb +0 -15
  126. data/spec/support/unit/helpers/mailer_builder.rb +0 -12
  127. data/spec/support/unit/helpers/message_helpers.rb +0 -19
  128. data/spec/support/unit/helpers/model_builder.rb +0 -114
  129. data/spec/support/unit/helpers/rails_versions.rb +0 -42
  130. data/spec/support/unit/helpers/validation_matcher_scenario_helpers.rb +0 -44
  131. data/spec/support/unit/i18n.rb +0 -7
  132. data/spec/support/unit/load_environment.rb +0 -12
  133. data/spec/support/unit/matchers/deprecate.rb +0 -60
  134. data/spec/support/unit/matchers/fail_with_message_including_matcher.rb +0 -51
  135. data/spec/support/unit/matchers/fail_with_message_matcher.rb +0 -64
  136. data/spec/support/unit/matchers/print_warning_including.rb +0 -67
  137. data/spec/support/unit/model_creation_strategies/active_model.rb +0 -111
  138. data/spec/support/unit/model_creation_strategies/active_record.rb +0 -77
  139. data/spec/support/unit/model_creators.rb +0 -19
  140. data/spec/support/unit/model_creators/active_model.rb +0 -39
  141. data/spec/support/unit/model_creators/active_record.rb +0 -42
  142. data/spec/support/unit/model_creators/active_record/has_and_belongs_to_many.rb +0 -95
  143. data/spec/support/unit/model_creators/active_record/has_many.rb +0 -67
  144. data/spec/support/unit/model_creators/active_record/uniqueness_matcher.rb +0 -42
  145. data/spec/support/unit/model_creators/basic.rb +0 -102
  146. data/spec/support/unit/rails_application.rb +0 -151
  147. data/spec/support/unit/record_builder_with_i18n_validation_message.rb +0 -69
  148. data/spec/support/unit/record_validating_confirmation_builder.rb +0 -54
  149. data/spec/support/unit/record_with_different_error_attribute_builder.rb +0 -92
  150. data/spec/support/unit/shared_examples/ignoring_interference_by_writer.rb +0 -79
  151. data/spec/support/unit/shared_examples/numerical_submatcher.rb +0 -17
  152. data/spec/support/unit/shared_examples/set_session_or_flash.rb +0 -360
  153. data/spec/support/unit/validation_matcher_scenario.rb +0 -60
  154. data/spec/unit/shoulda/matchers/action_controller/callback_matcher_spec.rb +0 -82
  155. data/spec/unit/shoulda/matchers/action_controller/filter_param_matcher_spec.rb +0 -28
  156. data/spec/unit/shoulda/matchers/action_controller/permit_matcher_spec.rb +0 -629
  157. data/spec/unit/shoulda/matchers/action_controller/redirect_to_matcher_spec.rb +0 -42
  158. data/spec/unit/shoulda/matchers/action_controller/render_template_matcher_spec.rb +0 -76
  159. data/spec/unit/shoulda/matchers/action_controller/render_with_layout_matcher_spec.rb +0 -62
  160. data/spec/unit/shoulda/matchers/action_controller/rescue_from_matcher_spec.rb +0 -90
  161. data/spec/unit/shoulda/matchers/action_controller/respond_with_matcher_spec.rb +0 -31
  162. data/spec/unit/shoulda/matchers/action_controller/route_matcher_spec.rb +0 -330
  163. data/spec/unit/shoulda/matchers/action_controller/route_params_spec.rb +0 -30
  164. data/spec/unit/shoulda/matchers/action_controller/set_flash_matcher_spec.rb +0 -67
  165. data/spec/unit/shoulda/matchers/action_controller/set_session_matcher_spec.rb +0 -17
  166. data/spec/unit/shoulda/matchers/action_controller/set_session_or_flash_matcher_spec.rb +0 -562
  167. data/spec/unit/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +0 -117
  168. data/spec/unit/shoulda/matchers/active_model/allow_value_matcher_spec.rb +0 -829
  169. data/spec/unit/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +0 -86
  170. data/spec/unit/shoulda/matchers/active_model/have_secure_password_matcher_spec.rb +0 -20
  171. data/spec/unit/shoulda/matchers/active_model/helpers_spec.rb +0 -162
  172. data/spec/unit/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +0 -290
  173. data/spec/unit/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +0 -109
  174. data/spec/unit/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +0 -172
  175. data/spec/unit/shoulda/matchers/active_model/validate_exclusion_of_matcher_spec.rb +0 -264
  176. data/spec/unit/shoulda/matchers/active_model/validate_inclusion_of_matcher_spec.rb +0 -1049
  177. data/spec/unit/shoulda/matchers/active_model/validate_length_of_matcher_spec.rb +0 -335
  178. data/spec/unit/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +0 -1865
  179. data/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +0 -406
  180. data/spec/unit/shoulda/matchers/active_record/accept_nested_attributes_for_matcher_spec.rb +0 -107
  181. data/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb +0 -1672
  182. data/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +0 -251
  183. data/spec/unit/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb +0 -690
  184. data/spec/unit/shoulda/matchers/active_record/have_db_column_matcher_spec.rb +0 -111
  185. data/spec/unit/shoulda/matchers/active_record/have_db_index_matcher_spec.rb +0 -85
  186. data/spec/unit/shoulda/matchers/active_record/have_readonly_attributes_matcher_spec.rb +0 -41
  187. data/spec/unit/shoulda/matchers/active_record/have_secure_token_matcher_spec.rb +0 -169
  188. data/spec/unit/shoulda/matchers/active_record/serialize_matcher_spec.rb +0 -86
  189. data/spec/unit/shoulda/matchers/active_record/validate_uniqueness_of_matcher_spec.rb +0 -1682
  190. data/spec/unit/shoulda/matchers/doublespeak/double_collection_spec.rb +0 -190
  191. data/spec/unit/shoulda/matchers/doublespeak/double_implementation_registry_spec.rb +0 -21
  192. data/spec/unit/shoulda/matchers/doublespeak/double_spec.rb +0 -271
  193. data/spec/unit/shoulda/matchers/doublespeak/object_double_spec.rb +0 -77
  194. data/spec/unit/shoulda/matchers/doublespeak/proxy_implementation_spec.rb +0 -72
  195. data/spec/unit/shoulda/matchers/doublespeak/stub_implementation_spec.rb +0 -101
  196. data/spec/unit/shoulda/matchers/doublespeak/world_spec.rb +0 -78
  197. data/spec/unit/shoulda/matchers/doublespeak_spec.rb +0 -27
  198. data/spec/unit/shoulda/matchers/independent/delegate_method_matcher/stubbed_target_spec.rb +0 -43
  199. data/spec/unit/shoulda/matchers/independent/delegate_method_matcher_spec.rb +0 -650
  200. data/spec/unit/shoulda/matchers/routing/route_matcher_spec.rb +0 -406
  201. data/spec/unit/shoulda/matchers/util/word_wrap_spec.rb +0 -252
  202. data/spec/unit_spec_helper.rb +0 -54
  203. data/spec/warnings_spy.rb +0 -64
  204. data/spec/warnings_spy/filesystem.rb +0 -45
  205. data/spec/warnings_spy/partitioner.rb +0 -36
  206. data/spec/warnings_spy/reader.rb +0 -53
  207. data/spec/warnings_spy/reporter.rb +0 -88
  208. data/tasks/documentation.rb +0 -199
  209. data/zeus.json +0 -11
@@ -1,335 +0,0 @@
1
- require 'unit_spec_helper'
2
-
3
- describe Shoulda::Matchers::ActiveModel::ValidateLengthOfMatcher, type: :model 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 validate_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 validate_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 validate_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 validate_length_of(:attr).is_at_least(4).with_short_message(nil)
23
- end
24
-
25
- it_supports(
26
- 'ignoring_interference_by_writer',
27
- tests: {
28
- accept_if_qualified_but_changing_value_does_not_interfere: {
29
- changing_values_with: :upcase,
30
- },
31
- reject_if_qualified_but_changing_value_interferes: {
32
- model_name: 'Example',
33
- attribute_name: :attr,
34
- changing_values_with: :add_character,
35
- expected_message: <<-MESSAGE.strip
36
- Expected Example to validate that the length of :attr is at least 4, but
37
- this could not be proved.
38
- After setting :attr to ‹"xxx"› -- which was read back as ‹"xxxa"› --
39
- the matcher expected the Example to be invalid, but it was valid
40
- instead.
41
-
42
- As indicated in the message above, :attr seems to be changing certain
43
- values as they are set, and this could have something to do with why
44
- this test is failing. If you've overridden the writer method for this
45
- attribute, then you may need to change it to make this test pass, or
46
- do something else entirely.
47
- MESSAGE
48
- }
49
- }
50
- ) do
51
- def validation_matcher_scenario_args
52
- super.deep_merge(validation_options: { minimum: 4 })
53
- end
54
-
55
- def configure_validation_matcher(matcher)
56
- matcher.is_at_least(4)
57
- end
58
- end
59
-
60
- it 'fails when used in the negative' do
61
- assertion = lambda do
62
- expect(validating_length(minimum: 4)).
63
- not_to validate_length_of(:attr).is_at_least(4)
64
- end
65
-
66
- message = <<-MESSAGE
67
- Expected Example not to validate that the length of :attr is at least 4,
68
- but this could not be proved.
69
- After setting :attr to ‹"xxxx"›, the matcher expected the Example to
70
- be invalid, but it was valid instead.
71
- MESSAGE
72
-
73
- expect(&assertion).to fail_with_message(message)
74
- end
75
- end
76
-
77
- context 'an attribute with a minimum length validation of 0' do
78
- it 'accepts ensuring the correct minimum length' do
79
- expect(validating_length(minimum: 0)).
80
- to validate_length_of(:attr).is_at_least(0)
81
- end
82
- end
83
-
84
- context 'an attribute with a maximum length' do
85
- it 'accepts ensuring the correct maximum length' do
86
- expect(validating_length(maximum: 4)).
87
- to validate_length_of(:attr).is_at_most(4)
88
- end
89
-
90
- it 'rejects ensuring a lower maximum length with any message' do
91
- expect(validating_length(maximum: 4)).
92
- not_to validate_length_of(:attr).is_at_most(3).with_long_message(/.*/)
93
- end
94
-
95
- it 'rejects ensuring a higher maximum length with any message' do
96
- expect(validating_length(maximum: 4)).
97
- not_to validate_length_of(:attr).is_at_most(5).with_long_message(/.*/)
98
- end
99
-
100
- it 'does not override the default message with a blank' do
101
- expect(validating_length(maximum: 4)).
102
- to validate_length_of(:attr).is_at_most(4).with_long_message(nil)
103
- end
104
-
105
- it_supports(
106
- 'ignoring_interference_by_writer',
107
- tests: {
108
- accept_if_qualified_but_changing_value_does_not_interfere: {
109
- changing_values_with: :upcase,
110
- },
111
- reject_if_qualified_but_changing_value_interferes: {
112
- model_name: 'Example',
113
- attribute_name: :attr,
114
- changing_values_with: :remove_character,
115
- expected_message: <<-MESSAGE.strip
116
- Expected Example to validate that the length of :attr is at most 4, but
117
- this could not be proved.
118
- After setting :attr to ‹"xxxxx"› -- which was read back as ‹"xxxx"› --
119
- the matcher expected the Example to be invalid, but it was valid
120
- instead.
121
-
122
- As indicated in the message above, :attr seems to be changing certain
123
- values as they are set, and this could have something to do with why
124
- this test is failing. If you've overridden the writer method for this
125
- attribute, then you may need to change it to make this test pass, or
126
- do something else entirely.
127
- MESSAGE
128
- }
129
- }
130
- ) do
131
- def validation_matcher_scenario_args
132
- super.deep_merge(validation_options: { maximum: 4 })
133
- end
134
-
135
- def configure_validation_matcher(matcher)
136
- matcher.is_at_most(4)
137
- end
138
- end
139
- end
140
-
141
- context 'an attribute with a required exact length' do
142
- it 'accepts ensuring the correct length' do
143
- expect(validating_length(is: 4)).
144
- to validate_length_of(:attr).is_equal_to(4)
145
- end
146
-
147
- it 'rejects ensuring a lower maximum length with any message' do
148
- expect(validating_length(is: 4)).
149
- not_to validate_length_of(:attr).is_equal_to(3).with_message(/.*/)
150
- end
151
-
152
- it 'rejects ensuring a higher maximum length with any message' do
153
- expect(validating_length(is: 4)).
154
- not_to validate_length_of(:attr).is_equal_to(5).with_message(/.*/)
155
- end
156
-
157
- it 'does not override the default message with a blank' do
158
- expect(validating_length(is: 4)).
159
- to validate_length_of(:attr).is_equal_to(4).with_message(nil)
160
- end
161
-
162
- it_supports(
163
- 'ignoring_interference_by_writer',
164
- tests: {
165
- accept_if_qualified_but_changing_value_does_not_interfere: {
166
- changing_values_with: :upcase,
167
- },
168
- reject_if_qualified_but_changing_value_interferes: {
169
- model_name: 'Example',
170
- attribute_name: :attr,
171
- changing_values_with: :add_character,
172
- expected_message: <<-MESSAGE.strip
173
- Expected Example to validate that the length of :attr is 4, but this
174
- could not be proved.
175
- After setting :attr to ‹"xxx"› -- which was read back as ‹"xxxa"› --
176
- the matcher expected the Example to be invalid, but it was valid
177
- instead.
178
-
179
- As indicated in the message above, :attr seems to be changing certain
180
- values as they are set, and this could have something to do with why
181
- this test is failing. If you've overridden the writer method for this
182
- attribute, then you may need to change it to make this test pass, or
183
- do something else entirely.
184
- MESSAGE
185
- }
186
- }
187
- ) do
188
- def validation_matcher_scenario_args
189
- super.deep_merge(validation_options: { is: 4 })
190
- end
191
-
192
- def configure_validation_matcher(matcher)
193
- matcher.is_equal_to(4)
194
- end
195
- end
196
- end
197
-
198
- context 'an attribute with a required exact length and another validation' do
199
- it 'accepts ensuring the correct length' do
200
- model = define_model(:example, attr: :string) do
201
- validates_length_of :attr, is: 4
202
- validates_numericality_of :attr
203
- end.new
204
-
205
- expect(model).to validate_length_of(:attr).is_equal_to(4)
206
- end
207
- end
208
-
209
- context 'an attribute with a custom minimum length validation' do
210
- it 'accepts ensuring the correct minimum length' do
211
- expect(validating_length(minimum: 4, too_short: 'foobar')).
212
- to validate_length_of(:attr).is_at_least(4).with_short_message(/foo/)
213
- end
214
- end
215
-
216
- context 'an attribute with a custom maximum length validation' do
217
- it 'accepts ensuring the correct minimum length' do
218
- expect(validating_length(maximum: 4, too_long: 'foobar')).
219
- to validate_length_of(:attr).is_at_most(4).with_long_message(/foo/)
220
- end
221
- end
222
-
223
- context 'an attribute with a custom equal validation' do
224
- it 'accepts ensuring the correct exact length' do
225
- expect(validating_length(is: 4, message: 'foobar')).
226
- to validate_length_of(:attr).is_equal_to(4).with_message(/foo/)
227
- end
228
- end
229
-
230
- context 'an attribute without a length validation' do
231
- it 'rejects ensuring a minimum length' do
232
- expect(define_model(:example, attr: :string).new).
233
- not_to validate_length_of(:attr).is_at_least(1)
234
- end
235
- end
236
-
237
- context 'using translations' do
238
- after { I18n.backend.reload! }
239
-
240
- context "a too_long translation containing %{attribute}, %{model}" do
241
- before do
242
- stub_translation(
243
- "activerecord.errors.messages.too_long",
244
- "The %{attribute} of your %{model} is too long (maximum is %{count} characters)")
245
- end
246
-
247
- it "does not raise an exception" do
248
- expect {
249
- expect(validating_length(maximum: 4)).
250
- to validate_length_of(:attr).is_at_most(4)
251
- }.to_not raise_exception
252
- end
253
- end
254
-
255
- context "a too_short translation containing %{attribute}, %{model}" do
256
- before do
257
- stub_translation(
258
- "activerecord.errors.messages.too_short",
259
- "The %{attribute} of your %{model} is too short (minimum is %{count} characters)")
260
- end
261
-
262
- it "does not raise an exception" do
263
- expect {
264
- expect(validating_length(minimum: 4)).to validate_length_of(:attr).is_at_least(4)
265
- }.to_not raise_exception
266
- end
267
- end
268
-
269
- context "a wrong_length translation containing %{attribute}, %{model}" do
270
- before do
271
- stub_translation(
272
- "activerecord.errors.messages.wrong_length",
273
- "The %{attribute} of your %{model} is the wrong length (should be %{count} characters)")
274
- end
275
-
276
- it "does not raise an exception" do
277
- expect {
278
- expect(validating_length(is: 4)).
279
- to validate_length_of(:attr).is_equal_to(4)
280
- }.to_not raise_exception
281
- end
282
- end
283
- end
284
-
285
- context 'qualified with allow_nil' do
286
- context 'and validating with allow_nil' do
287
- it 'accepts' do
288
- expect(validating_length(minimum: 1, allow_nil: true)).
289
- to validate_length_of(:attr).is_at_least(1).allow_nil
290
- end
291
- end
292
-
293
- context 'and not validating with allow_nil' do
294
- it 'rejects' do
295
- assertion = lambda do
296
- expect(validating_length(minimum: 1)).
297
- to validate_length_of(:attr).is_at_least(1).allow_nil
298
- end
299
-
300
- message = <<-MESSAGE
301
- Expected Example to validate that the length of :attr is at least 1, but
302
- this could not be proved.
303
- After setting :attr to ‹nil›, the matcher expected the Example to be
304
- valid, but it was invalid instead, producing these validation errors:
305
-
306
- * attr: ["is too short (minimum is 1 character)"]
307
- MESSAGE
308
-
309
- expect(&assertion).to fail_with_message(message)
310
- end
311
- end
312
- end
313
-
314
- def define_model_validating_length(options = {})
315
- options = options.dup
316
- attribute_name = options.delete(:attribute_name) { :attr }
317
-
318
- define_model(:example, attribute_name => :string) do |model|
319
- model.validates_length_of(attribute_name, options)
320
- end
321
- end
322
-
323
- def validating_length(options = {})
324
- define_model_validating_length(options).new
325
- end
326
-
327
- alias_method :build_record_validating_length, :validating_length
328
-
329
- def validation_matcher_scenario_args
330
- super.deep_merge(
331
- matcher_name: :validate_length_of,
332
- model_creator: :active_model
333
- )
334
- end
335
- end
@@ -1,1865 +0,0 @@
1
- require 'unit_spec_helper'
2
-
3
- describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher, type: :model do
4
- class << self
5
- def all_qualifiers
6
- [
7
- {
8
- category: :comparison,
9
- name: :is_greater_than,
10
- argument: 1,
11
- validation_name: :greater_than,
12
- validation_value: 1,
13
- },
14
- {
15
- category: :comparison,
16
- name: :is_greater_than_or_equal_to,
17
- argument: 1,
18
- validation_name: :greater_than_or_equal_to,
19
- validation_value: 1,
20
- },
21
- {
22
- category: :comparison,
23
- name: :is_less_than,
24
- argument: 1,
25
- validation_name: :less_than,
26
- validation_value: 1,
27
- },
28
- {
29
- category: :comparison,
30
- name: :is_less_than_or_equal_to,
31
- argument: 1,
32
- validation_name: :less_than_or_equal_to,
33
- validation_value: 1,
34
- },
35
- {
36
- category: :comparison,
37
- name: :is_equal_to,
38
- argument: 1,
39
- validation_name: :equal_to,
40
- validation_value: 1,
41
- },
42
- {
43
- category: :cardinality,
44
- name: :odd,
45
- validation_name: :odd,
46
- validation_value: true,
47
- },
48
- {
49
- category: :cardinality,
50
- name: :even,
51
- validation_name: :even,
52
- validation_value: true,
53
- },
54
- {
55
- name: :only_integer,
56
- validation_name: :only_integer,
57
- validation_value: true,
58
- },
59
- {
60
- name: :on,
61
- argument: :customizable,
62
- validation_name: :on,
63
- validation_value: :customizable
64
- }
65
- ]
66
- end
67
-
68
- def qualifiers_under(category)
69
- all_qualifiers.select do |qualifier|
70
- qualifier[:category] == category
71
- end
72
- end
73
-
74
- def mutually_exclusive_qualifiers
75
- qualifiers_under(:cardinality) + qualifiers_under(:comparison)
76
- end
77
-
78
- def non_mutually_exclusive_qualifiers
79
- all_qualifiers - mutually_exclusive_qualifiers
80
- end
81
-
82
- def validations_by_qualifier
83
- all_qualifiers.each_with_object({}) do |qualifier, hash|
84
- hash[qualifier[:name]] = qualifier[:validation_name]
85
- end
86
- end
87
-
88
- def all_qualifier_combinations
89
- combinations = []
90
-
91
- ([nil] + mutually_exclusive_qualifiers).each do |mutually_exclusive_qualifier|
92
- (0..non_mutually_exclusive_qualifiers.length).each do |n|
93
- non_mutually_exclusive_qualifiers.combination(n) do |combination|
94
- super_combination = (
95
- [mutually_exclusive_qualifier] +
96
- combination
97
- )
98
- super_combination.select!(&:present?)
99
-
100
- if super_combination.any?
101
- combinations << super_combination
102
- end
103
- end
104
- end
105
- end
106
-
107
- combinations
108
- end
109
-
110
- def default_qualifier_arguments
111
- all_qualifiers.each_with_object({}) do |qualifier, hash|
112
- hash[qualifier[:name]] = qualifier[:argument]
113
- end
114
- end
115
-
116
- def default_validation_values
117
- all_qualifiers.each_with_object({}) do |qualifier, hash|
118
- hash[qualifier[:validation_name]] = qualifier[:validation_value]
119
- end
120
- end
121
- end
122
-
123
- context 'qualified with nothing' do
124
- context 'and validating numericality' do
125
- it 'accepts' do
126
- record = build_record_validating_numericality
127
- expect(record).to validate_numericality
128
- end
129
-
130
- it_supports(
131
- 'ignoring_interference_by_writer',
132
- tests: {
133
- accept_if_qualified_but_changing_value_does_not_interfere: {
134
- changing_values_with: :next_value,
135
- },
136
- reject_if_qualified_but_changing_value_interferes: {
137
- model_name: 'Example',
138
- attribute_name: :attr,
139
- changing_values_with: :numeric_value,
140
- expected_message: <<-MESSAGE.strip
141
- Expected Example to validate that :attr looks like a number, but this
142
- could not be proved.
143
- After setting :attr to ‹"abcd"› -- which was read back as ‹"1"› -- the
144
- matcher expected the Example to be invalid, but it was valid instead.
145
-
146
- As indicated in the message above, :attr seems to be changing certain
147
- values as they are set, and this could have something to do with why
148
- this test is failing. If you've overridden the writer method for this
149
- attribute, then you may need to change it to make this test pass, or
150
- do something else entirely.
151
- MESSAGE
152
- }
153
- }
154
- )
155
-
156
- context 'when the attribute is a virtual attribute in an ActiveRecord model' do
157
- it 'accepts' do
158
- record = build_record_validating_numericality_of_virtual_attribute
159
- expect(record).to validate_numericality
160
- end
161
- end
162
-
163
- context 'when the column is an integer column' do
164
- it 'accepts (and does not raise an AttributeChangedValueError)' do
165
- record = build_record_validating_numericality(column_type: :integer)
166
- expect(record).to validate_numericality
167
- end
168
- end
169
-
170
- context 'when the column is a float column' do
171
- it 'accepts (and does not raise an AttributeChangedValueError)' do
172
- record = build_record_validating_numericality(column_type: :float)
173
- expect(record).to validate_numericality
174
- end
175
- end
176
-
177
- context 'when the column is a decimal column' do
178
- it 'accepts (and does not raise an AttributeChangedValueError)' do
179
- record = build_record_validating_numericality(column_type: :decimal)
180
- expect(record).to validate_numericality
181
- end
182
- end
183
-
184
- if database_supports_money_columns?
185
- context 'when the column is a money column' do
186
- it 'accepts (and does not raise an AttributeChangedValueError)' do
187
- record = build_record_validating_numericality(column_type: :money)
188
- expect(record).to validate_numericality
189
- end
190
- end
191
- end
192
-
193
- context 'when used in the negative' do
194
- it 'fails' do
195
- assertion = lambda do
196
- record = build_record_validating_numericality
197
- expect(record).not_to validate_numericality
198
- end
199
-
200
- message = <<-MESSAGE
201
- Expected Example not to validate that :attr looks like a number, but
202
- this could not be proved.
203
- After setting :attr to ‹"abcd"›, the matcher expected the Example to
204
- be valid, but it was invalid instead, producing these validation
205
- errors:
206
-
207
- * attr: ["is not a number"]
208
- MESSAGE
209
-
210
- expect(&assertion).to fail_with_message(message)
211
- end
212
- end
213
- end
214
-
215
- context 'and not validating anything' do
216
- it 'rejects since it does not disallow non-numbers' do
217
- record = build_record_validating_nothing
218
-
219
- assertion = -> { expect(record).to validate_numericality }
220
-
221
- message = <<-MESSAGE
222
- Expected Example to validate that :attr looks like a number, but this
223
- could not be proved.
224
- After setting :attr to ‹"abcd"›, the matcher expected the Example to
225
- be invalid, but it was valid instead.
226
- MESSAGE
227
-
228
- expect(&assertion).to fail_with_message(message)
229
- end
230
- end
231
- end
232
-
233
- context 'qualified with allow_nil' do
234
- context 'and validating with allow_nil' do
235
- it 'accepts' do
236
- record = build_record_validating_numericality(allow_nil: true)
237
- expect(record).to validate_numericality.allow_nil
238
- end
239
-
240
- it_supports(
241
- 'ignoring_interference_by_writer',
242
- tests: {
243
- accept_if_qualified_but_changing_value_does_not_interfere: {
244
- changing_values_with: :next_value_or_numeric_value,
245
- },
246
- reject_if_qualified_but_changing_value_interferes: {
247
- model_name: 'Example',
248
- attribute_name: :attr,
249
- changing_values_with: :next_value_or_non_numeric_value,
250
- expected_message: <<-MESSAGE.strip
251
- Expected Example to validate that :attr looks like a number as long as
252
- it is not nil, but this could not be proved.
253
- In checking that Example allows :attr to be ‹nil›, after setting :attr
254
- to ‹nil› -- which was read back as ‹"a"› -- the matcher expected the
255
- Example to be valid, but it was invalid instead, producing these
256
- validation errors:
257
-
258
- * attr: ["is not a number"]
259
-
260
- As indicated in the message above, :attr seems to be changing certain
261
- values as they are set, and this could have something to do with why
262
- this test is failing. If you've overridden the writer method for this
263
- attribute, then you may need to change it to make this test pass, or
264
- do something else entirely.
265
- MESSAGE
266
- }
267
- }
268
- ) do
269
- def validation_matcher_scenario_args
270
- super.deep_merge(validation_options: { allow_nil: true })
271
- end
272
-
273
- def configure_validation_matcher(matcher)
274
- matcher.allow_nil
275
- end
276
- end
277
- end
278
-
279
- context 'and not validating with allow_nil' do
280
- it 'rejects since it tries to treat nil as a number' do
281
- record = build_record_validating_numericality
282
-
283
- assertion = lambda do
284
- expect(record).to validate_numericality.allow_nil
285
- end
286
-
287
- message = <<-MESSAGE
288
- Expected Example to validate that :attr looks like a number as long as
289
- it is not nil, but this could not be proved.
290
- In checking that Example allows :attr to be ‹nil›, after setting :attr
291
- to ‹nil›, the matcher expected the Example to be valid, but it was
292
- invalid instead, producing these validation errors:
293
-
294
- * attr: ["is not a number"]
295
- MESSAGE
296
-
297
- expect(&assertion).to fail_with_message(message)
298
- end
299
- end
300
- end
301
-
302
- context 'qualified with only_integer' do
303
- context 'and validating with only_integer' do
304
- it 'accepts' do
305
- record = build_record_validating_numericality(only_integer: true)
306
- expect(record).to validate_numericality.only_integer
307
- end
308
-
309
- it_supports(
310
- 'ignoring_interference_by_writer',
311
- tests: {
312
- accept_if_qualified_but_changing_value_does_not_interfere: {
313
- changing_values_with: :next_value,
314
- },
315
- reject_if_qualified_but_changing_value_interferes: {
316
- model_name: 'Example',
317
- attribute_name: :attr,
318
- changing_values_with: :numeric_value,
319
- expected_message: <<-MESSAGE.strip
320
- Expected Example to validate that :attr looks like an integer, but this
321
- could not be proved.
322
- After setting :attr to ‹"0.1"› -- which was read back as ‹"1"› -- the
323
- matcher expected the Example to be invalid, but it was valid instead.
324
-
325
- As indicated in the message above, :attr seems to be changing certain
326
- values as they are set, and this could have something to do with why
327
- this test is failing. If you've overridden the writer method for this
328
- attribute, then you may need to change it to make this test pass, or
329
- do something else entirely.
330
- MESSAGE
331
- }
332
- }
333
- ) do
334
- def validation_matcher_scenario_args
335
- super.deep_merge(validation_options: { only_integer: true })
336
- end
337
-
338
- def configure_validation_matcher(matcher)
339
- matcher.only_integer
340
- end
341
- end
342
- end
343
-
344
- context 'and not validating with only_integer' do
345
- it 'rejects since it does not disallow non-integers' do
346
- record = build_record_validating_numericality
347
-
348
- assertion = lambda do
349
- expect(record).to validate_numericality.only_integer
350
- end
351
-
352
- message = <<-MESSAGE
353
- Expected Example to validate that :attr looks like an integer, but this
354
- could not be proved.
355
- After setting :attr to ‹"0.1"›, the matcher expected the Example to be
356
- invalid, but it was valid instead.
357
- MESSAGE
358
-
359
- expect(&assertion).to fail_with_message(message)
360
- end
361
- end
362
- end
363
-
364
- context 'qualified with odd' do
365
- context 'and validating with odd' do
366
- it 'accepts' do
367
- record = build_record_validating_numericality(odd: true)
368
- expect(record).to validate_numericality.odd
369
- end
370
-
371
- it_supports(
372
- 'ignoring_interference_by_writer',
373
- tests: {
374
- accept_if_qualified_but_changing_value_does_not_interfere: {
375
- changing_values_with: :next_next_value,
376
- },
377
- reject_if_qualified_but_changing_value_interferes: {
378
- model_name: 'Example',
379
- attribute_name: :attr,
380
- changing_values_with: :next_value,
381
- expected_message: <<-MESSAGE.strip
382
- Expected Example to validate that :attr looks like an odd number, but
383
- this could not be proved.
384
- After setting :attr to ‹"2"› -- which was read back as ‹"3"› -- the
385
- matcher expected the Example to be invalid, but it was valid instead.
386
-
387
- As indicated in the message above, :attr seems to be changing certain
388
- values as they are set, and this could have something to do with why
389
- this test is failing. If you've overridden the writer method for this
390
- attribute, then you may need to change it to make this test pass, or
391
- do something else entirely.
392
- MESSAGE
393
- }
394
- }
395
- ) do
396
- def validation_matcher_scenario_args
397
- super.deep_merge(validation_options: { odd: true })
398
- end
399
-
400
- def configure_validation_matcher(matcher)
401
- matcher.odd
402
- end
403
- end
404
-
405
- context 'when the attribute is a virtual attribute in ActiveRecord model' do
406
- it 'accepts' do
407
- record = build_record_validating_numericality_of_virtual_attribute(
408
- odd: true
409
- )
410
- expect(record).to validate_numericality.odd
411
- end
412
- end
413
-
414
- context 'when the column is an integer column' do
415
- it 'accepts (and does not raise an error)' do
416
- record = build_record_validating_numericality(
417
- column_type: :integer,
418
- odd: true
419
- )
420
-
421
- expect(record).to validate_numericality.odd
422
- end
423
- end
424
-
425
- context 'when the column is a float column' do
426
- it 'accepts (and does not raise an error)' do
427
- record = build_record_validating_numericality(
428
- column_type: :float,
429
- odd: true
430
- )
431
-
432
- expect(record).to validate_numericality.odd
433
- end
434
- end
435
-
436
- context 'when the column is a decimal column' do
437
- it 'accepts (and does not raise an error)' do
438
- record = build_record_validating_numericality(
439
- column_type: :decimal,
440
- odd: true,
441
- )
442
-
443
- expect(record).to validate_numericality.odd
444
- end
445
- end
446
- end
447
-
448
- context 'and not validating with odd' do
449
- it 'rejects since it does not disallow even numbers' do
450
- record = build_record_validating_numericality
451
-
452
- assertion = lambda do
453
- expect(record).to validate_numericality.odd
454
- end
455
-
456
- message = <<-MESSAGE
457
- Expected Example to validate that :attr looks like an odd number, but
458
- this could not be proved.
459
- After setting :attr to ‹"2"›, the matcher expected the Example to be
460
- invalid, but it was valid instead.
461
- MESSAGE
462
-
463
- expect(&assertion).to fail_with_message(message)
464
- end
465
- end
466
- end
467
-
468
- context 'qualified with even' do
469
- context 'and validating with even' do
470
- it 'accepts' do
471
- record = build_record_validating_numericality(even: true)
472
- expect(record).to validate_numericality.even
473
- end
474
-
475
- it_supports(
476
- 'ignoring_interference_by_writer',
477
- tests: {
478
- accept_if_qualified_but_changing_value_does_not_interfere: {
479
- changing_values_with: :next_next_value,
480
- },
481
- reject_if_qualified_but_changing_value_interferes: {
482
- model_name: 'Example',
483
- attribute_name: :attr,
484
- changing_values_with: :next_value,
485
- expected_message: <<-MESSAGE.strip
486
- Expected Example to validate that :attr looks like an even number, but
487
- this could not be proved.
488
- After setting :attr to ‹"1"› -- which was read back as ‹"2"› -- the
489
- matcher expected the Example to be invalid, but it was valid instead.
490
-
491
- As indicated in the message above, :attr seems to be changing certain
492
- values as they are set, and this could have something to do with why
493
- this test is failing. If you've overridden the writer method for this
494
- attribute, then you may need to change it to make this test pass, or
495
- do something else entirely.
496
- MESSAGE
497
- }
498
- }
499
- ) do
500
- def validation_matcher_scenario_args
501
- super.deep_merge(validation_options: { even: true })
502
- end
503
-
504
- def configure_validation_matcher(matcher)
505
- matcher.even
506
- end
507
- end
508
-
509
- context 'when the attribute is a virtual attribute in an ActiveRecord model' do
510
- it 'accepts' do
511
- record = build_record_validating_numericality_of_virtual_attribute(
512
- even: true,
513
- )
514
- expect(record).to validate_numericality.even
515
- end
516
- end
517
-
518
- context 'when the column is an integer column' do
519
- it 'accepts (and does not raise an error)' do
520
- record = build_record_validating_numericality(
521
- column_type: :integer,
522
- even: true
523
- )
524
-
525
- expect(record).to validate_numericality.even
526
- end
527
- end
528
-
529
- context 'when the column is a float column' do
530
- it 'accepts (and does not raise an error)' do
531
- record = build_record_validating_numericality(
532
- column_type: :float,
533
- even: true
534
- )
535
-
536
- expect(record).to validate_numericality.even
537
- end
538
- end
539
-
540
- context 'when the column is a decimal column' do
541
- it 'accepts (and does not raise an error)' do
542
- record = build_record_validating_numericality(
543
- column_type: :decimal,
544
- even: true,
545
- )
546
-
547
- expect(record).to validate_numericality.even
548
- end
549
- end
550
- end
551
-
552
- context 'and not validating with even' do
553
- it 'rejects since it does not disallow odd numbers' do
554
- record = build_record_validating_numericality
555
-
556
- assertion = lambda do
557
- expect(record).to validate_numericality.even
558
- end
559
-
560
- message = <<-MESSAGE
561
- Expected Example to validate that :attr looks like an even number, but
562
- this could not be proved.
563
- After setting :attr to ‹"1"›, the matcher expected the Example to be
564
- invalid, but it was valid instead.
565
- MESSAGE
566
-
567
- expect(&assertion).to fail_with_message(message)
568
- end
569
- end
570
- end
571
-
572
- context 'qualified with is_less_than_or_equal_to' do
573
- context 'and validating with less_than_or_equal_to' do
574
- it 'accepts' do
575
- record = build_record_validating_numericality(
576
- less_than_or_equal_to: 18
577
- )
578
- expect(record).to validate_numericality.is_less_than_or_equal_to(18)
579
- end
580
-
581
- it_supports(
582
- 'ignoring_interference_by_writer',
583
- tests: {
584
- reject_if_qualified_but_changing_value_interferes: {
585
- model_name: 'Example',
586
- attribute_name: :attr,
587
- changing_values_with: :next_value,
588
- expected_message: <<-MESSAGE.strip
589
- Expected Example to validate that :attr looks like a number less than or
590
- equal to 18, but this could not be proved.
591
- After setting :attr to ‹"18"› -- which was read back as ‹"19"› -- the
592
- matcher expected the Example to be valid, but it was invalid instead,
593
- producing these validation errors:
594
-
595
- * attr: ["must be less than or equal to 18"]
596
-
597
- As indicated in the message above, :attr seems to be changing certain
598
- values as they are set, and this could have something to do with why
599
- this test is failing. If you've overridden the writer method for this
600
- attribute, then you may need to change it to make this test pass, or
601
- do something else entirely.
602
- MESSAGE
603
- }
604
- }
605
- ) do
606
- def validation_matcher_scenario_args
607
- super.deep_merge(
608
- validation_options: { less_than_or_equal_to: 18 }
609
- )
610
- end
611
-
612
- def configure_validation_matcher(matcher)
613
- matcher.is_less_than_or_equal_to(18)
614
- end
615
- end
616
-
617
- context 'when the attribute is a virtual attribute in an ActiveRecord model' do
618
- it 'accepts' do
619
- record = build_record_validating_numericality_of_virtual_attribute(
620
- less_than_or_equal_to: 18,
621
- )
622
- expect(record).to validate_numericality.is_less_than_or_equal_to(18)
623
- end
624
- end
625
-
626
- context 'when the column is an integer column' do
627
- it 'accepts (and does not raise an error)' do
628
- record = build_record_validating_numericality(
629
- column_type: :integer,
630
- less_than_or_equal_to: 18
631
- )
632
-
633
- expect(record).to validate_numericality.is_less_than_or_equal_to(18)
634
- end
635
- end
636
-
637
- context 'when the column is a float column' do
638
- it 'accepts (and does not raise an error)' do
639
- record = build_record_validating_numericality(
640
- column_type: :float,
641
- less_than_or_equal_to: 18
642
- )
643
-
644
- expect(record).to validate_numericality.is_less_than_or_equal_to(18)
645
- end
646
- end
647
-
648
- context 'when the column is a decimal column' do
649
- it 'accepts (and does not raise an error)' do
650
- record = build_record_validating_numericality(
651
- column_type: :decimal,
652
- less_than_or_equal_to: 18,
653
- )
654
-
655
- expect(record).to validate_numericality.is_less_than_or_equal_to(18)
656
- end
657
- end
658
- end
659
-
660
- context 'and not validating with less_than_or_equal_to' do
661
- it 'rejects since it does not disallow numbers greater than the value' do
662
- record = build_record_validating_numericality
663
-
664
- assertion = lambda do
665
- expect(record).to validate_numericality.is_less_than_or_equal_to(18)
666
- end
667
-
668
- message = <<-MESSAGE
669
- Expected Example to validate that :attr looks like a number less than or
670
- equal to 18, but this could not be proved.
671
- After setting :attr to ‹"19"›, the matcher expected the Example to be
672
- invalid, but it was valid instead.
673
- MESSAGE
674
-
675
- expect(&assertion).to fail_with_message(message)
676
- end
677
- end
678
- end
679
-
680
- context 'qualified with is_less_than' do
681
- context 'and validating with less_than' do
682
- it 'accepts' do
683
- record = build_record_validating_numericality(less_than: 18)
684
- expect(record).
685
- to validate_numericality.
686
- is_less_than(18)
687
- end
688
-
689
- it_supports(
690
- 'ignoring_interference_by_writer',
691
- tests: {
692
- reject_if_qualified_but_changing_value_interferes: {
693
- model_name: 'Example',
694
- attribute_name: :attr,
695
- changing_values_with: :next_value,
696
- expected_message: <<-MESSAGE.strip
697
- Expected Example to validate that :attr looks like a number less than
698
- 18, but this could not be proved.
699
- After setting :attr to ‹"17"› -- which was read back as ‹"18"› -- the
700
- matcher expected the Example to be valid, but it was invalid instead,
701
- producing these validation errors:
702
-
703
- * attr: ["must be less than 18"]
704
-
705
- As indicated in the message above, :attr seems to be changing certain
706
- values as they are set, and this could have something to do with why
707
- this test is failing. If you've overridden the writer method for this
708
- attribute, then you may need to change it to make this test pass, or
709
- do something else entirely.
710
- MESSAGE
711
- }
712
- }
713
- ) do
714
- def validation_matcher_scenario_args
715
- super.deep_merge(validation_options: { less_than: 18 })
716
- end
717
-
718
- def configure_validation_matcher(matcher)
719
- matcher.is_less_than(18)
720
- end
721
- end
722
-
723
- context 'when the attribute is a virtual attribute in an ActiveRecord model' do
724
- it 'accepts' do
725
- record = build_record_validating_numericality_of_virtual_attribute(
726
- less_than: 18,
727
- )
728
- expect(record).to validate_numericality.is_less_than(18)
729
- end
730
- end
731
-
732
- context 'when the column is an integer column' do
733
- it 'accepts (and does not raise an error)' do
734
- record = build_record_validating_numericality(
735
- column_type: :integer,
736
- less_than: 18
737
- )
738
-
739
- expect(record).to validate_numericality.is_less_than(18)
740
- end
741
- end
742
-
743
- context 'when the column is a float column' do
744
- it 'accepts (and does not raise an error)' do
745
- record = build_record_validating_numericality(
746
- column_type: :float,
747
- less_than: 18
748
- )
749
-
750
- expect(record).to validate_numericality.is_less_than(18)
751
- end
752
- end
753
-
754
- context 'when the column is a decimal column' do
755
- it 'accepts (and does not raise an error)' do
756
- record = build_record_validating_numericality(
757
- column_type: :decimal,
758
- less_than: 18,
759
- )
760
-
761
- expect(record).to validate_numericality.is_less_than(18)
762
- end
763
- end
764
- end
765
-
766
- context 'and not validating with less_than' do
767
- it 'rejects since it does not disallow numbers greater than or equal to the value' do
768
- record = build_record_validating_numericality
769
-
770
- assertion = lambda do
771
- expect(record).to validate_numericality.is_less_than(18)
772
- end
773
-
774
- message = <<-MESSAGE
775
- Expected Example to validate that :attr looks like a number less than
776
- 18, but this could not be proved.
777
- After setting :attr to ‹"19"›, the matcher expected the Example to be
778
- invalid, but it was valid instead.
779
- MESSAGE
780
-
781
- expect(&assertion).to fail_with_message(message)
782
- end
783
- end
784
- end
785
-
786
- context 'qualified with is_equal_to' do
787
- context 'and validating with equal_to' do
788
- it 'accepts' do
789
- record = build_record_validating_numericality(equal_to: 18)
790
- expect(record).to validate_numericality.is_equal_to(18)
791
- end
792
-
793
- it_supports(
794
- 'ignoring_interference_by_writer',
795
- tests: {
796
- reject_if_qualified_but_changing_value_interferes: {
797
- model_name: 'Example',
798
- attribute_name: :attr,
799
- changing_values_with: :next_value,
800
- expected_message: <<-MESSAGE.strip
801
- Expected Example to validate that :attr looks like a number equal to 18,
802
- but this could not be proved.
803
- After setting :attr to ‹"18"› -- which was read back as ‹"19"› -- the
804
- matcher expected the Example to be valid, but it was invalid instead,
805
- producing these validation errors:
806
-
807
- * attr: ["must be equal to 18"]
808
-
809
- As indicated in the message above, :attr seems to be changing certain
810
- values as they are set, and this could have something to do with why
811
- this test is failing. If you've overridden the writer method for this
812
- attribute, then you may need to change it to make this test pass, or
813
- do something else entirely.
814
- MESSAGE
815
- }
816
- }
817
- ) do
818
- def validation_matcher_scenario_args
819
- super.deep_merge(validation_options: { equal_to: 18 })
820
- end
821
-
822
- def configure_validation_matcher(matcher)
823
- matcher.is_equal_to(18)
824
- end
825
- end
826
-
827
- context 'when the attribute is a virtual attribute in an ActiveRecord model' do
828
- it 'accepts' do
829
- record = build_record_validating_numericality_of_virtual_attribute(
830
- equal_to: 18,
831
- )
832
- expect(record).to validate_numericality.is_equal_to(18)
833
- end
834
- end
835
-
836
- context 'when the column is an integer column' do
837
- it 'accepts (and does not raise an error)' do
838
- record = build_record_validating_numericality(
839
- column_type: :integer,
840
- equal_to: 18
841
- )
842
-
843
- expect(record).to validate_numericality.is_equal_to(18)
844
- end
845
- end
846
-
847
- context 'when the column is a float column' do
848
- it 'accepts (and does not raise an error)' do
849
- record = build_record_validating_numericality(
850
- column_type: :float,
851
- equal_to: 18
852
- )
853
-
854
- expect(record).to validate_numericality.is_equal_to(18)
855
- end
856
- end
857
-
858
- context 'when the column is a decimal column' do
859
- it 'accepts (and does not raise an error)' do
860
- record = build_record_validating_numericality(
861
- column_type: :decimal,
862
- equal_to: 18,
863
- )
864
-
865
- expect(record).to validate_numericality.is_equal_to(18)
866
- end
867
- end
868
- end
869
-
870
- context 'and not validating with equal_to' do
871
- it 'rejects since it does not disallow numbers that are not the value' do
872
- record = build_record_validating_numericality
873
-
874
- assertion = lambda do
875
- expect(record).to validate_numericality.is_equal_to(18)
876
- end
877
-
878
- message = <<-MESSAGE
879
- Expected Example to validate that :attr looks like a number equal to 18,
880
- but this could not be proved.
881
- After setting :attr to ‹"19"›, the matcher expected the Example to be
882
- invalid, but it was valid instead.
883
- MESSAGE
884
-
885
- expect(&assertion).to fail_with_message(message)
886
- end
887
- end
888
- end
889
-
890
- context 'qualified with is_greater_than_or_equal to' do
891
- context 'validating with greater_than_or_equal_to' do
892
- it 'accepts' do
893
- record = build_record_validating_numericality(
894
- greater_than_or_equal_to: 18
895
- )
896
- expect(record).
897
- to validate_numericality.
898
- is_greater_than_or_equal_to(18)
899
- end
900
-
901
- it_supports(
902
- 'ignoring_interference_by_writer',
903
- tests: {
904
- reject_if_qualified_but_changing_value_interferes: {
905
- model_name: 'Example',
906
- attribute_name: :attr,
907
- changing_values_with: :next_value,
908
- expected_message: <<-MESSAGE.strip
909
- Expected Example to validate that :attr looks like a number greater than
910
- or equal to 18, but this could not be proved.
911
- After setting :attr to ‹"17"› -- which was read back as ‹"18"› -- the
912
- matcher expected the Example to be invalid, but it was valid instead.
913
-
914
- As indicated in the message above, :attr seems to be changing certain
915
- values as they are set, and this could have something to do with why
916
- this test is failing. If you've overridden the writer method for this
917
- attribute, then you may need to change it to make this test pass, or
918
- do something else entirely.
919
- MESSAGE
920
- }
921
- }
922
- ) do
923
- def validation_matcher_scenario_args
924
- super.deep_merge(
925
- validation_options: { greater_than_or_equal_to: 18 }
926
- )
927
- end
928
-
929
- def configure_validation_matcher(matcher)
930
- matcher.is_greater_than_or_equal_to(18)
931
- end
932
- end
933
-
934
- context 'when the attribute is a virtual attribute in an ActiveRecord model' do
935
- it 'accepts' do
936
- record = build_record_validating_numericality_of_virtual_attribute(
937
- greater_than_or_equal_to: 18,
938
- )
939
- expect(record).to validate_numericality.
940
- is_greater_than_or_equal_to(18)
941
- end
942
- end
943
-
944
- context 'when the column is an integer column' do
945
- it 'accepts (and does not raise an error)' do
946
- record = build_record_validating_numericality(
947
- column_type: :integer,
948
- greater_than_or_equal_to: 18
949
- )
950
-
951
- expect(record).
952
- to validate_numericality.
953
- is_greater_than_or_equal_to(18)
954
- end
955
- end
956
-
957
- context 'when the column is a float column' do
958
- it 'accepts (and does not raise an error)' do
959
- record = build_record_validating_numericality(
960
- column_type: :float,
961
- greater_than_or_equal_to: 18
962
- )
963
-
964
- expect(record).
965
- to validate_numericality.
966
- is_greater_than_or_equal_to(18)
967
- end
968
- end
969
-
970
- context 'when the column is a decimal column' do
971
- it 'accepts (and does not raise an error)' do
972
- record = build_record_validating_numericality(
973
- column_type: :decimal,
974
- greater_than_or_equal_to: 18,
975
- )
976
-
977
- expect(record).
978
- to validate_numericality.
979
- is_greater_than_or_equal_to(18)
980
- end
981
- end
982
- end
983
-
984
- context 'not validating with greater_than_or_equal_to' do
985
- it 'rejects since it does not disallow numbers that are less than the value' do
986
- record = build_record_validating_numericality
987
-
988
- assertion = lambda do
989
- expect(record).to validate_numericality.
990
- is_greater_than_or_equal_to(18)
991
- end
992
-
993
- message = <<-MESSAGE
994
- Expected Example to validate that :attr looks like a number greater than
995
- or equal to 18, but this could not be proved.
996
- After setting :attr to ‹"17"›, the matcher expected the Example to be
997
- invalid, but it was valid instead.
998
- MESSAGE
999
-
1000
- expect(&assertion).to fail_with_message(message)
1001
- end
1002
- end
1003
- end
1004
-
1005
- context 'qualified with is_greater_than' do
1006
- context 'and validating with greater_than' do
1007
- it 'accepts' do
1008
- record = build_record_validating_numericality(greater_than: 18)
1009
- expect(record).
1010
- to validate_numericality.
1011
- is_greater_than(18)
1012
- end
1013
-
1014
- it_supports(
1015
- 'ignoring_interference_by_writer',
1016
- tests: {
1017
- reject_if_qualified_but_changing_value_interferes: {
1018
- model_name: 'Example',
1019
- attribute_name: :attr,
1020
- changing_values_with: :next_value,
1021
- expected_message: <<-MESSAGE.strip
1022
- Expected Example to validate that :attr looks like a number greater than
1023
- 18, but this could not be proved.
1024
- After setting :attr to ‹"18"› -- which was read back as ‹"19"› -- the
1025
- matcher expected the Example to be invalid, but it was valid instead.
1026
-
1027
- As indicated in the message above, :attr seems to be changing certain
1028
- values as they are set, and this could have something to do with why
1029
- this test is failing. If you've overridden the writer method for this
1030
- attribute, then you may need to change it to make this test pass, or
1031
- do something else entirely.
1032
- MESSAGE
1033
- }
1034
- }
1035
- ) do
1036
- def validation_matcher_scenario_args
1037
- super.deep_merge(validation_options: { greater_than: 18 })
1038
- end
1039
-
1040
- def configure_validation_matcher(matcher)
1041
- matcher.is_greater_than(18)
1042
- end
1043
- end
1044
-
1045
- context 'when the attribute is a virtual attribute in an ActiveRecord model' do
1046
- it 'accepts' do
1047
- record = build_record_validating_numericality_of_virtual_attribute(
1048
- greater_than: 18,
1049
- )
1050
- expect(record).to validate_numericality.is_greater_than(18)
1051
- end
1052
- end
1053
-
1054
- context 'when the column is an integer column' do
1055
- it 'accepts (and does not raise an error)' do
1056
- record = build_record_validating_numericality(
1057
- column_type: :integer,
1058
- greater_than: 18
1059
- )
1060
-
1061
- expect(record).
1062
- to validate_numericality.
1063
- is_greater_than(18)
1064
- end
1065
- end
1066
-
1067
- context 'when the column is a float column' do
1068
- it 'accepts (and does not raise an error)' do
1069
- record = build_record_validating_numericality(
1070
- column_type: :float,
1071
- greater_than: 18
1072
- )
1073
-
1074
- expect(record).
1075
- to validate_numericality.
1076
- is_greater_than(18)
1077
- end
1078
- end
1079
-
1080
- context 'when the column is a decimal column' do
1081
- it 'accepts (and does not raise an error)' do
1082
- record = build_record_validating_numericality(
1083
- column_type: :decimal,
1084
- greater_than: 18,
1085
- )
1086
-
1087
- expect(record).
1088
- to validate_numericality.
1089
- is_greater_than(18)
1090
- end
1091
- end
1092
- end
1093
-
1094
- context 'and not validating with greater_than' do
1095
- it 'rejects since it does not disallow numbers that are less than or equal to the value' do
1096
- record = build_record_validating_numericality
1097
-
1098
- assertion = lambda do
1099
- expect(record).to validate_numericality.is_greater_than(18)
1100
- end
1101
-
1102
- message = <<-MESSAGE
1103
- Expected Example to validate that :attr looks like a number greater than
1104
- 18, but this could not be proved.
1105
- After setting :attr to ‹"18"›, the matcher expected the Example to be
1106
- invalid, but it was valid instead.
1107
- MESSAGE
1108
-
1109
- expect(&assertion).to fail_with_message(message)
1110
- end
1111
- end
1112
- end
1113
-
1114
- context 'qualified with with_message' do
1115
- context 'and validating with the same message' do
1116
- it 'accepts' do
1117
- record = build_record_validating_numericality(message: 'custom')
1118
- expect(record).to validate_numericality.with_message(/custom/)
1119
- end
1120
- end
1121
-
1122
- context 'and validating with a different message' do
1123
- it 'rejects with the correct failure message' do
1124
- record = build_record_validating_numericality(message: 'custom')
1125
-
1126
- assertion = lambda do
1127
- expect(record).to validate_numericality.with_message(/wrong/)
1128
- end
1129
-
1130
- message = <<-MESSAGE
1131
- Expected Example to validate that :attr looks like a number, producing a
1132
- custom validation error on failure, but this could not be proved.
1133
- After setting :attr to ‹"abcd"›, the matcher expected the Example to
1134
- be invalid and to produce a validation error matching ‹/wrong/› on
1135
- :attr. The record was indeed invalid, but it produced these validation
1136
- errors instead:
1137
-
1138
- * attr: ["custom"]
1139
- MESSAGE
1140
-
1141
- expect(&assertion).to fail_with_message(message)
1142
- end
1143
- end
1144
-
1145
- context 'and no message is provided' do
1146
- it 'ignores the qualifier' do
1147
- record = build_record_validating_numericality
1148
- expect(record).to validate_numericality.with_message(nil)
1149
- end
1150
- end
1151
-
1152
- context 'and the validation is missing from the model' do
1153
- it 'rejects with the correct failure message' do
1154
- model = define_model_validating_nothing
1155
-
1156
- assertion = lambda do
1157
- expect(model.new).to validate_numericality.with_message(/wrong/)
1158
- end
1159
-
1160
- message = <<-MESSAGE
1161
- Expected Example to validate that :attr looks like a number, producing a
1162
- custom validation error on failure, but this could not be proved.
1163
- After setting :attr to ‹"abcd"›, the matcher expected the Example to
1164
- be invalid, but it was valid instead.
1165
- MESSAGE
1166
-
1167
- expect(&assertion).to fail_with_message(message)
1168
- end
1169
- end
1170
- end
1171
-
1172
- context 'qualified with strict' do
1173
- context 'and validating strictly' do
1174
- it 'accepts' do
1175
- record = build_record_validating_numericality(strict: true)
1176
- expect(record).to validate_numericality.strict
1177
- end
1178
- end
1179
-
1180
- context 'and not validating strictly' do
1181
- it 'rejects since ActiveModel::StrictValidationFailed is never raised' do
1182
- record = build_record_validating_numericality(attribute_name: :attr)
1183
-
1184
- assertion = lambda do
1185
- expect(record).to validate_numericality_of(:attr).strict
1186
- end
1187
-
1188
- message = <<-MESSAGE
1189
- Expected Example to validate that :attr looks like a number, raising a
1190
- validation exception on failure, but this could not be proved.
1191
- After setting :attr to ‹"abcd"›, the matcher expected the Example to
1192
- be invalid and to raise a validation exception, but the record
1193
- produced validation errors instead.
1194
- MESSAGE
1195
-
1196
- expect(&assertion).to fail_with_message(message)
1197
- end
1198
- end
1199
- end
1200
-
1201
- context 'qualified with on and validating with on' do
1202
- it 'accepts' do
1203
- record = build_record_validating_numericality(on: :customizable)
1204
- expect(record).to validate_numericality.on(:customizable)
1205
- end
1206
- end
1207
-
1208
- context 'qualified with on but not validating with on' do
1209
- it 'accepts since the validation never considers a context' do
1210
- record = build_record_validating_numericality
1211
- expect(record).to validate_numericality.on(:customizable)
1212
- end
1213
- end
1214
-
1215
- context 'not qualified with on but validating with on' do
1216
- it 'rejects since the validation never runs' do
1217
- record = build_record_validating_numericality(on: :customizable)
1218
-
1219
- assertion = lambda do
1220
- expect(record).to validate_numericality
1221
- end
1222
-
1223
- message = <<-MESSAGE
1224
- Expected Example to validate that :attr looks like a number, but this
1225
- could not be proved.
1226
- After setting :attr to ‹"abcd"›, the matcher expected the Example to
1227
- be invalid, but it was valid instead.
1228
- MESSAGE
1229
-
1230
- expect(&assertion).to fail_with_message(message)
1231
- end
1232
- end
1233
-
1234
- context 'with combinations of qualifiers together' do
1235
- all_qualifier_combinations.each do |combination|
1236
- if combination.size > 1
1237
- it do
1238
- validation_options = build_validation_options(for: combination)
1239
- record = build_record_validating_numericality(validation_options)
1240
- validate_numericality = self.validate_numericality
1241
- apply_qualifiers!(for: combination, to: validate_numericality)
1242
- expect(record).to validate_numericality
1243
- end
1244
- end
1245
- end
1246
-
1247
- context 'when the qualifiers do not match the validation options' do
1248
- specify 'such as validating even but testing that only_integer is validated' do
1249
- record = build_record_validating_numericality(
1250
- even: true,
1251
- greater_than: 18
1252
- )
1253
-
1254
- assertion = lambda do
1255
- expect(record).
1256
- to validate_numericality.
1257
- only_integer.
1258
- is_greater_than(18)
1259
- end
1260
-
1261
- message = <<-MESSAGE
1262
- Expected Example to validate that :attr looks like an integer greater
1263
- than 18, but this could not be proved.
1264
- In checking that Example disallows :attr from being a decimal number,
1265
- after setting :attr to ‹"0.1"›, the matcher expected the Example to be
1266
- invalid and to produce the validation error "must be an integer" on
1267
- :attr. The record was indeed invalid, but it produced these validation
1268
- errors instead:
1269
-
1270
- * attr: ["must be greater than 18"]
1271
- MESSAGE
1272
-
1273
- expect(&assertion).to fail_with_message(message)
1274
- end
1275
-
1276
- specify 'such as not validating only_integer but testing that only_integer is validated' do
1277
- record = build_record_validating_numericality(greater_than: 18)
1278
-
1279
- assertion = lambda do
1280
- expect(record).
1281
- to validate_numericality.
1282
- only_integer.
1283
- is_greater_than(18)
1284
- end
1285
-
1286
- message = <<-MESSAGE.strip_heredoc
1287
- Expected Example to validate that :attr looks like an integer greater
1288
- than 18, but this could not be proved.
1289
- In checking that Example disallows :attr from being a decimal number,
1290
- after setting :attr to ‹"0.1"›, the matcher expected the Example to be
1291
- invalid and to produce the validation error "must be an integer" on
1292
- :attr. The record was indeed invalid, but it produced these validation
1293
- errors instead:
1294
-
1295
- * attr: ["must be greater than 18"]
1296
- MESSAGE
1297
-
1298
- expect(&assertion).to fail_with_message(message)
1299
- end
1300
-
1301
- specify 'such as validating greater_than_or_equal_to (+ even) but testing that greater_than is validated' do
1302
- record = build_record_validating_numericality(
1303
- even: true,
1304
- greater_than_or_equal_to: 18
1305
- )
1306
-
1307
- assertion = lambda do
1308
- expect(record).
1309
- to validate_numericality.
1310
- even.
1311
- is_greater_than(18)
1312
- end
1313
-
1314
- message = <<-MESSAGE
1315
- Expected Example to validate that :attr looks like an even number
1316
- greater than 18, but this could not be proved.
1317
- In checking that Example disallows :attr from being a number that is
1318
- not greater than 18, after setting :attr to ‹"18"›, the matcher
1319
- expected the Example to be invalid, but it was valid instead.
1320
- MESSAGE
1321
-
1322
- expect(&assertion).to fail_with_message(message)
1323
- end
1324
-
1325
- specify 'such as validating odd (+ greater_than) but testing that even is validated' do
1326
- record = build_record_validating_numericality(
1327
- odd: true,
1328
- greater_than: 18
1329
- )
1330
-
1331
- assertion = lambda do
1332
- expect(record).
1333
- to validate_numericality.
1334
- even.
1335
- is_greater_than(18)
1336
- end
1337
-
1338
- message = <<-MESSAGE
1339
- Expected Example to validate that :attr looks like an even number
1340
- greater than 18, but this could not be proved.
1341
- In checking that Example disallows :attr from being an odd number,
1342
- after setting :attr to ‹"1"›, the matcher expected the Example to be
1343
- invalid and to produce the validation error "must be even" on :attr.
1344
- The record was indeed invalid, but it produced these validation errors
1345
- instead:
1346
-
1347
- * attr: ["must be greater than 18"]
1348
- MESSAGE
1349
-
1350
- expect(&assertion).to fail_with_message(message)
1351
- end
1352
-
1353
- specify 'such as validating greater_than_or_equal_to (+ odd) but testing that is_less_than_or_equal_to is validated' do
1354
- record = build_record_validating_numericality(
1355
- odd: true,
1356
- greater_than_or_equal_to: 99
1357
- )
1358
-
1359
- assertion = lambda do
1360
- expect(record).
1361
- to validate_numericality.
1362
- odd.
1363
- is_less_than_or_equal_to(99)
1364
- end
1365
-
1366
- message = <<-MESSAGE
1367
- Expected Example to validate that :attr looks like an odd number less
1368
- than or equal to 99, but this could not be proved.
1369
- In checking that Example disallows :attr from being a number that is
1370
- not less than or equal to 99, after setting :attr to ‹"101"›, the
1371
- matcher expected the Example to be invalid, but it was valid instead.
1372
- MESSAGE
1373
-
1374
- expect(&assertion).to fail_with_message(message)
1375
- end
1376
-
1377
- specify 'such as validating greater_than_or_equal_to (+ only_integer + less_than) but testing that greater_than is validated' do
1378
- record = build_record_validating_numericality(
1379
- only_integer: true,
1380
- greater_than_or_equal_to: 18,
1381
- less_than: 99
1382
- )
1383
-
1384
- assertion = lambda do
1385
- expect(record).
1386
- to validate_numericality.
1387
- only_integer.
1388
- is_greater_than(18).
1389
- is_less_than(99)
1390
- end
1391
-
1392
- message = <<-MESSAGE
1393
- Expected Example to validate that :attr looks like an integer greater
1394
- than 18 and less than 99, but this could not be proved.
1395
- In checking that Example disallows :attr from being a number that is
1396
- not greater than 18, after setting :attr to ‹"18"›, the matcher
1397
- expected the Example to be invalid, but it was valid instead.
1398
- MESSAGE
1399
-
1400
- expect(&assertion).to fail_with_message(message)
1401
- end
1402
- end
1403
-
1404
- context 'when qualifiers match the validation options but the values are different' do
1405
- specify 'such as testing greater_than (+ only_integer) with lower value' do
1406
- record = build_record_validating_numericality(
1407
- only_integer: true,
1408
- greater_than: 19
1409
- )
1410
-
1411
- assertion = lambda do
1412
- expect(record).
1413
- to validate_numericality.
1414
- only_integer.
1415
- is_greater_than(18)
1416
- end
1417
-
1418
- message = <<-MESSAGE
1419
- Expected Example to validate that :attr looks like an integer greater
1420
- than 18, but this could not be proved.
1421
- In checking that Example disallows :attr from being a number that is
1422
- not greater than 18, after setting :attr to ‹"18"›, the matcher
1423
- expected the Example to be invalid and to produce the validation error
1424
- "must be greater than 18" on :attr. The record was indeed invalid, but
1425
- it produced these validation errors instead:
1426
-
1427
- * attr: ["must be greater than 19"]
1428
- MESSAGE
1429
-
1430
- expect(&assertion).to fail_with_message(message)
1431
- end
1432
-
1433
- specify 'such as testing greater_than (+ only_integer) with higher value' do
1434
- record = build_record_validating_numericality(
1435
- only_integer: true,
1436
- greater_than: 17
1437
- )
1438
-
1439
- assertion = lambda do
1440
- expect(record).
1441
- to validate_numericality.
1442
- only_integer.
1443
- is_greater_than(18)
1444
- end
1445
-
1446
- message = <<-MESSAGE
1447
- Expected Example to validate that :attr looks like an integer greater
1448
- than 18, but this could not be proved.
1449
- In checking that Example disallows :attr from being a number that is
1450
- not greater than 18, after setting :attr to ‹"18"›, the matcher
1451
- expected the Example to be invalid, but it was valid instead.
1452
- MESSAGE
1453
-
1454
- expect(&assertion).to fail_with_message(message)
1455
- end
1456
-
1457
- specify 'such as testing greater_than (+ even) with lower value' do
1458
- record = build_record_validating_numericality(
1459
- even: true,
1460
- greater_than: 20
1461
- )
1462
-
1463
- assertion = lambda do
1464
- expect(record).
1465
- to validate_numericality.
1466
- even.
1467
- is_greater_than(18)
1468
- end
1469
-
1470
- message = <<-MESSAGE
1471
- Expected Example to validate that :attr looks like an even number
1472
- greater than 18, but this could not be proved.
1473
- In checking that Example disallows :attr from being a number that is
1474
- not greater than 18, after setting :attr to ‹"18"›, the matcher
1475
- expected the Example to be invalid and to produce the validation error
1476
- "must be greater than 18" on :attr. The record was indeed invalid, but
1477
- it produced these validation errors instead:
1478
-
1479
- * attr: ["must be greater than 20"]
1480
- MESSAGE
1481
-
1482
- expect(&assertion).to fail_with_message(message)
1483
- end
1484
-
1485
- specify 'such as testing greater than (+ even) with higher value' do
1486
- record = build_record_validating_numericality(
1487
- even: true,
1488
- greater_than: 16
1489
- )
1490
-
1491
- assertion = lambda do
1492
- expect(record).
1493
- to validate_numericality.
1494
- even.
1495
- is_greater_than(18)
1496
- end
1497
-
1498
- message = <<-MESSAGE
1499
- Expected Example to validate that :attr looks like an even number
1500
- greater than 18, but this could not be proved.
1501
- In checking that Example disallows :attr from being a number that is
1502
- not greater than 18, after setting :attr to ‹"18"›, the matcher
1503
- expected the Example to be invalid, but it was valid instead.
1504
- MESSAGE
1505
-
1506
- expect(&assertion).to fail_with_message(message)
1507
- end
1508
-
1509
- specify 'such as testing less_than_or_equal_to (+ odd) with lower value' do
1510
- record = build_record_validating_numericality(
1511
- odd: true,
1512
- less_than_or_equal_to: 101
1513
- )
1514
-
1515
- assertion = lambda do
1516
- expect(record).
1517
- to validate_numericality.
1518
- odd.
1519
- is_less_than_or_equal_to(99)
1520
- end
1521
-
1522
- message = <<-MESSAGE
1523
- Expected Example to validate that :attr looks like an odd number less
1524
- than or equal to 99, but this could not be proved.
1525
- In checking that Example disallows :attr from being a number that is
1526
- not less than or equal to 99, after setting :attr to ‹"101"›, the
1527
- matcher expected the Example to be invalid, but it was valid instead.
1528
- MESSAGE
1529
-
1530
- expect(&assertion).to fail_with_message(message)
1531
- end
1532
-
1533
- specify 'such as testing less_than_or_equal_to (+ odd) with higher value' do
1534
- record = build_record_validating_numericality(
1535
- odd: true,
1536
- less_than_or_equal_to: 97
1537
- )
1538
-
1539
- assertion = lambda do
1540
- expect(record).
1541
- to validate_numericality.
1542
- odd.
1543
- is_less_than_or_equal_to(99)
1544
- end
1545
-
1546
- message = <<-MESSAGE
1547
- Expected Example to validate that :attr looks like an odd number less
1548
- than or equal to 99, but this could not be proved.
1549
- In checking that Example disallows :attr from being a number that is
1550
- not less than or equal to 99, after setting :attr to ‹"101"›, the
1551
- matcher expected the Example to be invalid and to produce the
1552
- validation error "must be less than or equal to 99" on :attr. The
1553
- record was indeed invalid, but it produced these validation errors
1554
- instead:
1555
-
1556
- * attr: ["must be less than or equal to 97"]
1557
- MESSAGE
1558
-
1559
- expect(&assertion).to fail_with_message(message)
1560
- end
1561
-
1562
- specify 'such as testing greater_than (+ only_integer + less_than) with lower value' do
1563
- record = build_record_validating_numericality(
1564
- only_integer: true,
1565
- greater_than: 19,
1566
- less_than: 99
1567
- )
1568
-
1569
- assertion = lambda do
1570
- expect(record).
1571
- to validate_numericality.
1572
- only_integer.
1573
- is_greater_than(18).
1574
- is_less_than(99)
1575
- end
1576
-
1577
- message = <<-MESSAGE
1578
- Expected Example to validate that :attr looks like an integer greater
1579
- than 18 and less than 99, but this could not be proved.
1580
- In checking that Example disallows :attr from being a number that is
1581
- not greater than 18, after setting :attr to ‹"18"›, the matcher
1582
- expected the Example to be invalid and to produce the validation error
1583
- "must be greater than 18" on :attr. The record was indeed invalid, but
1584
- it produced these validation errors instead:
1585
-
1586
- * attr: ["must be greater than 19"]
1587
- MESSAGE
1588
-
1589
- expect(&assertion).to fail_with_message(message)
1590
- end
1591
-
1592
- specify 'such as testing less_than (+ only_integer + greater_than) with higher value' do
1593
- record = build_record_validating_numericality(
1594
- only_integer: true,
1595
- greater_than: 18,
1596
- less_than: 100
1597
- )
1598
-
1599
- assertion = lambda do
1600
- expect(record).
1601
- to validate_numericality.
1602
- only_integer.
1603
- is_greater_than(18).
1604
- is_less_than(99)
1605
- end
1606
-
1607
- message = <<-MESSAGE
1608
- Expected Example to validate that :attr looks like an integer greater
1609
- than 18 and less than 99, but this could not be proved.
1610
- In checking that Example disallows :attr from being a number that is
1611
- not less than 99, after setting :attr to ‹"100"›, the matcher expected
1612
- the Example to be invalid and to produce the validation error "must be
1613
- less than 99" on :attr. The record was indeed invalid, but it produced
1614
- these validation errors instead:
1615
-
1616
- * attr: ["must be less than 100"]
1617
- MESSAGE
1618
-
1619
- expect(&assertion).to fail_with_message(message)
1620
- end
1621
- end
1622
- end
1623
-
1624
- context 'with large numbers' do
1625
- it do
1626
- record = build_record_validating_numericality(greater_than: 100_000)
1627
- expect(record).to validate_numericality.is_greater_than(100_000)
1628
- end
1629
-
1630
- it do
1631
- record = build_record_validating_numericality(less_than: 100_000)
1632
- expect(record).to validate_numericality.is_less_than(100_000)
1633
- end
1634
-
1635
- it do
1636
- record = build_record_validating_numericality(
1637
- greater_than_or_equal_to: 100_000
1638
- )
1639
- expect(record).
1640
- to validate_numericality.
1641
- is_greater_than_or_equal_to(100_000)
1642
- end
1643
-
1644
- it do
1645
- record = build_record_validating_numericality(
1646
- less_than_or_equal_to: 100_000
1647
- )
1648
- expect(record).
1649
- to validate_numericality.
1650
- is_less_than_or_equal_to(100_000)
1651
- end
1652
- end
1653
-
1654
- context 'when the subject is stubbed' do
1655
- it 'retains that stub while the validate_numericality is matching' do
1656
- model = define_model :example, attr: :string do
1657
- validates_numericality_of :attr, odd: true
1658
- before_validation :set_attr!
1659
- def set_attr!; self.attr = 5 end
1660
- end
1661
-
1662
- record = model.new
1663
- allow(record).to receive(:set_attr!)
1664
-
1665
- expect(record).to validate_numericality_of(:attr).odd
1666
- end
1667
- end
1668
-
1669
- context 'against an ActiveModel model' do
1670
- it 'accepts' do
1671
- model = define_active_model_class :example, accessors: [:attr] do
1672
- validates_numericality_of :attr
1673
- end
1674
-
1675
- expect(model.new).to validate_numericality_of(:attr)
1676
- end
1677
-
1678
- it_supports(
1679
- 'ignoring_interference_by_writer',
1680
- tests: {
1681
- accept_if_qualified_but_changing_value_does_not_interfere: {
1682
- changing_values_with: :next_value,
1683
- },
1684
- reject_if_qualified_but_changing_value_interferes: {
1685
- model_name: 'Example',
1686
- attribute_name: :attr,
1687
- changing_values_with: :numeric_value,
1688
- expected_message: <<-MESSAGE.strip
1689
- Expected Example to validate that :attr looks like a number, but this
1690
- could not be proved.
1691
- After setting :attr to ‹"abcd"› -- which was read back as ‹"1"› -- the
1692
- matcher expected the Example to be invalid, but it was valid instead.
1693
-
1694
- As indicated in the message above, :attr seems to be changing certain
1695
- values as they are set, and this could have something to do with why
1696
- this test is failing. If you've overridden the writer method for this
1697
- attribute, then you may need to change it to make this test pass, or
1698
- do something else entirely.
1699
- MESSAGE
1700
- }
1701
- }
1702
- )
1703
-
1704
- def validation_matcher_scenario_args
1705
- super.deep_merge(model_creator: :active_model)
1706
- end
1707
- end
1708
-
1709
- describe '#description' do
1710
- context 'qualified with nothing' do
1711
- it 'describes that it allows numbers' do
1712
- matcher = validate_numericality_of(:attr)
1713
- expect(matcher.description).to eq(
1714
- 'validate that :attr looks like a number'
1715
- )
1716
- end
1717
- end
1718
-
1719
- context 'qualified with only_integer' do
1720
- it 'describes that it allows integers' do
1721
- matcher = validate_numericality_of(:attr).only_integer
1722
- expect(matcher.description).to eq(
1723
- 'validate that :attr looks like an integer'
1724
- )
1725
- end
1726
- end
1727
-
1728
- qualifiers_under(:cardinality).each do |qualifier|
1729
- context "qualified with #{qualifier[:name]}" do
1730
- it "describes that it allows #{qualifier[:name]} numbers" do
1731
- matcher = validate_numericality_of(:attr).__send__(qualifier[:name])
1732
- expect(matcher.description).to eq(
1733
- "validate that :attr looks like an #{qualifier[:name]} number"
1734
- )
1735
- end
1736
- end
1737
- end
1738
-
1739
- qualifiers_under(:comparison).each do |qualifier|
1740
- comparison_phrase = qualifier[:validation_name].to_s.gsub('_', ' ')
1741
-
1742
- context "qualified with #{qualifier[:name]}" do
1743
- it "describes that it allows numbers #{comparison_phrase} a certain value" do
1744
- matcher = validate_numericality_of(:attr).
1745
- __send__(qualifier[:name], 18)
1746
-
1747
- expect(matcher.description).to eq(
1748
- "validate that :attr looks like a number #{comparison_phrase} 18"
1749
- )
1750
- end
1751
- end
1752
- end
1753
-
1754
- context 'qualified with odd + is_greater_than_or_equal_to' do
1755
- it "describes that it allows odd numbers greater than or equal to a certain value" do
1756
- matcher = validate_numericality_of(:attr).
1757
- odd.
1758
- is_greater_than_or_equal_to(18)
1759
-
1760
- expect(matcher.description).to eq(
1761
- 'validate that :attr looks like an odd number greater than or equal to 18'
1762
- )
1763
- end
1764
- end
1765
-
1766
- context 'qualified with only integer + is_greater_than + less_than_or_equal_to' do
1767
- it 'describes that it allows integer greater than one value and less than or equal to another' do
1768
- matcher = validate_numericality_of(:attr).
1769
- only_integer.
1770
- is_greater_than(18).
1771
- is_less_than_or_equal_to(100)
1772
-
1773
- expect(matcher.description).to eq(
1774
- 'validate that :attr looks like an integer greater than 18 and less than or equal to 100'
1775
- )
1776
- end
1777
- end
1778
-
1779
- context 'qualified with strict' do
1780
- it 'describes that it relies upon a strict validation' do
1781
- matcher = validate_numericality_of(:attr).strict
1782
- expect(matcher.description).to eq(
1783
- 'validate that :attr looks like a number, raising a validation exception on failure'
1784
- )
1785
- end
1786
-
1787
- context 'and qualified with a comparison qualifier' do
1788
- it 'places the comparison description after "strictly"' do
1789
- matcher = validate_numericality_of(:attr).is_less_than(18).strict
1790
- expect(matcher.description).to eq(
1791
- 'validate that :attr looks like a number less than 18, raising a validation exception on failure'
1792
- )
1793
- end
1794
- end
1795
- end
1796
- end
1797
-
1798
- def build_validation_options(args)
1799
- combination = args.fetch(:for)
1800
-
1801
- combination.each_with_object({}) do |qualifier, hash|
1802
- value = self.class.default_validation_values.fetch(qualifier[:validation_name])
1803
- hash[qualifier[:validation_name]] = value
1804
- end
1805
- end
1806
-
1807
- def apply_qualifiers!(args)
1808
- combination = args.fetch(:for)
1809
- matcher = args.fetch(:to)
1810
-
1811
- combination.each do |qualifier|
1812
- args = self.class.default_qualifier_arguments.fetch(qualifier[:name])
1813
- matcher.__send__(qualifier[:name], *args)
1814
- end
1815
- end
1816
-
1817
- def define_model_validating_numericality(options = {})
1818
- attribute_name = options.delete(:attribute_name) { self.attribute_name }
1819
- column_type = options.delete(:column_type) { :string }
1820
-
1821
- define_model 'Example', attribute_name => { type: column_type } do |model|
1822
- model.validates_numericality_of(attribute_name, options)
1823
- end
1824
- end
1825
-
1826
- def define_model_validating_numericality_of_virtual_attribute(options = {})
1827
- attribute_name = options.delete(:attribute_name) { self.attribute_name }
1828
-
1829
- define_model 'Example' do |model|
1830
- model.send(:attr_accessor, attribute_name)
1831
- model.validates_numericality_of(attribute_name, options)
1832
- end
1833
- end
1834
-
1835
- def build_record_validating_numericality_of_virtual_attribute(options = {})
1836
- define_model_validating_numericality_of_virtual_attribute(options).new
1837
- end
1838
-
1839
- def build_record_validating_numericality(options = {})
1840
- define_model_validating_numericality(options).new
1841
- end
1842
-
1843
- def define_model_validating_nothing
1844
- define_model('Example', attribute_name => :string)
1845
- end
1846
-
1847
- def build_record_validating_nothing
1848
- define_model_validating_nothing.new
1849
- end
1850
-
1851
- def validate_numericality
1852
- validate_numericality_of(attribute_name)
1853
- end
1854
-
1855
- def attribute_name
1856
- :attr
1857
- end
1858
-
1859
- def validation_matcher_scenario_args
1860
- super.deep_merge(
1861
- matcher_name: :validate_numericality_of,
1862
- model_creator: :active_record
1863
- )
1864
- end
1865
- end