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.
- checksums.yaml +5 -5
- data/{MIT-LICENSE → LICENSE} +1 -1
- data/README.md +407 -232
- data/docs/errors/NonCaseSwappableValueError.md +2 -2
- data/lib/shoulda/matchers/action_controller/callback_matcher.rb +7 -80
- data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +4 -3
- data/lib/shoulda/matchers/action_controller/flash_store.rb +2 -4
- data/lib/shoulda/matchers/action_controller/permit_matcher.rb +36 -30
- data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +8 -10
- data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +7 -9
- data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +18 -15
- data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +3 -2
- data/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +3 -3
- data/lib/shoulda/matchers/action_controller/route_matcher.rb +88 -29
- data/lib/shoulda/matchers/action_controller/route_params.rb +2 -2
- data/lib/shoulda/matchers/action_controller/set_flash_matcher.rb +4 -4
- data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +3 -3
- data/lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb +19 -13
- data/lib/shoulda/matchers/action_controller.rb +2 -0
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb +1 -1
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +5 -9
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator.rb +2 -2
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters.rb +1 -1
- data/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb +1 -1
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +42 -39
- data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +52 -26
- data/lib/shoulda/matchers/active_model/helpers.rb +2 -2
- data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +32 -30
- data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +2 -1
- data/lib/shoulda/matchers/active_model/qualifiers/allow_blank.rb +26 -0
- data/lib/shoulda/matchers/active_model/qualifiers/allow_nil.rb +26 -0
- data/lib/shoulda/matchers/active_model/qualifiers/ignoring_interference_by_writer.rb +1 -1
- data/lib/shoulda/matchers/active_model/qualifiers.rb +2 -0
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +30 -6
- data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +8 -3
- data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +31 -16
- data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +52 -16
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +137 -84
- data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +159 -46
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +130 -66
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +251 -24
- data/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +12 -9
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +38 -6
- data/lib/shoulda/matchers/active_model/validation_message_finder.rb +2 -4
- data/lib/shoulda/matchers/active_model/validator.rb +4 -9
- data/lib/shoulda/matchers/active_model.rb +3 -5
- data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +10 -7
- data/lib/shoulda/matchers/active_record/association_matcher.rb +386 -111
- data/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +5 -2
- data/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +4 -4
- data/lib/shoulda/matchers/active_record/association_matchers/inverse_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +11 -6
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +14 -15
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +30 -8
- data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +34 -11
- data/lib/shoulda/matchers/active_record/association_matchers/optional_matcher.rb +69 -0
- data/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +74 -0
- data/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +3 -2
- data/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +7 -5
- data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +458 -42
- data/lib/shoulda/matchers/active_record/have_attached_matcher.rb +185 -0
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +63 -23
- data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +164 -48
- data/lib/shoulda/matchers/active_record/have_implicit_order_column.rb +106 -0
- data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +13 -11
- data/lib/shoulda/matchers/active_record/have_rich_text_matcher.rb +83 -0
- data/lib/shoulda/matchers/active_record/have_secure_token_matcher.rb +132 -0
- data/lib/shoulda/matchers/active_record/serialize_matcher.rb +18 -18
- data/lib/shoulda/matchers/active_record/uniqueness/test_model_creator.rb +1 -3
- data/lib/shoulda/matchers/active_record/uniqueness/test_models.rb +0 -2
- data/lib/shoulda/matchers/active_record/uniqueness.rb +1 -1
- data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +430 -200
- data/lib/shoulda/matchers/active_record.rb +28 -20
- data/lib/shoulda/matchers/configuration.rb +12 -1
- data/lib/shoulda/matchers/doublespeak/double.rb +1 -1
- data/lib/shoulda/matchers/doublespeak/double_collection.rb +3 -3
- data/lib/shoulda/matchers/doublespeak/double_implementation_registry.rb +8 -5
- data/lib/shoulda/matchers/doublespeak/object_double.rb +6 -2
- data/lib/shoulda/matchers/doublespeak/stub_implementation.rb +1 -5
- data/lib/shoulda/matchers/doublespeak/world.rb +2 -2
- data/lib/shoulda/matchers/doublespeak.rb +2 -1
- data/lib/shoulda/matchers/error.rb +1 -1
- data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +109 -29
- data/lib/shoulda/matchers/independent.rb +2 -2
- data/lib/shoulda/matchers/integrations/configuration.rb +8 -4
- data/lib/shoulda/matchers/integrations/libraries/action_controller.rb +1 -1
- data/lib/shoulda/matchers/integrations/libraries/rails.rb +2 -2
- data/lib/shoulda/matchers/integrations/test_frameworks/active_support_test_case.rb +1 -1
- data/lib/shoulda/matchers/integrations/test_frameworks/minitest_4.rb +1 -1
- data/lib/shoulda/matchers/integrations/test_frameworks/minitest_5.rb +1 -1
- data/lib/shoulda/matchers/integrations/test_frameworks/missing_test_framework.rb +1 -1
- data/lib/shoulda/matchers/integrations/test_frameworks/test_unit.rb +1 -1
- data/lib/shoulda/matchers/rails_shim.rb +172 -51
- data/lib/shoulda/matchers/routing.rb +2 -2
- data/lib/shoulda/matchers/util/word_wrap.rb +17 -12
- data/lib/shoulda/matchers/util.rb +39 -5
- data/lib/shoulda/matchers/version.rb +1 -1
- data/lib/shoulda/matchers/warn.rb +4 -3
- data/shoulda-matchers.gemspec +33 -15
- metadata +31 -338
- data/.gitignore +0 -12
- data/.hound.yml +0 -3
- data/.hound_config/ruby.yml +0 -12
- data/.travis.yml +0 -19
- data/.yardopts +0 -10
- data/Appraisals +0 -73
- data/CONTRIBUTING.md +0 -101
- data/Gemfile +0 -15
- data/Gemfile.lock +0 -70
- data/NEWS.md +0 -986
- data/Rakefile +0 -39
- data/custom_plan.rb +0 -88
- data/doc_config/gh-pages/index.html.erb +0 -9
- data/doc_config/yard/setup.rb +0 -22
- data/doc_config/yard/templates/default/fulldoc/html/css/bootstrap.css +0 -5967
- data/doc_config/yard/templates/default/fulldoc/html/css/full_list.css +0 -12
- data/doc_config/yard/templates/default/fulldoc/html/css/global.css +0 -62
- data/doc_config/yard/templates/default/fulldoc/html/css/solarized.css +0 -69
- data/doc_config/yard/templates/default/fulldoc/html/css/style.css +0 -312
- data/doc_config/yard/templates/default/fulldoc/html/full_list.erb +0 -32
- data/doc_config/yard/templates/default/fulldoc/html/full_list_class.erb +0 -1
- data/doc_config/yard/templates/default/fulldoc/html/full_list_method.erb +0 -8
- data/doc_config/yard/templates/default/fulldoc/html/js/app.js +0 -298
- data/doc_config/yard/templates/default/fulldoc/html/js/full_list.js +0 -1
- data/doc_config/yard/templates/default/fulldoc/html/js/jquery.stickyheaders.js +0 -289
- data/doc_config/yard/templates/default/fulldoc/html/js/underscore.min.js +0 -6
- data/doc_config/yard/templates/default/fulldoc/html/setup.rb +0 -8
- data/doc_config/yard/templates/default/layout/html/breadcrumb.erb +0 -14
- data/doc_config/yard/templates/default/layout/html/fonts.erb +0 -1
- data/doc_config/yard/templates/default/layout/html/footer.erb +0 -6
- data/doc_config/yard/templates/default/layout/html/layout.erb +0 -23
- data/doc_config/yard/templates/default/layout/html/search.erb +0 -13
- data/doc_config/yard/templates/default/layout/html/setup.rb +0 -40
- data/doc_config/yard/templates/default/method_details/html/source.erb +0 -10
- data/doc_config/yard/templates/default/module/html/box_info.erb +0 -31
- data/gemfiles/4.0.0.gemfile +0 -38
- data/gemfiles/4.0.0.gemfile.lock +0 -223
- data/gemfiles/4.0.1.gemfile +0 -38
- data/gemfiles/4.0.1.gemfile.lock +0 -225
- data/gemfiles/4.1.gemfile +0 -38
- data/gemfiles/4.1.gemfile.lock +0 -220
- data/gemfiles/4.2.gemfile +0 -38
- data/gemfiles/4.2.gemfile.lock +0 -243
- data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +0 -159
- data/lib/shoulda/matchers/independent/delegate_method_matcher/stubbed_target.rb +0 -37
- data/script/SUPPORTED_VERSIONS +0 -1
- data/script/install_gems_in_all_appraisals +0 -14
- data/script/run_all_tests +0 -14
- data/script/update_gem_in_all_appraisals +0 -15
- data/script/update_gems_in_all_appraisals +0 -14
- data/spec/acceptance/active_model_integration_spec.rb +0 -23
- data/spec/acceptance/independent_matchers_spec.rb +0 -125
- data/spec/acceptance/multiple_libraries_integration_spec.rb +0 -55
- data/spec/acceptance/rails_integration_spec.rb +0 -156
- data/spec/acceptance_spec_helper.rb +0 -23
- data/spec/doublespeak_spec_helper.rb +0 -2
- data/spec/report_warnings.rb +0 -7
- data/spec/spec_helper.rb +0 -21
- data/spec/support/acceptance/adds_shoulda_matchers_to_project.rb +0 -133
- data/spec/support/acceptance/helpers/active_model_helpers.rb +0 -11
- data/spec/support/acceptance/helpers/array_helpers.rb +0 -13
- data/spec/support/acceptance/helpers/base_helpers.rb +0 -19
- data/spec/support/acceptance/helpers/command_helpers.rb +0 -55
- data/spec/support/acceptance/helpers/file_helpers.rb +0 -19
- data/spec/support/acceptance/helpers/gem_helpers.rb +0 -31
- data/spec/support/acceptance/helpers/minitest_helpers.rb +0 -11
- data/spec/support/acceptance/helpers/n_unit_helpers.rb +0 -25
- data/spec/support/acceptance/helpers/pluralization_helpers.rb +0 -13
- data/spec/support/acceptance/helpers/rails_version_helpers.rb +0 -11
- data/spec/support/acceptance/helpers/rspec_helpers.rb +0 -24
- data/spec/support/acceptance/helpers/ruby_version_helpers.rb +0 -9
- data/spec/support/acceptance/helpers/step_helpers.rb +0 -127
- data/spec/support/acceptance/helpers.rb +0 -31
- data/spec/support/acceptance/matchers/have_output.rb +0 -31
- data/spec/support/acceptance/matchers/indicate_number_of_tests_was_run_matcher.rb +0 -55
- data/spec/support/acceptance/matchers/indicate_that_tests_were_run_matcher.rb +0 -103
- data/spec/support/tests/bundle.rb +0 -94
- data/spec/support/tests/command_runner.rb +0 -230
- data/spec/support/tests/current_bundle.rb +0 -61
- data/spec/support/tests/database.rb +0 -28
- data/spec/support/tests/database_adapters/postgresql.rb +0 -25
- data/spec/support/tests/database_adapters/sqlite3.rb +0 -26
- data/spec/support/tests/database_configuration.rb +0 -33
- data/spec/support/tests/database_configuration_registry.rb +0 -28
- data/spec/support/tests/filesystem.rb +0 -100
- data/spec/support/tests/version.rb +0 -45
- data/spec/support/unit/active_record/create_table.rb +0 -54
- data/spec/support/unit/attribute.rb +0 -47
- data/spec/support/unit/capture.rb +0 -40
- data/spec/support/unit/change_value.rb +0 -111
- data/spec/support/unit/create_model_arguments/basic.rb +0 -135
- data/spec/support/unit/create_model_arguments/has_many.rb +0 -15
- data/spec/support/unit/create_model_arguments/uniqueness_matcher.rb +0 -74
- data/spec/support/unit/helpers/active_model_helpers.rb +0 -27
- data/spec/support/unit/helpers/active_model_versions.rb +0 -28
- data/spec/support/unit/helpers/active_record_versions.rb +0 -24
- data/spec/support/unit/helpers/active_resource_builder.rb +0 -27
- data/spec/support/unit/helpers/allow_value_matcher_helpers.rb +0 -15
- data/spec/support/unit/helpers/class_builder.rb +0 -90
- data/spec/support/unit/helpers/column_type_helpers.rb +0 -26
- data/spec/support/unit/helpers/confirmation_matcher_helpers.rb +0 -17
- data/spec/support/unit/helpers/controller_builder.rb +0 -63
- data/spec/support/unit/helpers/database_helpers.rb +0 -20
- data/spec/support/unit/helpers/i18n_faker.rb +0 -15
- data/spec/support/unit/helpers/mailer_builder.rb +0 -12
- data/spec/support/unit/helpers/model_builder.rb +0 -114
- data/spec/support/unit/helpers/rails_versions.rb +0 -28
- data/spec/support/unit/helpers/validation_matcher_scenario_helpers.rb +0 -44
- data/spec/support/unit/i18n.rb +0 -7
- data/spec/support/unit/load_environment.rb +0 -12
- data/spec/support/unit/matchers/deprecate.rb +0 -60
- data/spec/support/unit/matchers/fail_with_message_including_matcher.rb +0 -51
- data/spec/support/unit/matchers/fail_with_message_matcher.rb +0 -62
- data/spec/support/unit/matchers/print_warning_including.rb +0 -59
- data/spec/support/unit/model_creation_strategies/active_model.rb +0 -111
- data/spec/support/unit/model_creation_strategies/active_record.rb +0 -77
- data/spec/support/unit/model_creators/active_model.rb +0 -39
- data/spec/support/unit/model_creators/active_record/has_and_belongs_to_many.rb +0 -95
- data/spec/support/unit/model_creators/active_record/has_many.rb +0 -67
- data/spec/support/unit/model_creators/active_record/uniqueness_matcher.rb +0 -42
- data/spec/support/unit/model_creators/active_record.rb +0 -43
- data/spec/support/unit/model_creators/basic.rb +0 -97
- data/spec/support/unit/model_creators.rb +0 -19
- data/spec/support/unit/rails_application.rb +0 -126
- data/spec/support/unit/record_builder_with_i18n_validation_message.rb +0 -69
- data/spec/support/unit/record_validating_confirmation_builder.rb +0 -51
- data/spec/support/unit/record_with_different_error_attribute_builder.rb +0 -92
- data/spec/support/unit/shared_examples/ignoring_interference_by_writer.rb +0 -79
- data/spec/support/unit/shared_examples/numerical_submatcher.rb +0 -17
- data/spec/support/unit/shared_examples/set_session_or_flash.rb +0 -360
- data/spec/support/unit/validation_matcher_scenario.rb +0 -62
- data/spec/unit/shoulda/matchers/action_controller/callback_matcher_spec.rb +0 -82
- data/spec/unit/shoulda/matchers/action_controller/filter_param_matcher_spec.rb +0 -28
- data/spec/unit/shoulda/matchers/action_controller/permit_matcher_spec.rb +0 -592
- data/spec/unit/shoulda/matchers/action_controller/redirect_to_matcher_spec.rb +0 -42
- data/spec/unit/shoulda/matchers/action_controller/render_template_matcher_spec.rb +0 -76
- data/spec/unit/shoulda/matchers/action_controller/render_with_layout_matcher_spec.rb +0 -62
- data/spec/unit/shoulda/matchers/action_controller/rescue_from_matcher_spec.rb +0 -90
- data/spec/unit/shoulda/matchers/action_controller/respond_with_matcher_spec.rb +0 -31
- data/spec/unit/shoulda/matchers/action_controller/route_matcher_spec.rb +0 -330
- data/spec/unit/shoulda/matchers/action_controller/route_params_spec.rb +0 -30
- data/spec/unit/shoulda/matchers/action_controller/set_flash_matcher_spec.rb +0 -67
- data/spec/unit/shoulda/matchers/action_controller/set_session_matcher_spec.rb +0 -17
- data/spec/unit/shoulda/matchers/action_controller/set_session_or_flash_matcher_spec.rb +0 -562
- data/spec/unit/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +0 -115
- data/spec/unit/shoulda/matchers/active_model/allow_value_matcher_spec.rb +0 -823
- data/spec/unit/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +0 -86
- data/spec/unit/shoulda/matchers/active_model/have_secure_password_matcher_spec.rb +0 -20
- data/spec/unit/shoulda/matchers/active_model/helpers_spec.rb +0 -162
- data/spec/unit/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +0 -266
- data/spec/unit/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +0 -91
- data/spec/unit/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +0 -149
- data/spec/unit/shoulda/matchers/active_model/validate_exclusion_of_matcher_spec.rb +0 -207
- data/spec/unit/shoulda/matchers/active_model/validate_inclusion_of_matcher_spec.rb +0 -1015
- data/spec/unit/shoulda/matchers/active_model/validate_length_of_matcher_spec.rb +0 -288
- data/spec/unit/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +0 -1837
- data/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +0 -380
- data/spec/unit/shoulda/matchers/active_record/accept_nested_attributes_for_matcher_spec.rb +0 -107
- data/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb +0 -1242
- data/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +0 -251
- data/spec/unit/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb +0 -168
- data/spec/unit/shoulda/matchers/active_record/have_db_column_matcher_spec.rb +0 -111
- data/spec/unit/shoulda/matchers/active_record/have_db_index_matcher_spec.rb +0 -85
- data/spec/unit/shoulda/matchers/active_record/have_readonly_attributes_matcher_spec.rb +0 -41
- data/spec/unit/shoulda/matchers/active_record/serialize_matcher_spec.rb +0 -86
- data/spec/unit/shoulda/matchers/active_record/validate_uniqueness_of_matcher_spec.rb +0 -1418
- data/spec/unit/shoulda/matchers/doublespeak/double_collection_spec.rb +0 -190
- data/spec/unit/shoulda/matchers/doublespeak/double_implementation_registry_spec.rb +0 -21
- data/spec/unit/shoulda/matchers/doublespeak/double_spec.rb +0 -271
- data/spec/unit/shoulda/matchers/doublespeak/object_double_spec.rb +0 -77
- data/spec/unit/shoulda/matchers/doublespeak/proxy_implementation_spec.rb +0 -72
- data/spec/unit/shoulda/matchers/doublespeak/stub_implementation_spec.rb +0 -101
- data/spec/unit/shoulda/matchers/doublespeak/world_spec.rb +0 -80
- data/spec/unit/shoulda/matchers/doublespeak_spec.rb +0 -27
- data/spec/unit/shoulda/matchers/independent/delegate_method_matcher/stubbed_target_spec.rb +0 -43
- data/spec/unit/shoulda/matchers/independent/delegate_method_matcher_spec.rb +0 -517
- data/spec/unit/shoulda/matchers/routing/route_matcher_spec.rb +0 -242
- data/spec/unit/shoulda/matchers/util/word_wrap_spec.rb +0 -252
- data/spec/unit_spec_helper.rb +0 -46
- data/spec/warnings_spy/filesystem.rb +0 -45
- data/spec/warnings_spy/partitioner.rb +0 -36
- data/spec/warnings_spy/reader.rb +0 -53
- data/spec/warnings_spy/reporter.rb +0 -88
- data/spec/warnings_spy.rb +0 -64
- data/tasks/documentation.rb +0 -199
- data/zeus.json +0 -11
@@ -1,823 +0,0 @@
|
|
1
|
-
require 'unit_spec_helper'
|
2
|
-
|
3
|
-
describe Shoulda::Matchers::ActiveModel, type: :model do
|
4
|
-
describe '#allow_values' do
|
5
|
-
it 'is aliased to #allow_value' do
|
6
|
-
expect(method(:allow_values)).to eq(method(:allow_value))
|
7
|
-
end
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
describe Shoulda::Matchers::ActiveModel::AllowValueMatcher, type: :model do
|
12
|
-
context "#description" do
|
13
|
-
it 'describes itself with multiple values' do
|
14
|
-
matcher = allow_value('foo', 'bar').for(:baz)
|
15
|
-
|
16
|
-
expect(matcher.description).to eq(
|
17
|
-
'allow :baz to be ‹"foo"› or ‹"bar"›'
|
18
|
-
)
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'describes itself with a single value' do
|
22
|
-
matcher = allow_value('foo').for(:baz)
|
23
|
-
|
24
|
-
expect(matcher.description).to eq 'allow :baz to be ‹"foo"›'
|
25
|
-
end
|
26
|
-
|
27
|
-
if active_model_3_2?
|
28
|
-
it 'describes itself with a strict validation' do
|
29
|
-
strict_matcher = allow_value('xyz').for(:attr).strict
|
30
|
-
|
31
|
-
expect(strict_matcher.description).to eq(
|
32
|
-
'allow :attr to be ‹"xyz"›, raising a validation exception on failure'
|
33
|
-
)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
describe '#_after_setting_value' do
|
39
|
-
it 'sets a block which is yielded after each value is set on the attribute' do
|
40
|
-
attribute = :attr
|
41
|
-
record = define_model(:example, attribute => :string).new
|
42
|
-
matcher = described_class.new('a', 'b', 'c').for(attribute)
|
43
|
-
call_count = 0
|
44
|
-
|
45
|
-
matcher._after_setting_value { call_count += 1 }
|
46
|
-
matcher.matches?(record)
|
47
|
-
|
48
|
-
expect(call_count).to eq 3
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
context 'an attribute with a validation' do
|
53
|
-
context 'given one good value' do
|
54
|
-
context 'when used in the positive' do
|
55
|
-
it 'accepts' do
|
56
|
-
expect(validating_format(with: /abc/)).
|
57
|
-
to allow_value('abcde').for(:attr)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
context 'when used in the negative' do
|
62
|
-
it 'rejects with an appropriate failure message' do
|
63
|
-
assertion = lambda do
|
64
|
-
expect(validating_format(with: /abc/)).
|
65
|
-
not_to allow_value('abcde').for(:attr)
|
66
|
-
end
|
67
|
-
|
68
|
-
message = <<-MESSAGE
|
69
|
-
After setting :attr to ‹"abcde"›, the matcher expected the Example to be
|
70
|
-
invalid, but it was valid instead.
|
71
|
-
MESSAGE
|
72
|
-
|
73
|
-
expect(&assertion).to fail_with_message(message)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
context 'given several good values' do
|
79
|
-
context 'when used in the positive' do
|
80
|
-
it 'accepts' do
|
81
|
-
expect(validating_format(with: /abc/)).
|
82
|
-
to allow_value('abcde', 'deabc').for(:attr)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
context 'when used in the negative' do
|
87
|
-
it 'rejects with an appropriate failure message' do
|
88
|
-
assertion = lambda do
|
89
|
-
expect(validating_format(with: /abc/)).
|
90
|
-
not_to allow_value('abcde', 'deabc').for(:attr)
|
91
|
-
end
|
92
|
-
|
93
|
-
message = <<-MESSAGE
|
94
|
-
After setting :attr to ‹"abcde"›, the matcher expected the Example to be
|
95
|
-
invalid, but it was valid instead.
|
96
|
-
MESSAGE
|
97
|
-
|
98
|
-
expect(&assertion).to fail_with_message(message)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
context 'given one bad value' do
|
104
|
-
context 'when used in the positive' do
|
105
|
-
it 'rejects with an appropriate failure message' do
|
106
|
-
assertion = lambda do
|
107
|
-
expect(validating_format(with: /abc/)).
|
108
|
-
to allow_value('xyz').for(:attr)
|
109
|
-
end
|
110
|
-
|
111
|
-
message = <<-MESSAGE
|
112
|
-
After setting :attr to ‹"xyz"›, the matcher expected the Example to be
|
113
|
-
valid, but it was invalid instead, producing these validation errors:
|
114
|
-
|
115
|
-
* attr: ["is invalid"]
|
116
|
-
MESSAGE
|
117
|
-
|
118
|
-
expect(&assertion).to fail_with_message(message)
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
context 'when used in the negative' do
|
123
|
-
it 'accepts' do
|
124
|
-
expect(validating_format(with: /abc/)).
|
125
|
-
not_to allow_value('xyz').for(:attr)
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
context 'given several bad values' do
|
131
|
-
context 'when used in the positive' do
|
132
|
-
it 'rejects with an appropriate failure message' do
|
133
|
-
assertion = lambda do
|
134
|
-
expect(validating_format(with: /abc/)).
|
135
|
-
to allow_value('xyz', 'zyx', nil, []).
|
136
|
-
for(:attr).
|
137
|
-
ignoring_interference_by_writer
|
138
|
-
end
|
139
|
-
|
140
|
-
message = <<-MESSAGE
|
141
|
-
After setting :attr to ‹"xyz"›, the matcher expected the Example to be
|
142
|
-
valid, but it was invalid instead, producing these validation errors:
|
143
|
-
|
144
|
-
* attr: ["is invalid"]
|
145
|
-
MESSAGE
|
146
|
-
|
147
|
-
expect(&assertion).to fail_with_message(message)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
context 'when used in the negative' do
|
152
|
-
it 'accepts' do
|
153
|
-
expect(validating_format(with: /abc/)).
|
154
|
-
not_to allow_value('xyz', 'zyx', nil, []).
|
155
|
-
for(:attr).
|
156
|
-
ignoring_interference_by_writer
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
context 'given good values along with bad values' do
|
162
|
-
context 'when used in the positive' do
|
163
|
-
it 'rejects with an appropriate failure message' do
|
164
|
-
assertion = lambda do
|
165
|
-
expect(validating_format(with: /abc/)).
|
166
|
-
to allow_value('abc', 'xyz').
|
167
|
-
for(:attr).
|
168
|
-
ignoring_interference_by_writer
|
169
|
-
end
|
170
|
-
|
171
|
-
message = <<-MESSAGE
|
172
|
-
After setting :attr to ‹"xyz"›, the matcher expected the Example to be
|
173
|
-
valid, but it was invalid instead, producing these validation errors:
|
174
|
-
|
175
|
-
* attr: ["is invalid"]
|
176
|
-
MESSAGE
|
177
|
-
|
178
|
-
expect(&assertion).to fail_with_message(message)
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
context 'when used in the negative' do
|
183
|
-
it 'rejects with an appropriate failure message' do
|
184
|
-
assertion = lambda do
|
185
|
-
expect(validating_format(with: /abc/)).
|
186
|
-
not_to allow_value('abc', 'xyz').
|
187
|
-
for(:attr).
|
188
|
-
ignoring_interference_by_writer
|
189
|
-
end
|
190
|
-
|
191
|
-
message = <<-MESSAGE
|
192
|
-
After setting :attr to ‹"abc"›, the matcher expected the Example to be
|
193
|
-
invalid, but it was valid instead.
|
194
|
-
MESSAGE
|
195
|
-
|
196
|
-
expect(&assertion).to fail_with_message(message)
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
context 'given bad values along with good values' do
|
202
|
-
context 'when used in the positive' do
|
203
|
-
it 'rejects with an appropriate failure message' do
|
204
|
-
assertion = lambda do
|
205
|
-
expect(validating_format(with: /abc/)).
|
206
|
-
to allow_value('xyz', 'abc').
|
207
|
-
for(:attr).
|
208
|
-
ignoring_interference_by_writer
|
209
|
-
end
|
210
|
-
|
211
|
-
message = <<-MESSAGE
|
212
|
-
After setting :attr to ‹"xyz"›, the matcher expected the Example to be
|
213
|
-
valid, but it was invalid instead, producing these validation errors:
|
214
|
-
|
215
|
-
* attr: ["is invalid"]
|
216
|
-
MESSAGE
|
217
|
-
|
218
|
-
expect(&assertion).to fail_with_message(message)
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
context 'when used in the negative' do
|
223
|
-
it 'rejects with an appropriate failure message' do
|
224
|
-
assertion = lambda do
|
225
|
-
expect(validating_format(with: /abc/)).
|
226
|
-
not_to allow_value('xyz', 'abc').
|
227
|
-
for(:attr).
|
228
|
-
ignoring_interference_by_writer
|
229
|
-
end
|
230
|
-
|
231
|
-
message = <<-MESSAGE
|
232
|
-
After setting :attr to ‹"abc"›, the matcher expected the Example to be
|
233
|
-
invalid, but it was valid instead.
|
234
|
-
MESSAGE
|
235
|
-
|
236
|
-
expect(&assertion).to fail_with_message(message)
|
237
|
-
end
|
238
|
-
end
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
context 'an attribute with a validation and a custom message' do
|
243
|
-
it 'allows a good value' do
|
244
|
-
expect(validating_format(with: /abc/, message: 'bad value')).
|
245
|
-
to allow_value('abcde').for(:attr).with_message(/bad/)
|
246
|
-
end
|
247
|
-
|
248
|
-
it 'rejects a bad value with an appropriate failure message' do
|
249
|
-
message = <<-MESSAGE
|
250
|
-
After setting :attr to ‹"xyz"›, the matcher expected the Example to be
|
251
|
-
valid, but it was invalid instead, producing these validation errors:
|
252
|
-
|
253
|
-
* attr: ["bad value"]
|
254
|
-
MESSAGE
|
255
|
-
|
256
|
-
assertion = lambda do
|
257
|
-
expect(validating_format(with: /abc/, message: 'bad value')).
|
258
|
-
to allow_value('xyz').for(:attr).with_message(/bad/)
|
259
|
-
end
|
260
|
-
|
261
|
-
expect(&assertion).to fail_with_message(message)
|
262
|
-
end
|
263
|
-
|
264
|
-
context 'when the custom messages do not match' do
|
265
|
-
it 'rejects with an appropriate failure message' do
|
266
|
-
message = <<-MESSAGE
|
267
|
-
After setting :attr to ‹"xyz"›, the matcher expected the Example to be
|
268
|
-
invalid and to produce a validation error matching ‹/different/› on
|
269
|
-
:attr. The record was indeed invalid, but it produced these validation
|
270
|
-
errors instead:
|
271
|
-
|
272
|
-
* attr: ["bad value"]
|
273
|
-
MESSAGE
|
274
|
-
|
275
|
-
assertion = lambda do
|
276
|
-
expect(validating_format(with: /abc/, message: 'bad value')).
|
277
|
-
not_to allow_value('xyz').for(:attr).with_message(/different/)
|
278
|
-
end
|
279
|
-
|
280
|
-
expect(&assertion).to fail_with_message(message)
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
context 'when interpolation values are provided along with a custom message' do
|
285
|
-
context 'when the messages match' do
|
286
|
-
it 'accepts' do
|
287
|
-
options = {
|
288
|
-
attribute_name: :attr,
|
289
|
-
attribute_type: :string
|
290
|
-
}
|
291
|
-
|
292
|
-
record = record_with_custom_validation(options) do
|
293
|
-
if self.attr == 'xyz'
|
294
|
-
self.errors.add :attr, :greater_than, count: 2
|
295
|
-
end
|
296
|
-
end
|
297
|
-
|
298
|
-
expect(record).
|
299
|
-
not_to allow_value('xyz').
|
300
|
-
for(:attr).
|
301
|
-
with_message(:greater_than, values: { count: 2 })
|
302
|
-
end
|
303
|
-
end
|
304
|
-
|
305
|
-
context 'when the messages do not match' do
|
306
|
-
it 'rejects with an appropriate failure message' do
|
307
|
-
options = {
|
308
|
-
attribute_name: :attr,
|
309
|
-
attribute_type: :string
|
310
|
-
}
|
311
|
-
|
312
|
-
record = record_with_custom_validation(options) do
|
313
|
-
if self.attr == 'xyz'
|
314
|
-
self.errors.add :attr, "some other error"
|
315
|
-
end
|
316
|
-
end
|
317
|
-
|
318
|
-
assertion = lambda do
|
319
|
-
expect(record).
|
320
|
-
not_to allow_value('xyz').
|
321
|
-
for(:attr).
|
322
|
-
with_message(:greater_than, values: { count: 2 })
|
323
|
-
end
|
324
|
-
|
325
|
-
message = <<-MESSAGE
|
326
|
-
After setting :attr to ‹"xyz"›, the matcher expected the Example to be
|
327
|
-
invalid and to produce the validation error "must be greater than 2" on
|
328
|
-
:attr. The record was indeed invalid, but it produced these validation
|
329
|
-
errors instead:
|
330
|
-
|
331
|
-
* attr: ["some other error"]
|
332
|
-
MESSAGE
|
333
|
-
|
334
|
-
expect(&assertion).to fail_with_message(message)
|
335
|
-
end
|
336
|
-
end
|
337
|
-
end
|
338
|
-
end
|
339
|
-
|
340
|
-
context 'when the attribute being validated is different than the attribute that receives the validation error' do
|
341
|
-
include UnitTests::AllowValueMatcherHelpers
|
342
|
-
|
343
|
-
context 'when the validation error message was provided directly' do
|
344
|
-
context 'given a valid value' do
|
345
|
-
it 'accepts' do
|
346
|
-
builder = builder_for_record_with_different_error_attribute
|
347
|
-
expect(builder.record).
|
348
|
-
to allow_value(builder.valid_value).
|
349
|
-
for(builder.attribute_to_validate).
|
350
|
-
with_message(
|
351
|
-
builder.message,
|
352
|
-
against: builder.attribute_that_receives_error
|
353
|
-
)
|
354
|
-
end
|
355
|
-
end
|
356
|
-
|
357
|
-
context 'given an invalid value' do
|
358
|
-
it 'rejects' do
|
359
|
-
builder = builder_for_record_with_different_error_attribute
|
360
|
-
invalid_value = "#{builder.valid_value} (invalid)"
|
361
|
-
|
362
|
-
expect(builder.record).
|
363
|
-
not_to allow_value(invalid_value).
|
364
|
-
for(builder.attribute_to_validate).
|
365
|
-
with_message(
|
366
|
-
builder.message,
|
367
|
-
against: builder.attribute_that_receives_error
|
368
|
-
)
|
369
|
-
end
|
370
|
-
|
371
|
-
context 'if the messages do not match' do
|
372
|
-
it 'technically accepts' do
|
373
|
-
builder = builder_for_record_with_different_error_attribute(
|
374
|
-
message: "a different error"
|
375
|
-
)
|
376
|
-
invalid_value = "#{builder.valid_value} (invalid)"
|
377
|
-
|
378
|
-
assertion = lambda do
|
379
|
-
expect(builder.record).
|
380
|
-
not_to allow_value(invalid_value).
|
381
|
-
for(builder.attribute_to_validate).
|
382
|
-
with_message(
|
383
|
-
"some error",
|
384
|
-
against: builder.attribute_that_receives_error
|
385
|
-
)
|
386
|
-
end
|
387
|
-
|
388
|
-
message = <<-MESSAGE
|
389
|
-
After setting :#{builder.attribute_to_validate} to ‹"#{invalid_value}"›, the
|
390
|
-
matcher expected the #{builder.model.name} to be invalid and to produce the validation
|
391
|
-
error "some error" on :#{builder.attribute_that_receives_error}. The record was
|
392
|
-
indeed invalid, but it produced these validation errors instead:
|
393
|
-
|
394
|
-
* #{builder.attribute_that_receives_error}: ["a different error"]
|
395
|
-
MESSAGE
|
396
|
-
|
397
|
-
expect(&assertion).to fail_with_message(message)
|
398
|
-
end
|
399
|
-
end
|
400
|
-
end
|
401
|
-
end
|
402
|
-
|
403
|
-
context 'when the validation error message was provided via i18n' do
|
404
|
-
it 'passes given a valid value' do
|
405
|
-
builder = builder_for_record_with_different_error_attribute_using_i18n
|
406
|
-
expect(builder.record).
|
407
|
-
to allow_value(builder.valid_value).
|
408
|
-
for(builder.attribute_to_validate).
|
409
|
-
with_message(
|
410
|
-
builder.validation_message_key,
|
411
|
-
against: builder.attribute_that_receives_error
|
412
|
-
)
|
413
|
-
end
|
414
|
-
|
415
|
-
it 'fails given an invalid value' do
|
416
|
-
builder = builder_for_record_with_different_error_attribute_using_i18n
|
417
|
-
invalid_value = "#{builder.valid_value} (invalid)"
|
418
|
-
expect(builder.record).
|
419
|
-
not_to allow_value(invalid_value).
|
420
|
-
for(builder.attribute_to_validate).
|
421
|
-
with_message(
|
422
|
-
builder.validation_message_key,
|
423
|
-
against: builder.attribute_that_receives_error
|
424
|
-
)
|
425
|
-
end
|
426
|
-
end
|
427
|
-
end
|
428
|
-
|
429
|
-
context "an attribute with a context-dependent validation" do
|
430
|
-
context "without the validation context" do
|
431
|
-
it "allows a bad value" do
|
432
|
-
expect(validating_format(with: /abc/, on: :customisable)).to allow_value("xyz").for(:attr)
|
433
|
-
end
|
434
|
-
end
|
435
|
-
|
436
|
-
context "with the validation context" do
|
437
|
-
it "allows a good value" do
|
438
|
-
expect(validating_format(with: /abc/, on: :customisable)).to allow_value("abcde").for(:attr).on(:customisable)
|
439
|
-
end
|
440
|
-
|
441
|
-
it "rejects a bad value" do
|
442
|
-
expect(validating_format(with: /abc/, on: :customisable)).not_to allow_value("xyz").for(:attr).on(:customisable)
|
443
|
-
end
|
444
|
-
end
|
445
|
-
end
|
446
|
-
|
447
|
-
context 'an attribute with several validations' do
|
448
|
-
let(:model) do
|
449
|
-
define_model :example, attr: :string do
|
450
|
-
validates_presence_of :attr
|
451
|
-
validates_length_of :attr, within: 1..5
|
452
|
-
validates_numericality_of :attr, greater_than_or_equal_to: 1,
|
453
|
-
less_than_or_equal_to: 50000
|
454
|
-
end.new
|
455
|
-
end
|
456
|
-
|
457
|
-
bad_values = [nil, '', 'abc', '0', '50001', '123456', []]
|
458
|
-
|
459
|
-
it 'matches given a good value' do
|
460
|
-
expect(model).to allow_value('12345').for(:attr)
|
461
|
-
end
|
462
|
-
|
463
|
-
it 'does not match given a bad value' do
|
464
|
-
bad_values.each do |bad_value|
|
465
|
-
expect(model).
|
466
|
-
not_to allow_value(bad_value).
|
467
|
-
for(:attr).
|
468
|
-
ignoring_interference_by_writer
|
469
|
-
end
|
470
|
-
end
|
471
|
-
|
472
|
-
it 'does not match given multiple bad values' do
|
473
|
-
expect(model).
|
474
|
-
not_to allow_value(*bad_values).
|
475
|
-
for(:attr).
|
476
|
-
ignoring_interference_by_writer
|
477
|
-
end
|
478
|
-
|
479
|
-
it "does not match given good values along with bad values" do
|
480
|
-
message = <<-MESSAGE.strip_heredoc
|
481
|
-
After setting :attr to ‹"12345"›, the matcher expected the Example to be
|
482
|
-
invalid, but it was valid instead.
|
483
|
-
MESSAGE
|
484
|
-
|
485
|
-
assertion = lambda do
|
486
|
-
expect(model).not_to allow_value('12345', *bad_values).for(:attr)
|
487
|
-
end
|
488
|
-
|
489
|
-
expect(&assertion).to fail_with_message(message)
|
490
|
-
end
|
491
|
-
|
492
|
-
it "does not match given bad values along with good values" do
|
493
|
-
message = <<-MESSAGE.strip_heredoc
|
494
|
-
After setting :attr to ‹"12345"›, the matcher expected the Example to be
|
495
|
-
invalid, but it was valid instead.
|
496
|
-
MESSAGE
|
497
|
-
|
498
|
-
assertion = lambda do
|
499
|
-
expect(model).not_to allow_value(*bad_values, '12345').for(:attr)
|
500
|
-
end
|
501
|
-
|
502
|
-
expect(&assertion).to fail_with_message(message)
|
503
|
-
end
|
504
|
-
end
|
505
|
-
|
506
|
-
context 'with a single value' do
|
507
|
-
it 'allows you to call description before calling matches?' do
|
508
|
-
model = define_model(:example, attr: :string).new
|
509
|
-
matcher = described_class.new('foo').for(:attr)
|
510
|
-
matcher.description
|
511
|
-
|
512
|
-
expect { matcher.matches?(model) }.not_to raise_error
|
513
|
-
end
|
514
|
-
end
|
515
|
-
|
516
|
-
context 'with no values' do
|
517
|
-
it 'raises an error' do
|
518
|
-
expect { allow_value.for(:baz) }.
|
519
|
-
to raise_error(ArgumentError, /at least one argument/)
|
520
|
-
end
|
521
|
-
end
|
522
|
-
|
523
|
-
if active_model_3_2?
|
524
|
-
context 'an attribute with a strict format validation' do
|
525
|
-
context 'when qualified with strict' do
|
526
|
-
it 'rejects a bad value, providing the correct failure message' do
|
527
|
-
message = <<-MESSAGE.strip_heredoc
|
528
|
-
After setting :attr to ‹"xyz"›, the matcher expected the Example to be
|
529
|
-
valid, but it was invalid instead, raising a validation exception with
|
530
|
-
the message "Attr is invalid".
|
531
|
-
MESSAGE
|
532
|
-
|
533
|
-
assertion = lambda do
|
534
|
-
expect(validating_format(with: /abc/, strict: true)).
|
535
|
-
to allow_value('xyz').for(:attr).strict
|
536
|
-
end
|
537
|
-
|
538
|
-
expect(&assertion).to fail_with_message(message)
|
539
|
-
end
|
540
|
-
|
541
|
-
context 'qualified with a custom message' do
|
542
|
-
it 'rejects a bad value when the failure messages do not match' do
|
543
|
-
message = <<-MESSAGE.strip_heredoc
|
544
|
-
After setting :attr to ‹"xyz"›, the matcher expected the Example to be
|
545
|
-
invalid and to raise a validation exception with message matching
|
546
|
-
‹/abc/›. The record was indeed invalid, but the exception message was
|
547
|
-
"Attr is invalid" instead.
|
548
|
-
MESSAGE
|
549
|
-
|
550
|
-
assertion = lambda do
|
551
|
-
expect(validating_format(with: /abc/, strict: true)).
|
552
|
-
not_to allow_value('xyz').for(:attr).with_message(/abc/).strict
|
553
|
-
end
|
554
|
-
|
555
|
-
expect(&assertion).to fail_with_message(message)
|
556
|
-
end
|
557
|
-
end
|
558
|
-
end
|
559
|
-
end
|
560
|
-
end
|
561
|
-
|
562
|
-
context 'when the attribute interferes with attempts to be set' do
|
563
|
-
context 'when the attribute cannot be changed from nil to non-nil' do
|
564
|
-
context 'and the record remains valid' do
|
565
|
-
it 'accepts (and does not raise an AttributeChangedValueError)' do
|
566
|
-
model = define_active_model_class 'Example', accessors: [:name] do
|
567
|
-
def name=(_value)
|
568
|
-
nil
|
569
|
-
end
|
570
|
-
end
|
571
|
-
|
572
|
-
expect(model.new).to allow_value('anything').for(:name)
|
573
|
-
end
|
574
|
-
end
|
575
|
-
|
576
|
-
context 'and the record becomes invalid' do
|
577
|
-
it 'rejects with an appropriate failure message' do
|
578
|
-
model = define_active_model_class 'Example', accessors: [:name] do
|
579
|
-
validates_presence_of :name
|
580
|
-
|
581
|
-
def name=(_value)
|
582
|
-
nil
|
583
|
-
end
|
584
|
-
end
|
585
|
-
|
586
|
-
assertion = lambda do
|
587
|
-
expect(model.new).to allow_value('anything').for(:name)
|
588
|
-
end
|
589
|
-
|
590
|
-
message = <<-MESSAGE.strip
|
591
|
-
After setting :name to ‹"anything"› -- which was read back as ‹nil› --
|
592
|
-
the matcher expected the Example to be valid, but it was invalid
|
593
|
-
instead, producing these validation errors:
|
594
|
-
|
595
|
-
* name: ["can't be blank"]
|
596
|
-
|
597
|
-
As indicated in the message above, :name 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 do
|
601
|
-
something else entirely.
|
602
|
-
MESSAGE
|
603
|
-
|
604
|
-
expect(&assertion).to fail_with_message(message)
|
605
|
-
end
|
606
|
-
end
|
607
|
-
end
|
608
|
-
|
609
|
-
context 'when the attribute cannot be changed from non-nil to nil' do
|
610
|
-
context 'and the record remains valid' do
|
611
|
-
it 'accepts (and does not raise an AttributeChangedValueError)' do
|
612
|
-
model = define_active_model_class 'Example', accessors: [:name] do
|
613
|
-
def name=(value)
|
614
|
-
if value
|
615
|
-
super(value)
|
616
|
-
end
|
617
|
-
end
|
618
|
-
end
|
619
|
-
|
620
|
-
record = model.new(name: 'some name')
|
621
|
-
|
622
|
-
expect(record).to allow_value(nil).for(:name)
|
623
|
-
end
|
624
|
-
end
|
625
|
-
|
626
|
-
context 'and the record becomes invalid' do
|
627
|
-
it 'rejects with an appropriate failure message' do
|
628
|
-
model = define_active_model_class 'Example', accessors: [:name] do
|
629
|
-
validates_absence_of :name
|
630
|
-
|
631
|
-
def name=(value)
|
632
|
-
if value
|
633
|
-
super(value)
|
634
|
-
end
|
635
|
-
end
|
636
|
-
end
|
637
|
-
|
638
|
-
record = model.new(name: 'some name')
|
639
|
-
|
640
|
-
assertion = lambda do
|
641
|
-
expect(record).to allow_value(nil).for(:name)
|
642
|
-
end
|
643
|
-
|
644
|
-
message = <<-MESSAGE.strip
|
645
|
-
After setting :name to ‹nil› -- which was read back as ‹"some name"› --
|
646
|
-
the matcher expected the Example to be valid, but it was invalid
|
647
|
-
instead, producing these validation errors:
|
648
|
-
|
649
|
-
* name: ["must be blank"]
|
650
|
-
|
651
|
-
As indicated in the message above, :name seems to be changing certain
|
652
|
-
values as they are set, and this could have something to do with why
|
653
|
-
this test is failing. If you've overridden the writer method for this
|
654
|
-
attribute, then you may need to change it to make this test pass, or do
|
655
|
-
something else entirely.
|
656
|
-
MESSAGE
|
657
|
-
|
658
|
-
expect(&assertion).to fail_with_message(message)
|
659
|
-
end
|
660
|
-
end
|
661
|
-
end
|
662
|
-
|
663
|
-
context 'when the attribute cannot be changed from a non-nil value to another non-nil value' do
|
664
|
-
context 'and the record remains valid' do
|
665
|
-
it 'accepts (and does not raise an AttributeChangedValueError)' do
|
666
|
-
model = define_active_model_class 'Example', accessors: [:name] do
|
667
|
-
def name=(_value)
|
668
|
-
super('constant name')
|
669
|
-
end
|
670
|
-
end
|
671
|
-
|
672
|
-
record = model.new(name: 'some name')
|
673
|
-
|
674
|
-
expect(record).to allow_value('another name').for(:name)
|
675
|
-
end
|
676
|
-
end
|
677
|
-
|
678
|
-
context 'and the record becomes invalid' do
|
679
|
-
it 'rejects with an appropriate failure message' do
|
680
|
-
model = define_active_model_class 'Example', accessors: [:name] do
|
681
|
-
validates_format_of :name, with: /another name/
|
682
|
-
|
683
|
-
def name=(value)
|
684
|
-
super('constant name')
|
685
|
-
end
|
686
|
-
end
|
687
|
-
|
688
|
-
record = model.new(name: 'some name')
|
689
|
-
|
690
|
-
assertion = lambda do
|
691
|
-
expect(record).to allow_value('another name').for(:name)
|
692
|
-
end
|
693
|
-
|
694
|
-
message = <<-MESSAGE.strip
|
695
|
-
After setting :name to ‹"another name"› -- which was read back as
|
696
|
-
‹"constant name"› -- the matcher expected the Example to be valid, but
|
697
|
-
it was invalid instead, producing these validation errors:
|
698
|
-
|
699
|
-
* name: ["is invalid"]
|
700
|
-
|
701
|
-
As indicated in the message above, :name seems to be changing certain
|
702
|
-
values as they are set, and this could have something to do with why
|
703
|
-
this test is failing. If you've overridden the writer method for this
|
704
|
-
attribute, then you may need to change it to make this test pass, or do
|
705
|
-
something else entirely.
|
706
|
-
MESSAGE
|
707
|
-
|
708
|
-
expect(&assertion).to fail_with_message(message)
|
709
|
-
end
|
710
|
-
end
|
711
|
-
end
|
712
|
-
end
|
713
|
-
|
714
|
-
context 'when the attribute does not exist on the model' do
|
715
|
-
context 'when the assertion is positive' do
|
716
|
-
it 'raises an AttributeDoesNotExistError' do
|
717
|
-
model = define_class('Example')
|
718
|
-
|
719
|
-
assertion = lambda do
|
720
|
-
expect(model.new).to allow_value('foo').for(:nonexistent)
|
721
|
-
end
|
722
|
-
|
723
|
-
message = <<-MESSAGE.rstrip
|
724
|
-
The matcher attempted to set :nonexistent on the Example to "foo", but
|
725
|
-
that attribute does not exist.
|
726
|
-
MESSAGE
|
727
|
-
|
728
|
-
expect(&assertion).to raise_error(
|
729
|
-
described_class::AttributeDoesNotExistError,
|
730
|
-
message
|
731
|
-
)
|
732
|
-
end
|
733
|
-
end
|
734
|
-
|
735
|
-
context 'when the assertion is negative' do
|
736
|
-
it 'raises an AttributeDoesNotExistError' do
|
737
|
-
model = define_class('Example')
|
738
|
-
|
739
|
-
assertion = lambda do
|
740
|
-
expect(model.new).not_to allow_value('foo').for(:nonexistent)
|
741
|
-
end
|
742
|
-
|
743
|
-
message = <<-MESSAGE.rstrip
|
744
|
-
The matcher attempted to set :nonexistent on the Example to "foo", but
|
745
|
-
that attribute does not exist.
|
746
|
-
MESSAGE
|
747
|
-
|
748
|
-
expect(&assertion).to raise_error(
|
749
|
-
described_class::AttributeDoesNotExistError,
|
750
|
-
message
|
751
|
-
)
|
752
|
-
end
|
753
|
-
end
|
754
|
-
end
|
755
|
-
|
756
|
-
context 'given attributes to preset on the record before validation' do
|
757
|
-
context 'when the assertion is positive' do
|
758
|
-
context 'if any attributes do not exist on the model' do
|
759
|
-
it 'raises an AttributeDoesNotExistError' do
|
760
|
-
model = define_active_model_class('Example', accessors: [:existent])
|
761
|
-
|
762
|
-
allow_value_matcher = allow_value('foo').for(:existent).tap do |matcher|
|
763
|
-
matcher.values_to_preset = { nonexistent: 'some value' }
|
764
|
-
end
|
765
|
-
|
766
|
-
assertion = lambda do
|
767
|
-
expect(model.new).to(allow_value_matcher)
|
768
|
-
end
|
769
|
-
|
770
|
-
message = <<-MESSAGE.rstrip
|
771
|
-
The matcher attempted to set :nonexistent on the Example to "some
|
772
|
-
value", but that attribute does not exist.
|
773
|
-
MESSAGE
|
774
|
-
|
775
|
-
expect(&assertion).to raise_error(
|
776
|
-
described_class::AttributeDoesNotExistError,
|
777
|
-
message
|
778
|
-
)
|
779
|
-
end
|
780
|
-
end
|
781
|
-
end
|
782
|
-
|
783
|
-
context 'when the assertion is negative' do
|
784
|
-
context 'if any attributes do not exist on the model' do
|
785
|
-
it 'raises an AttributeDoesNotExistError' do
|
786
|
-
model = define_active_model_class('Example', accessors: [:existent])
|
787
|
-
|
788
|
-
allow_value_matcher = allow_value('foo').for(:existent).tap do |matcher|
|
789
|
-
matcher.values_to_preset = { nonexistent: 'some value' }
|
790
|
-
end
|
791
|
-
|
792
|
-
assertion = lambda do
|
793
|
-
expect(model.new).not_to(allow_value_matcher)
|
794
|
-
end
|
795
|
-
|
796
|
-
message = <<-MESSAGE.rstrip
|
797
|
-
The matcher attempted to set :nonexistent on the Example to "some
|
798
|
-
value", but that attribute does not exist.
|
799
|
-
MESSAGE
|
800
|
-
|
801
|
-
expect(&assertion).to raise_error(
|
802
|
-
described_class::AttributeDoesNotExistError,
|
803
|
-
message
|
804
|
-
)
|
805
|
-
end
|
806
|
-
end
|
807
|
-
end
|
808
|
-
end
|
809
|
-
|
810
|
-
if active_record_supports_enum?
|
811
|
-
context 'given an ActiveRecord model' do
|
812
|
-
context 'where the attribute under test is an enum and the given value is a value in that enum' do
|
813
|
-
it 'accepts' do
|
814
|
-
model = define_model('Shipment', status: :integer) do
|
815
|
-
enum status: { pending: 1, shipped: 2, delivered: 3 }
|
816
|
-
end
|
817
|
-
|
818
|
-
expect(model.new).to allow_value(1).for(:status)
|
819
|
-
end
|
820
|
-
end
|
821
|
-
end
|
822
|
-
end
|
823
|
-
end
|