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
@@ -11,7 +11,7 @@ module Shoulda
|
|
11
11
|
# end
|
12
12
|
#
|
13
13
|
# # RSpec
|
14
|
-
# describe Person do
|
14
|
+
# RSpec.describe Person, type: :model do
|
15
15
|
# it { should belong_to(:organization) }
|
16
16
|
# end
|
17
17
|
#
|
@@ -28,7 +28,7 @@ module Shoulda
|
|
28
28
|
# end
|
29
29
|
#
|
30
30
|
# # RSpec
|
31
|
-
# describe Comment do
|
31
|
+
# RSpec.describe Comment, type: :model do
|
32
32
|
# it { should belong_to(:commentable) }
|
33
33
|
# end
|
34
34
|
#
|
@@ -49,7 +49,7 @@ module Shoulda
|
|
49
49
|
# end
|
50
50
|
#
|
51
51
|
# # RSpec
|
52
|
-
# describe Person do
|
52
|
+
# RSpec.describe Person, type: :model do
|
53
53
|
# it do
|
54
54
|
# should belong_to(:family).
|
55
55
|
# conditions(everyone_is_perfect: false)
|
@@ -72,7 +72,7 @@ module Shoulda
|
|
72
72
|
# end
|
73
73
|
#
|
74
74
|
# # RSpec
|
75
|
-
# describe Person do
|
75
|
+
# RSpec.describe Person, type: :model do
|
76
76
|
# it { should belong_to(:previous_company).order('hired_on desc') }
|
77
77
|
# end
|
78
78
|
#
|
@@ -91,7 +91,7 @@ module Shoulda
|
|
91
91
|
# end
|
92
92
|
#
|
93
93
|
# # RSpec
|
94
|
-
# describe Person do
|
94
|
+
# RSpec.describe Person, type: :model do
|
95
95
|
# it { should belong_to(:ancient_city).class_name('City') }
|
96
96
|
# end
|
97
97
|
#
|
@@ -109,7 +109,7 @@ module Shoulda
|
|
109
109
|
# end
|
110
110
|
#
|
111
111
|
# # RSpec
|
112
|
-
# describe Person do
|
112
|
+
# RSpec.describe Person, type: :model do
|
113
113
|
# it do
|
114
114
|
# should belong_to(:great_country).
|
115
115
|
# with_primary_key('country_id')
|
@@ -131,7 +131,7 @@ module Shoulda
|
|
131
131
|
# end
|
132
132
|
#
|
133
133
|
# # RSpec
|
134
|
-
# describe Person do
|
134
|
+
# RSpec.describe Person, type: :model do
|
135
135
|
# it do
|
136
136
|
# should belong_to(:great_country).
|
137
137
|
# with_foreign_key('country_id')
|
@@ -153,7 +153,7 @@ module Shoulda
|
|
153
153
|
# end
|
154
154
|
#
|
155
155
|
# # RSpec
|
156
|
-
# describe Person do
|
156
|
+
# RSpec.describe Person, type: :model do
|
157
157
|
# it { should belong_to(:world).dependent(:destroy) }
|
158
158
|
# end
|
159
159
|
#
|
@@ -165,7 +165,7 @@ module Shoulda
|
|
165
165
|
# To assert that *any* `:dependent` option was specified, use `true`:
|
166
166
|
#
|
167
167
|
# # RSpec
|
168
|
-
# describe Person do
|
168
|
+
# RSpec.describe Person, type: :model do
|
169
169
|
# it { should belong_to(:world).dependent(true) }
|
170
170
|
# end
|
171
171
|
#
|
@@ -176,7 +176,7 @@ module Shoulda
|
|
176
176
|
# end
|
177
177
|
#
|
178
178
|
# # RSpec
|
179
|
-
# describe Person do
|
179
|
+
# RSpec.describe Person, type: :model do
|
180
180
|
# it { should belong_to(:company).dependent(false) }
|
181
181
|
# end
|
182
182
|
#
|
@@ -190,7 +190,7 @@ module Shoulda
|
|
190
190
|
# end
|
191
191
|
#
|
192
192
|
# # RSpec
|
193
|
-
# describe Person do
|
193
|
+
# RSpec.describe Person, type: :model do
|
194
194
|
# it { should belong_to(:organization).counter_cache(true) }
|
195
195
|
# end
|
196
196
|
#
|
@@ -208,7 +208,7 @@ module Shoulda
|
|
208
208
|
# end
|
209
209
|
#
|
210
210
|
# # RSpec
|
211
|
-
# describe Person do
|
211
|
+
# RSpec.describe Person, type: :model do
|
212
212
|
# it { should belong_to(:organization).touch(true) }
|
213
213
|
# end
|
214
214
|
#
|
@@ -217,7 +217,7 @@ module Shoulda
|
|
217
217
|
# should belong_to(:organization).touch(true)
|
218
218
|
# end
|
219
219
|
#
|
220
|
-
#
|
220
|
+
# ##### autosave
|
221
221
|
#
|
222
222
|
# Use `autosave` to assert that the `:autosave` option was specified.
|
223
223
|
#
|
@@ -226,7 +226,7 @@ module Shoulda
|
|
226
226
|
# end
|
227
227
|
#
|
228
228
|
# # RSpec
|
229
|
-
# describe Account do
|
229
|
+
# RSpec.describe Account, type: :model do
|
230
230
|
# it { should belong_to(:bank).autosave(true) }
|
231
231
|
# end
|
232
232
|
#
|
@@ -253,6 +253,73 @@ module Shoulda
|
|
253
253
|
# should belong_to(:organization).inverse_of(:employees)
|
254
254
|
# end
|
255
255
|
#
|
256
|
+
# ##### required
|
257
|
+
#
|
258
|
+
# Use `required` to assert that the association is not allowed to be nil.
|
259
|
+
# (Enabled by default in Rails 5+.)
|
260
|
+
#
|
261
|
+
# class Person < ActiveRecord::Base
|
262
|
+
# belongs_to :organization, required: true
|
263
|
+
# end
|
264
|
+
#
|
265
|
+
# # RSpec
|
266
|
+
# describe Person
|
267
|
+
# it { should belong_to(:organization).required }
|
268
|
+
# end
|
269
|
+
#
|
270
|
+
# # Minitest (Shoulda)
|
271
|
+
# class PersonTest < ActiveSupport::TestCase
|
272
|
+
# should belong_to(:organization).required
|
273
|
+
# end
|
274
|
+
#
|
275
|
+
# ##### without_validating_presence
|
276
|
+
#
|
277
|
+
# Use `without_validating_presence` with `belong_to` to prevent the
|
278
|
+
# matcher from checking whether the association disallows nil (Rails 5+
|
279
|
+
# only). This can be helpful if you have a custom hook that always sets
|
280
|
+
# the association to a meaningful value:
|
281
|
+
#
|
282
|
+
# class Person < ActiveRecord::Base
|
283
|
+
# belongs_to :organization
|
284
|
+
#
|
285
|
+
# before_validation :autoassign_organization
|
286
|
+
#
|
287
|
+
# private
|
288
|
+
#
|
289
|
+
# def autoassign_organization
|
290
|
+
# self.organization = Organization.create!
|
291
|
+
# end
|
292
|
+
# end
|
293
|
+
#
|
294
|
+
# # RSpec
|
295
|
+
# describe Person
|
296
|
+
# it { should belong_to(:organization).without_validating_presence }
|
297
|
+
# end
|
298
|
+
#
|
299
|
+
# # Minitest (Shoulda)
|
300
|
+
# class PersonTest < ActiveSupport::TestCase
|
301
|
+
# should belong_to(:organization).without_validating_presence
|
302
|
+
# end
|
303
|
+
#
|
304
|
+
# ##### optional
|
305
|
+
#
|
306
|
+
# Use `optional` to assert that the association is allowed to be nil.
|
307
|
+
# (Rails 5+ only.)
|
308
|
+
#
|
309
|
+
# class Person < ActiveRecord::Base
|
310
|
+
# belongs_to :organization, optional: true
|
311
|
+
# end
|
312
|
+
#
|
313
|
+
# # RSpec
|
314
|
+
# describe Person
|
315
|
+
# it { should belong_to(:organization).optional }
|
316
|
+
# end
|
317
|
+
#
|
318
|
+
# # Minitest (Shoulda)
|
319
|
+
# class PersonTest < ActiveSupport::TestCase
|
320
|
+
# should belong_to(:organization).optional
|
321
|
+
# end
|
322
|
+
#
|
256
323
|
# @return [AssociationMatcher]
|
257
324
|
#
|
258
325
|
def belong_to(name)
|
@@ -267,7 +334,7 @@ module Shoulda
|
|
267
334
|
# end
|
268
335
|
#
|
269
336
|
# # RSpec
|
270
|
-
# describe Person do
|
337
|
+
# RSpec.describe Person, type: :model do
|
271
338
|
# it { should have_many(:friends) }
|
272
339
|
# end
|
273
340
|
#
|
@@ -284,7 +351,7 @@ module Shoulda
|
|
284
351
|
# end
|
285
352
|
#
|
286
353
|
# # RSpec
|
287
|
-
# describe Person do
|
354
|
+
# RSpec.describe Person, type: :model do
|
288
355
|
# it { should have_many(:pictures) }
|
289
356
|
# end
|
290
357
|
#
|
@@ -305,7 +372,7 @@ module Shoulda
|
|
305
372
|
# end
|
306
373
|
#
|
307
374
|
# # RSpec
|
308
|
-
# describe Person do
|
375
|
+
# RSpec.describe Person, type: :model do
|
309
376
|
# it { should have_many(:coins).conditions(quality: 'mint') }
|
310
377
|
# end
|
311
378
|
#
|
@@ -324,7 +391,7 @@ module Shoulda
|
|
324
391
|
# end
|
325
392
|
#
|
326
393
|
# # RSpec
|
327
|
-
# describe Person do
|
394
|
+
# RSpec.describe Person, type: :model do
|
328
395
|
# it { should have_many(:shirts).order('color') }
|
329
396
|
# end
|
330
397
|
#
|
@@ -343,7 +410,7 @@ module Shoulda
|
|
343
410
|
# end
|
344
411
|
#
|
345
412
|
# # RSpec
|
346
|
-
# describe Person do
|
413
|
+
# RSpec.describe Person, type: :model do
|
347
414
|
# it { should have_many(:hopes).class_name('Dream') }
|
348
415
|
# end
|
349
416
|
#
|
@@ -361,7 +428,7 @@ module Shoulda
|
|
361
428
|
# end
|
362
429
|
#
|
363
430
|
# # RSpec
|
364
|
-
# describe Person do
|
431
|
+
# RSpec.describe Person, type: :model do
|
365
432
|
# it { should have_many(:worries).with_primary_key('worrier_id') }
|
366
433
|
# end
|
367
434
|
#
|
@@ -379,7 +446,7 @@ module Shoulda
|
|
379
446
|
# end
|
380
447
|
#
|
381
448
|
# # RSpec
|
382
|
-
# describe Person do
|
449
|
+
# RSpec.describe Person, type: :model do
|
383
450
|
# it { should have_many(:worries).with_foreign_key('worrier_id') }
|
384
451
|
# end
|
385
452
|
#
|
@@ -397,7 +464,7 @@ module Shoulda
|
|
397
464
|
# end
|
398
465
|
#
|
399
466
|
# # RSpec
|
400
|
-
# describe Person do
|
467
|
+
# RSpec.describe Person, type: :model do
|
401
468
|
# it { should have_many(:secret_documents).dependent(:destroy) }
|
402
469
|
# end
|
403
470
|
#
|
@@ -416,7 +483,7 @@ module Shoulda
|
|
416
483
|
# end
|
417
484
|
#
|
418
485
|
# # RSpec
|
419
|
-
# describe Person do
|
486
|
+
# RSpec.describe Person, type: :model do
|
420
487
|
# it { should have_many(:acquaintances).through(:friends) }
|
421
488
|
# end
|
422
489
|
#
|
@@ -435,7 +502,7 @@ module Shoulda
|
|
435
502
|
# end
|
436
503
|
#
|
437
504
|
# # RSpec
|
438
|
-
# describe Person do
|
505
|
+
# RSpec.describe Person, type: :model do
|
439
506
|
# it do
|
440
507
|
# should have_many(:job_offers).
|
441
508
|
# through(:friends).
|
@@ -459,7 +526,7 @@ module Shoulda
|
|
459
526
|
# end
|
460
527
|
#
|
461
528
|
# # RSpec
|
462
|
-
# describe Person do
|
529
|
+
# RSpec.describe Person, type: :model do
|
463
530
|
# it { should have_many(:ideas).validate(false) }
|
464
531
|
# end
|
465
532
|
#
|
@@ -468,7 +535,7 @@ module Shoulda
|
|
468
535
|
# should have_many(:ideas).validate(false)
|
469
536
|
# end
|
470
537
|
#
|
471
|
-
#
|
538
|
+
# ##### autosave
|
472
539
|
#
|
473
540
|
# Use `autosave` to assert that the `:autosave` option was specified.
|
474
541
|
#
|
@@ -477,7 +544,7 @@ module Shoulda
|
|
477
544
|
# end
|
478
545
|
#
|
479
546
|
# # RSpec
|
480
|
-
# describe Player do
|
547
|
+
# RSpec.describe Player, type: :model do
|
481
548
|
# it { should have_many(:games).autosave(true) }
|
482
549
|
# end
|
483
550
|
#
|
@@ -486,6 +553,43 @@ module Shoulda
|
|
486
553
|
# should have_many(:games).autosave(true)
|
487
554
|
# end
|
488
555
|
#
|
556
|
+
# ##### index_errors
|
557
|
+
#
|
558
|
+
# Use `index_errors` to assert that the `:index_errors` option was
|
559
|
+
# specified.
|
560
|
+
#
|
561
|
+
# class Player < ActiveRecord::Base
|
562
|
+
# has_many :games, index_errors: true
|
563
|
+
# end
|
564
|
+
#
|
565
|
+
# # RSpec
|
566
|
+
# RSpec.describe Player, type: :model do
|
567
|
+
# it { should have_many(:games).index_errors(true) }
|
568
|
+
# end
|
569
|
+
#
|
570
|
+
# # Minitest (Shoulda)
|
571
|
+
# class PlayerTest < ActiveSupport::TestCase
|
572
|
+
# should have_many(:games).index_errors(true)
|
573
|
+
# end
|
574
|
+
#
|
575
|
+
# ##### inverse_of
|
576
|
+
#
|
577
|
+
# Use `inverse_of` to assert that the `:inverse_of` option was specified.
|
578
|
+
#
|
579
|
+
# class Organization < ActiveRecord::Base
|
580
|
+
# has_many :employees, inverse_of: :company
|
581
|
+
# end
|
582
|
+
#
|
583
|
+
# # RSpec
|
584
|
+
# describe Organization
|
585
|
+
# it { should have_many(:employees).inverse_of(:company) }
|
586
|
+
# end
|
587
|
+
#
|
588
|
+
# # Minitest (Shoulda)
|
589
|
+
# class OrganizationTest < ActiveSupport::TestCase
|
590
|
+
# should have_many(:employees).inverse_of(:company)
|
591
|
+
# end
|
592
|
+
#
|
489
593
|
# @return [AssociationMatcher]
|
490
594
|
#
|
491
595
|
def have_many(name)
|
@@ -500,7 +604,7 @@ module Shoulda
|
|
500
604
|
# end
|
501
605
|
#
|
502
606
|
# # RSpec
|
503
|
-
# describe Person do
|
607
|
+
# RSpec.describe Person, type: :model do
|
504
608
|
# it { should have_one(:partner) }
|
505
609
|
# end
|
506
610
|
#
|
@@ -521,7 +625,7 @@ module Shoulda
|
|
521
625
|
# end
|
522
626
|
#
|
523
627
|
# # RSpec
|
524
|
-
# describe Person do
|
628
|
+
# RSpec.describe Person, type: :model do
|
525
629
|
# it { should have_one(:pet).conditions('weight < 80') }
|
526
630
|
# end
|
527
631
|
#
|
@@ -540,7 +644,7 @@ module Shoulda
|
|
540
644
|
# end
|
541
645
|
#
|
542
646
|
# # RSpec
|
543
|
-
# describe Person do
|
647
|
+
# RSpec.describe Person, type: :model do
|
544
648
|
# it { should have_one(:focus).order('priority desc') }
|
545
649
|
# end
|
546
650
|
#
|
@@ -559,7 +663,7 @@ module Shoulda
|
|
559
663
|
# end
|
560
664
|
#
|
561
665
|
# # RSpec
|
562
|
-
# describe Person do
|
666
|
+
# RSpec.describe Person, type: :model do
|
563
667
|
# it { should have_one(:chance).class_name('Opportunity') }
|
564
668
|
# end
|
565
669
|
#
|
@@ -577,7 +681,7 @@ module Shoulda
|
|
577
681
|
# end
|
578
682
|
#
|
579
683
|
# # RSpec
|
580
|
-
# describe Person do
|
684
|
+
# RSpec.describe Person, type: :model do
|
581
685
|
# it { should have_one(:contract).dependent(:nullify) }
|
582
686
|
# end
|
583
687
|
#
|
@@ -595,7 +699,7 @@ module Shoulda
|
|
595
699
|
# end
|
596
700
|
#
|
597
701
|
# # RSpec
|
598
|
-
# describe Person do
|
702
|
+
# RSpec.describe Person, type: :model do
|
599
703
|
# it { should have_one(:job).with_primary_key('worker_id') }
|
600
704
|
# end
|
601
705
|
#
|
@@ -613,7 +717,7 @@ module Shoulda
|
|
613
717
|
# end
|
614
718
|
#
|
615
719
|
# # RSpec
|
616
|
-
# describe Person do
|
720
|
+
# RSpec.describe Person, type: :model do
|
617
721
|
# it { should have_one(:job).with_foreign_key('worker_id') }
|
618
722
|
# end
|
619
723
|
#
|
@@ -632,7 +736,7 @@ module Shoulda
|
|
632
736
|
# end
|
633
737
|
#
|
634
738
|
# # RSpec
|
635
|
-
# describe Person do
|
739
|
+
# RSpec.describe Person, type: :model do
|
636
740
|
# it { should have_one(:life).through(:partner) }
|
637
741
|
# end
|
638
742
|
#
|
@@ -651,7 +755,7 @@ module Shoulda
|
|
651
755
|
# end
|
652
756
|
#
|
653
757
|
# # RSpec
|
654
|
-
# describe Person do
|
758
|
+
# RSpec.describe Person, type: :model do
|
655
759
|
# it { should have_one(:car).through(:partner).source(:vehicle) }
|
656
760
|
# end
|
657
761
|
#
|
@@ -669,7 +773,7 @@ module Shoulda
|
|
669
773
|
# end
|
670
774
|
#
|
671
775
|
# # RSpec
|
672
|
-
# describe Person do
|
776
|
+
# RSpec.describe Person, type: :model do
|
673
777
|
# it { should have_one(:parking_card).validate(false) }
|
674
778
|
# end
|
675
779
|
#
|
@@ -678,7 +782,7 @@ module Shoulda
|
|
678
782
|
# should have_one(:parking_card).validate(false)
|
679
783
|
# end
|
680
784
|
#
|
681
|
-
#
|
785
|
+
# ##### autosave
|
682
786
|
#
|
683
787
|
# Use `autosave` to assert that the `:autosave` option was specified.
|
684
788
|
#
|
@@ -687,7 +791,7 @@ module Shoulda
|
|
687
791
|
# end
|
688
792
|
#
|
689
793
|
# # RSpec
|
690
|
-
# describe Account do
|
794
|
+
# RSpec.describe Account, type: :model do
|
691
795
|
# it { should have_one(:bank).autosave(true) }
|
692
796
|
# end
|
693
797
|
#
|
@@ -696,6 +800,25 @@ module Shoulda
|
|
696
800
|
# should have_one(:bank).autosave(true)
|
697
801
|
# end
|
698
802
|
#
|
803
|
+
# ##### required
|
804
|
+
#
|
805
|
+
# Use `required` to assert that the association is not allowed to be nil.
|
806
|
+
# (Rails 5+ only.)
|
807
|
+
#
|
808
|
+
# class Person < ActiveRecord::Base
|
809
|
+
# has_one :brain, required: true
|
810
|
+
# end
|
811
|
+
#
|
812
|
+
# # RSpec
|
813
|
+
# describe Person
|
814
|
+
# it { should have_one(:brain).required }
|
815
|
+
# end
|
816
|
+
#
|
817
|
+
# # Minitest (Shoulda)
|
818
|
+
# class PersonTest < ActiveSupport::TestCase
|
819
|
+
# should have_one(:brain).required
|
820
|
+
# end
|
821
|
+
#
|
699
822
|
# @return [AssociationMatcher]
|
700
823
|
#
|
701
824
|
def have_one(name)
|
@@ -711,7 +834,7 @@ module Shoulda
|
|
711
834
|
# end
|
712
835
|
#
|
713
836
|
# # RSpec
|
714
|
-
# describe Person do
|
837
|
+
# RSpec.describe Person, type: :model do
|
715
838
|
# it { should have_and_belong_to_many(:awards) }
|
716
839
|
# end
|
717
840
|
#
|
@@ -732,7 +855,7 @@ module Shoulda
|
|
732
855
|
# end
|
733
856
|
#
|
734
857
|
# # RSpec
|
735
|
-
# describe Person do
|
858
|
+
# RSpec.describe Person, type: :model do
|
736
859
|
# it do
|
737
860
|
# should have_and_belong_to_many(:issues).
|
738
861
|
# conditions(difficulty: 'hard')
|
@@ -755,7 +878,7 @@ module Shoulda
|
|
755
878
|
# end
|
756
879
|
#
|
757
880
|
# # RSpec
|
758
|
-
# describe Person do
|
881
|
+
# RSpec.describe Person, type: :model do
|
759
882
|
# it do
|
760
883
|
# should have_and_belong_to_many(:projects).
|
761
884
|
# order('time_spent')
|
@@ -778,7 +901,7 @@ module Shoulda
|
|
778
901
|
# end
|
779
902
|
#
|
780
903
|
# # RSpec
|
781
|
-
# describe Person do
|
904
|
+
# RSpec.describe Person, type: :model do
|
782
905
|
# it do
|
783
906
|
# should have_and_belong_to_many(:places_visited).
|
784
907
|
# class_name('City')
|
@@ -797,21 +920,21 @@ module Shoulda
|
|
797
920
|
# asserts that the table you're referring to actually exists.
|
798
921
|
#
|
799
922
|
# class Person < ActiveRecord::Base
|
800
|
-
# has_and_belongs_to_many :issues, join_table:
|
923
|
+
# has_and_belongs_to_many :issues, join_table: :people_tickets
|
801
924
|
# end
|
802
925
|
#
|
803
926
|
# # RSpec
|
804
|
-
# describe Person do
|
927
|
+
# RSpec.describe Person, type: :model do
|
805
928
|
# it do
|
806
929
|
# should have_and_belong_to_many(:issues).
|
807
|
-
# join_table(
|
930
|
+
# join_table(:people_tickets)
|
808
931
|
# end
|
809
932
|
# end
|
810
933
|
#
|
811
934
|
# # Minitest (Shoulda)
|
812
935
|
# class PersonTest < ActiveSupport::TestCase
|
813
936
|
# should have_and_belong_to_many(:issues).
|
814
|
-
# join_table(
|
937
|
+
# join_table(:people_tickets)
|
815
938
|
# end
|
816
939
|
#
|
817
940
|
# ##### validate
|
@@ -823,7 +946,7 @@ module Shoulda
|
|
823
946
|
# end
|
824
947
|
#
|
825
948
|
# # RSpec
|
826
|
-
# describe Person do
|
949
|
+
# RSpec.describe Person, type: :model do
|
827
950
|
# it do
|
828
951
|
# should have_and_belong_to_many(:interviews).
|
829
952
|
# validate(false)
|
@@ -836,7 +959,7 @@ module Shoulda
|
|
836
959
|
# validate(false)
|
837
960
|
# end
|
838
961
|
#
|
839
|
-
#
|
962
|
+
# ##### autosave
|
840
963
|
#
|
841
964
|
# Use `autosave` to assert that the `:autosave` option was specified.
|
842
965
|
#
|
@@ -845,7 +968,7 @@ module Shoulda
|
|
845
968
|
# end
|
846
969
|
#
|
847
970
|
# # RSpec
|
848
|
-
# describe Publisher do
|
971
|
+
# RSpec.describe Publisher, type: :model do
|
849
972
|
# it { should have_and_belong_to_many(:advertisers).autosave(true) }
|
850
973
|
# end
|
851
974
|
#
|
@@ -862,6 +985,13 @@ module Shoulda
|
|
862
985
|
|
863
986
|
# @private
|
864
987
|
class AssociationMatcher
|
988
|
+
MACROS = {
|
989
|
+
'belongs_to' => 'belong to',
|
990
|
+
'has_many' => 'have many',
|
991
|
+
'has_one' => 'have one',
|
992
|
+
'has_and_belongs_to_many' => 'have and belong to many',
|
993
|
+
}.freeze
|
994
|
+
|
865
995
|
delegate :reflection, :model_class, :associated_class, :through?,
|
866
996
|
:polymorphic?, to: :reflector
|
867
997
|
|
@@ -873,42 +1003,63 @@ module Shoulda
|
|
873
1003
|
@options = {}
|
874
1004
|
@submatchers = []
|
875
1005
|
@missing = ''
|
1006
|
+
|
1007
|
+
if macro == :belongs_to
|
1008
|
+
required(belongs_to_required_by_default?)
|
1009
|
+
end
|
876
1010
|
end
|
877
1011
|
|
878
1012
|
def through(through)
|
879
|
-
|
880
|
-
|
1013
|
+
add_submatcher(
|
1014
|
+
AssociationMatchers::ThroughMatcher,
|
1015
|
+
through,
|
1016
|
+
name,
|
1017
|
+
)
|
881
1018
|
self
|
882
1019
|
end
|
883
1020
|
|
884
1021
|
def dependent(dependent)
|
885
|
-
|
886
|
-
|
1022
|
+
add_submatcher(
|
1023
|
+
AssociationMatchers::DependentMatcher,
|
1024
|
+
dependent,
|
1025
|
+
name,
|
1026
|
+
)
|
887
1027
|
self
|
888
1028
|
end
|
889
1029
|
|
890
1030
|
def order(order)
|
891
|
-
|
892
|
-
|
1031
|
+
add_submatcher(
|
1032
|
+
AssociationMatchers::OrderMatcher,
|
1033
|
+
order,
|
1034
|
+
name,
|
1035
|
+
)
|
893
1036
|
self
|
894
1037
|
end
|
895
1038
|
|
896
1039
|
def counter_cache(counter_cache = true)
|
897
|
-
|
898
|
-
|
1040
|
+
add_submatcher(
|
1041
|
+
AssociationMatchers::CounterCacheMatcher,
|
1042
|
+
counter_cache,
|
1043
|
+
name,
|
1044
|
+
)
|
899
1045
|
self
|
900
1046
|
end
|
901
1047
|
|
902
1048
|
def inverse_of(inverse_of)
|
903
|
-
|
904
|
-
AssociationMatchers::InverseOfMatcher
|
905
|
-
|
1049
|
+
add_submatcher(
|
1050
|
+
AssociationMatchers::InverseOfMatcher,
|
1051
|
+
inverse_of,
|
1052
|
+
name,
|
1053
|
+
)
|
906
1054
|
self
|
907
1055
|
end
|
908
1056
|
|
909
1057
|
def source(source)
|
910
|
-
|
911
|
-
|
1058
|
+
add_submatcher(
|
1059
|
+
AssociationMatchers::SourceMatcher,
|
1060
|
+
source,
|
1061
|
+
name,
|
1062
|
+
)
|
912
1063
|
self
|
913
1064
|
end
|
914
1065
|
|
@@ -922,6 +1073,11 @@ module Shoulda
|
|
922
1073
|
self
|
923
1074
|
end
|
924
1075
|
|
1076
|
+
def index_errors(index_errors)
|
1077
|
+
@options[:index_errors] = index_errors
|
1078
|
+
self
|
1079
|
+
end
|
1080
|
+
|
925
1081
|
def class_name(class_name)
|
926
1082
|
@options[:class_name] = class_name
|
927
1083
|
self
|
@@ -937,6 +1093,26 @@ module Shoulda
|
|
937
1093
|
self
|
938
1094
|
end
|
939
1095
|
|
1096
|
+
def required(required = true)
|
1097
|
+
remove_submatcher(AssociationMatchers::OptionalMatcher)
|
1098
|
+
add_submatcher(
|
1099
|
+
AssociationMatchers::RequiredMatcher,
|
1100
|
+
name,
|
1101
|
+
required,
|
1102
|
+
)
|
1103
|
+
self
|
1104
|
+
end
|
1105
|
+
|
1106
|
+
def optional(optional = true)
|
1107
|
+
remove_submatcher(AssociationMatchers::RequiredMatcher)
|
1108
|
+
add_submatcher(
|
1109
|
+
AssociationMatchers::OptionalMatcher,
|
1110
|
+
name,
|
1111
|
+
optional,
|
1112
|
+
)
|
1113
|
+
self
|
1114
|
+
end
|
1115
|
+
|
940
1116
|
def validate(validate = true)
|
941
1117
|
@options[:validate] = validate
|
942
1118
|
self
|
@@ -952,9 +1128,16 @@ module Shoulda
|
|
952
1128
|
self
|
953
1129
|
end
|
954
1130
|
|
1131
|
+
def without_validating_presence
|
1132
|
+
remove_submatcher(AssociationMatchers::RequiredMatcher)
|
1133
|
+
self
|
1134
|
+
end
|
1135
|
+
|
955
1136
|
def description
|
956
1137
|
description = "#{macro_description} #{name}"
|
957
|
-
|
1138
|
+
if options.key?(:class_name)
|
1139
|
+
description += " class_name => #{options[:class_name]}"
|
1140
|
+
end
|
958
1141
|
[description, submatchers.map(&:description)].flatten.join(' ')
|
959
1142
|
end
|
960
1143
|
|
@@ -970,12 +1153,14 @@ module Shoulda
|
|
970
1153
|
@subject = subject
|
971
1154
|
association_exists? &&
|
972
1155
|
macro_correct? &&
|
1156
|
+
validate_inverse_of_through_association &&
|
973
1157
|
(polymorphic? || class_exists?) &&
|
974
1158
|
foreign_key_exists? &&
|
975
1159
|
primary_key_exists? &&
|
976
1160
|
class_name_correct? &&
|
977
1161
|
join_table_correct? &&
|
978
1162
|
autosave_correct? &&
|
1163
|
+
index_errors_correct? &&
|
979
1164
|
conditions_correct? &&
|
980
1165
|
validate_correct? &&
|
981
1166
|
touch_correct? &&
|
@@ -987,7 +1172,8 @@ module Shoulda
|
|
987
1172
|
end
|
988
1173
|
|
989
1174
|
def option_verifier
|
990
|
-
@
|
1175
|
+
@_option_verifier ||=
|
1176
|
+
AssociationMatchers::OptionVerifier.new(reflector)
|
991
1177
|
end
|
992
1178
|
|
993
1179
|
protected
|
@@ -995,44 +1181,49 @@ module Shoulda
|
|
995
1181
|
attr_reader :submatchers, :missing, :subject, :macro
|
996
1182
|
|
997
1183
|
def reflector
|
998
|
-
@
|
1184
|
+
@_reflector ||= AssociationMatchers::ModelReflector.new(subject, name)
|
999
1185
|
end
|
1000
1186
|
|
1001
|
-
def add_submatcher(
|
1002
|
-
|
1187
|
+
def add_submatcher(matcher_class, *args)
|
1188
|
+
remove_submatcher(matcher_class)
|
1189
|
+
submatchers << matcher_class.new(*args)
|
1003
1190
|
end
|
1004
1191
|
|
1005
|
-
def
|
1006
|
-
|
1007
|
-
|
1008
|
-
'belong to'
|
1009
|
-
when 'has_many'
|
1010
|
-
'have many'
|
1011
|
-
when 'has_one'
|
1012
|
-
'have one'
|
1013
|
-
when 'has_and_belongs_to_many'
|
1014
|
-
'have and belong to many'
|
1192
|
+
def remove_submatcher(matcher_class)
|
1193
|
+
submatchers.delete_if do |submatcher|
|
1194
|
+
submatcher.is_a?(matcher_class)
|
1015
1195
|
end
|
1016
1196
|
end
|
1017
1197
|
|
1198
|
+
def macro_description
|
1199
|
+
MACROS[macro.to_s]
|
1200
|
+
end
|
1201
|
+
|
1018
1202
|
def expectation
|
1019
|
-
|
1203
|
+
expectation =
|
1204
|
+
"#{model_class.name} to have a #{macro} association called #{name}"
|
1205
|
+
|
1206
|
+
if through?
|
1207
|
+
expectation << " through #{reflector.has_and_belongs_to_many_name}"
|
1208
|
+
end
|
1209
|
+
|
1210
|
+
expectation
|
1020
1211
|
end
|
1021
1212
|
|
1022
1213
|
def missing_options
|
1023
1214
|
missing_options = [missing, missing_options_for_failing_submatchers]
|
1024
|
-
missing_options.flatten.
|
1215
|
+
missing_options.flatten.select(&:present?).join(', ')
|
1025
1216
|
end
|
1026
1217
|
|
1027
1218
|
def failing_submatchers
|
1028
|
-
@
|
1219
|
+
@_failing_submatchers ||= submatchers.reject do |matcher|
|
1029
1220
|
matcher.matches?(subject)
|
1030
1221
|
end
|
1031
1222
|
end
|
1032
1223
|
|
1033
1224
|
def missing_options_for_failing_submatchers
|
1034
|
-
if defined?(@
|
1035
|
-
@
|
1225
|
+
if defined?(@_failing_submatchers)
|
1226
|
+
@_failing_submatchers.map(&:missing_option)
|
1036
1227
|
else
|
1037
1228
|
[]
|
1038
1229
|
end
|
@@ -1059,6 +1250,14 @@ module Shoulda
|
|
1059
1250
|
end
|
1060
1251
|
end
|
1061
1252
|
|
1253
|
+
def validate_inverse_of_through_association
|
1254
|
+
reflector.validate_inverse_of_through_association!
|
1255
|
+
true
|
1256
|
+
rescue ::ActiveRecord::ActiveRecordError => e
|
1257
|
+
@missing = e.message
|
1258
|
+
false
|
1259
|
+
end
|
1260
|
+
|
1062
1261
|
def macro_supports_primary_key?
|
1063
1262
|
macro == :belongs_to ||
|
1064
1263
|
([:has_many, :has_one].include?(macro) && !through?)
|
@@ -1084,10 +1283,14 @@ module Shoulda
|
|
1084
1283
|
|
1085
1284
|
def class_name_correct?
|
1086
1285
|
if options.key?(:class_name)
|
1087
|
-
if option_verifier.correct_for_constant?(
|
1286
|
+
if option_verifier.correct_for_constant?(
|
1287
|
+
:class_name,
|
1288
|
+
options[:class_name],
|
1289
|
+
)
|
1088
1290
|
true
|
1089
1291
|
else
|
1090
|
-
@missing = "#{name} should resolve to #{options[:class_name]}
|
1292
|
+
@missing = "#{name} should resolve to #{options[:class_name]}"\
|
1293
|
+
' for class_name'
|
1091
1294
|
false
|
1092
1295
|
end
|
1093
1296
|
else
|
@@ -1096,7 +1299,10 @@ module Shoulda
|
|
1096
1299
|
end
|
1097
1300
|
|
1098
1301
|
def join_table_correct?
|
1099
|
-
if
|
1302
|
+
if (
|
1303
|
+
macro != :has_and_belongs_to_many ||
|
1304
|
+
join_table_matcher.matches?(@subject)
|
1305
|
+
)
|
1100
1306
|
true
|
1101
1307
|
else
|
1102
1308
|
@missing = join_table_matcher.failure_message
|
@@ -1105,8 +1311,10 @@ module Shoulda
|
|
1105
1311
|
end
|
1106
1312
|
|
1107
1313
|
def join_table_matcher
|
1108
|
-
@
|
1109
|
-
|
1314
|
+
@_join_table_matcher ||= AssociationMatchers::JoinTableMatcher.new(
|
1315
|
+
self,
|
1316
|
+
reflector,
|
1317
|
+
)
|
1110
1318
|
end
|
1111
1319
|
|
1112
1320
|
def class_exists?
|
@@ -1119,10 +1327,14 @@ module Shoulda
|
|
1119
1327
|
|
1120
1328
|
def autosave_correct?
|
1121
1329
|
if options.key?(:autosave)
|
1122
|
-
if option_verifier.correct_for_boolean?(
|
1330
|
+
if option_verifier.correct_for_boolean?(
|
1331
|
+
:autosave,
|
1332
|
+
options[:autosave],
|
1333
|
+
)
|
1123
1334
|
true
|
1124
1335
|
else
|
1125
|
-
@missing = "#{name} should have autosave set to
|
1336
|
+
@missing = "#{name} should have autosave set to"\
|
1337
|
+
" #{options[:autosave]}"
|
1126
1338
|
false
|
1127
1339
|
end
|
1128
1340
|
else
|
@@ -1130,12 +1342,32 @@ module Shoulda
|
|
1130
1342
|
end
|
1131
1343
|
end
|
1132
1344
|
|
1345
|
+
def index_errors_correct?
|
1346
|
+
return true unless options.key?(:index_errors)
|
1347
|
+
|
1348
|
+
if option_verifier.correct_for_boolean?(
|
1349
|
+
:index_errors,
|
1350
|
+
options[:index_errors],
|
1351
|
+
)
|
1352
|
+
true
|
1353
|
+
else
|
1354
|
+
@missing =
|
1355
|
+
"#{name} should have index_errors set to " +
|
1356
|
+
options[:index_errors].to_s
|
1357
|
+
false
|
1358
|
+
end
|
1359
|
+
end
|
1360
|
+
|
1133
1361
|
def conditions_correct?
|
1134
1362
|
if options.key?(:conditions)
|
1135
|
-
if option_verifier.correct_for_relation_clause?(
|
1363
|
+
if option_verifier.correct_for_relation_clause?(
|
1364
|
+
:conditions,
|
1365
|
+
options[:conditions],
|
1366
|
+
)
|
1136
1367
|
true
|
1137
1368
|
else
|
1138
|
-
@missing = "#{name} should have the following conditions:
|
1369
|
+
@missing = "#{name} should have the following conditions:" +
|
1370
|
+
" #{options[:conditions]}"
|
1139
1371
|
false
|
1140
1372
|
end
|
1141
1373
|
else
|
@@ -1162,24 +1394,49 @@ module Shoulda
|
|
1162
1394
|
end
|
1163
1395
|
|
1164
1396
|
def class_has_foreign_key?(klass)
|
1165
|
-
|
1166
|
-
|
1397
|
+
@missing = validate_foreign_key(klass)
|
1398
|
+
|
1399
|
+
@missing.nil?
|
1400
|
+
end
|
1401
|
+
|
1402
|
+
def validate_foreign_key(klass)
|
1403
|
+
if options.key?(:foreign_key) && !foreign_key_correct?
|
1404
|
+
foreign_key_failure_message(klass, options[:foreign_key])
|
1405
|
+
elsif !has_column?(klass, actual_foreign_key)
|
1406
|
+
foreign_key_failure_message(klass, actual_foreign_key)
|
1407
|
+
end
|
1408
|
+
end
|
1409
|
+
|
1410
|
+
def has_column?(klass, column)
|
1411
|
+
case column
|
1412
|
+
when Array
|
1413
|
+
column.all? { |c| has_column?(klass, c.to_s) }
|
1167
1414
|
else
|
1168
|
-
|
1169
|
-
true
|
1170
|
-
else
|
1171
|
-
@missing = "#{klass} does not have a #{foreign_key} foreign key."
|
1172
|
-
false
|
1173
|
-
end
|
1415
|
+
column_names_for(klass).include?(column.to_s)
|
1174
1416
|
end
|
1175
1417
|
end
|
1176
1418
|
|
1419
|
+
def foreign_key_correct?
|
1420
|
+
option_verifier.correct_for_string?(
|
1421
|
+
:foreign_key,
|
1422
|
+
options[:foreign_key],
|
1423
|
+
)
|
1424
|
+
end
|
1425
|
+
|
1426
|
+
def foreign_key_failure_message(klass, foreign_key)
|
1427
|
+
"#{klass} does not have a #{foreign_key} foreign key."
|
1428
|
+
end
|
1429
|
+
|
1177
1430
|
def primary_key_correct?(klass)
|
1178
1431
|
if options.key?(:primary_key)
|
1179
|
-
if option_verifier.correct_for_string?(
|
1432
|
+
if option_verifier.correct_for_string?(
|
1433
|
+
:primary_key,
|
1434
|
+
options[:primary_key],
|
1435
|
+
)
|
1180
1436
|
true
|
1181
1437
|
else
|
1182
|
-
@missing = "#{klass} does not have a #{options[:primary_key]}
|
1438
|
+
@missing = "#{klass} does not have a #{options[:primary_key]}"\
|
1439
|
+
' primary key'
|
1183
1440
|
false
|
1184
1441
|
end
|
1185
1442
|
else
|
@@ -1187,19 +1444,27 @@ module Shoulda
|
|
1187
1444
|
end
|
1188
1445
|
end
|
1189
1446
|
|
1190
|
-
def
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1447
|
+
def actual_foreign_key
|
1448
|
+
return unless foreign_key_reflection
|
1449
|
+
|
1450
|
+
if foreign_key_reflection.options[:foreign_key]
|
1451
|
+
foreign_key_reflection.options[:foreign_key]
|
1452
|
+
elsif foreign_key_reflection.respond_to?(:foreign_key)
|
1453
|
+
foreign_key_reflection.foreign_key
|
1454
|
+
else
|
1455
|
+
foreign_key_reflection.primary_key_name
|
1197
1456
|
end
|
1198
1457
|
end
|
1199
1458
|
|
1200
1459
|
def foreign_key_reflection
|
1201
|
-
if
|
1202
|
-
|
1460
|
+
if (
|
1461
|
+
[:has_one, :has_many].include?(macro) &&
|
1462
|
+
reflection.options.include?(:inverse_of) &&
|
1463
|
+
reflection.options[:inverse_of] != false
|
1464
|
+
)
|
1465
|
+
associated_class.reflect_on_association(
|
1466
|
+
reflection.options[:inverse_of],
|
1467
|
+
)
|
1203
1468
|
else
|
1204
1469
|
reflection
|
1205
1470
|
end
|
@@ -1208,6 +1473,16 @@ module Shoulda
|
|
1208
1473
|
def submatchers_match?
|
1209
1474
|
failing_submatchers.empty?
|
1210
1475
|
end
|
1476
|
+
|
1477
|
+
def column_names_for(klass)
|
1478
|
+
klass.column_names
|
1479
|
+
rescue ::ActiveRecord::StatementInvalid
|
1480
|
+
[]
|
1481
|
+
end
|
1482
|
+
|
1483
|
+
def belongs_to_required_by_default?
|
1484
|
+
::ActiveRecord::Base.belongs_to_required_by_default
|
1485
|
+
end
|
1211
1486
|
end
|
1212
1487
|
end
|
1213
1488
|
end
|