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