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
@@ -0,0 +1,106 @@
|
|
1
|
+
module Shoulda
|
2
|
+
module Matchers
|
3
|
+
module ActiveRecord
|
4
|
+
# The `have_implicit_order_column` matcher tests that the model has `implicit_order_column`
|
5
|
+
# assigned to one of the table columns. (Rails 6+ only)
|
6
|
+
#
|
7
|
+
# class Product < ApplicationRecord
|
8
|
+
# self.implicit_order_column = :created_at
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# # RSpec
|
12
|
+
# RSpec.describe Product, type: :model do
|
13
|
+
# it { should have_implicit_order_column(:created_at) }
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# # Minitest (Shoulda)
|
17
|
+
# class ProductTest < ActiveSupport::TestCase
|
18
|
+
# should have_implicit_order_column(:created_at)
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# @return [HaveImplicitOrderColumnMatcher]
|
22
|
+
#
|
23
|
+
if RailsShim.active_record_gte_6?
|
24
|
+
def have_implicit_order_column(column_name)
|
25
|
+
HaveImplicitOrderColumnMatcher.new(column_name)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# @private
|
30
|
+
class HaveImplicitOrderColumnMatcher
|
31
|
+
attr_reader :failure_message
|
32
|
+
|
33
|
+
def initialize(column_name)
|
34
|
+
@column_name = column_name
|
35
|
+
end
|
36
|
+
|
37
|
+
def matches?(subject)
|
38
|
+
@subject = subject
|
39
|
+
check_column_exists!
|
40
|
+
check_implicit_order_column_matches!
|
41
|
+
true
|
42
|
+
rescue SecondaryCheckFailedError => e
|
43
|
+
@failure_message = Shoulda::Matchers.word_wrap(
|
44
|
+
"Expected #{model.name} to #{expectation}, " +
|
45
|
+
"but that could not be proved: #{e.message}.",
|
46
|
+
)
|
47
|
+
false
|
48
|
+
rescue PrimaryCheckFailedError => e
|
49
|
+
@failure_message = Shoulda::Matchers.word_wrap(
|
50
|
+
"Expected #{model.name} to #{expectation}, but #{e.message}.",
|
51
|
+
)
|
52
|
+
false
|
53
|
+
end
|
54
|
+
|
55
|
+
def failure_message_when_negated
|
56
|
+
Shoulda::Matchers.word_wrap(
|
57
|
+
"Expected #{model.name} not to #{expectation}, but it did.",
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
def description
|
62
|
+
expectation
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
attr_reader :column_name, :subject
|
68
|
+
|
69
|
+
def check_column_exists!
|
70
|
+
matcher = HaveDbColumnMatcher.new(column_name)
|
71
|
+
|
72
|
+
if !matcher.matches?(@subject)
|
73
|
+
raise SecondaryCheckFailedError.new(
|
74
|
+
"The :#{model.table_name} table does not have a " +
|
75
|
+
":#{column_name} column",
|
76
|
+
)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def check_implicit_order_column_matches!
|
81
|
+
if model.implicit_order_column.to_s != column_name.to_s
|
82
|
+
message =
|
83
|
+
if model.implicit_order_column.nil?
|
84
|
+
'implicit_order_column is not set'
|
85
|
+
else
|
86
|
+
"it is :#{model.implicit_order_column}"
|
87
|
+
end
|
88
|
+
|
89
|
+
raise PrimaryCheckFailedError.new(message)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def model
|
94
|
+
subject.class
|
95
|
+
end
|
96
|
+
|
97
|
+
def expectation
|
98
|
+
"have an implicit_order_column of :#{column_name}"
|
99
|
+
end
|
100
|
+
|
101
|
+
class SecondaryCheckFailedError < StandardError; end
|
102
|
+
class PrimaryCheckFailedError < StandardError; end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -9,7 +9,7 @@ module Shoulda
|
|
9
9
|
# end
|
10
10
|
#
|
11
11
|
# # RSpec
|
12
|
-
# describe User do
|
12
|
+
# RSpec.describe User, type: :model do
|
13
13
|
# it { should have_readonly_attribute(:password) }
|
14
14
|
# end
|
15
15
|
#
|
@@ -35,17 +35,19 @@ module Shoulda
|
|
35
35
|
def matches?(subject)
|
36
36
|
@subject = subject
|
37
37
|
if readonly_attributes.include?(@attribute)
|
38
|
-
@failure_message_when_negated = "Did not expect #{@attribute}
|
38
|
+
@failure_message_when_negated = "Did not expect #{@attribute}"\
|
39
|
+
' to be read-only'
|
39
40
|
true
|
40
41
|
else
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
"#{
|
47
|
-
|
48
|
-
|
42
|
+
@failure_message =
|
43
|
+
if readonly_attributes.empty?
|
44
|
+
"#{class_name} attribute #{@attribute} " <<
|
45
|
+
'is not read-only'
|
46
|
+
else
|
47
|
+
"#{class_name} is making " <<
|
48
|
+
"#{readonly_attributes.to_a.to_sentence} " <<
|
49
|
+
"read-only, but not #{@attribute}."
|
50
|
+
end
|
49
51
|
false
|
50
52
|
end
|
51
53
|
end
|
@@ -57,7 +59,7 @@ module Shoulda
|
|
57
59
|
private
|
58
60
|
|
59
61
|
def readonly_attributes
|
60
|
-
@
|
62
|
+
@_readonly_attributes ||= (@subject.class.readonly_attributes || [])
|
61
63
|
end
|
62
64
|
|
63
65
|
def class_name
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Shoulda
|
2
|
+
module Matchers
|
3
|
+
module ActiveRecord
|
4
|
+
# The `have_rich_text` matcher tests usage of the
|
5
|
+
# `has_rich_text` macro.
|
6
|
+
#
|
7
|
+
# #### Example
|
8
|
+
#
|
9
|
+
# class Post < ActiveRecord
|
10
|
+
# has_rich_text :content
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# # RSpec
|
14
|
+
# RSpec.describe Post, type: :model do
|
15
|
+
# it { should have_rich_text(:content) }
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# # Minitest (Shoulda)
|
19
|
+
# class PostTest < ActiveSupport::TestCase
|
20
|
+
# should have_rich_text(:content)
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# @return [HaveRichTextMatcher]
|
24
|
+
#
|
25
|
+
def have_rich_text(rich_text_attribute)
|
26
|
+
HaveRichTextMatcher.new(rich_text_attribute)
|
27
|
+
end
|
28
|
+
|
29
|
+
# @private
|
30
|
+
class HaveRichTextMatcher
|
31
|
+
def initialize(rich_text_attribute)
|
32
|
+
@rich_text_attribute = rich_text_attribute
|
33
|
+
end
|
34
|
+
|
35
|
+
def description
|
36
|
+
"have configured :#{rich_text_attribute} as a "\
|
37
|
+
'ActionText::RichText association'
|
38
|
+
end
|
39
|
+
|
40
|
+
def failure_message
|
41
|
+
"Expected #{subject.class} to #{error_description}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def failure_message_when_negated
|
45
|
+
"Did not expect #{subject.class} to have ActionText::RichText"\
|
46
|
+
" :#{rich_text_attribute}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def matches?(subject)
|
50
|
+
@subject = subject
|
51
|
+
@error = run_checks
|
52
|
+
@error.nil?
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
attr_reader :error, :rich_text_attribute, :subject
|
58
|
+
|
59
|
+
def run_checks
|
60
|
+
if !has_attribute?
|
61
|
+
":#{rich_text_attribute} does not exist"
|
62
|
+
elsif !has_expected_action_text?
|
63
|
+
:default
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def has_attribute?
|
68
|
+
@subject.respond_to?(rich_text_attribute.to_s)
|
69
|
+
end
|
70
|
+
|
71
|
+
def has_expected_action_text?
|
72
|
+
defined?(ActionText::RichText) &&
|
73
|
+
@subject.send(rich_text_attribute).
|
74
|
+
instance_of?(ActionText::RichText)
|
75
|
+
end
|
76
|
+
|
77
|
+
def error_description
|
78
|
+
error == :default ? description : "#{description} but #{error}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module Shoulda
|
2
|
+
module Matchers
|
3
|
+
module ActiveRecord
|
4
|
+
# The `have_secure_token` matcher tests usage of the
|
5
|
+
# `has_secure_token` macro.
|
6
|
+
#
|
7
|
+
# class User < ActiveRecord
|
8
|
+
# has_secure_token
|
9
|
+
# has_secure_token :auth_token
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# # RSpec
|
13
|
+
# RSpec.describe User, type: :model do
|
14
|
+
# it { should have_secure_token }
|
15
|
+
# it { should have_secure_token(:auth_token) }
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# # Minitest (Shoulda)
|
19
|
+
# class UserTest < ActiveSupport::TestCase
|
20
|
+
# should have_secure_token
|
21
|
+
# should have_secure_token(:auth_token)
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# #### Qualifiers
|
25
|
+
#
|
26
|
+
# ##### ignoring_check_for_db_index
|
27
|
+
#
|
28
|
+
# By default, this matcher tests that an index is defined on your token
|
29
|
+
# column. Use `ignoring_check_for_db_index` if this is not the case.
|
30
|
+
#
|
31
|
+
# class User < ActiveRecord
|
32
|
+
# has_secure_token :auth_token
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# # RSpec
|
36
|
+
# RSpec.describe User, type: :model do
|
37
|
+
# it { should have_secure_token(:auth_token).ignoring_check_for_db_index }
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# # Minitest (Shoulda)
|
41
|
+
# class UserTest < ActiveSupport::TestCase
|
42
|
+
# should have_secure_token(:auth_token).ignoring_check_for_db_index
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# @return [HaveSecureToken]
|
46
|
+
#
|
47
|
+
def have_secure_token(token_attribute = :token)
|
48
|
+
HaveSecureTokenMatcher.new(token_attribute)
|
49
|
+
end
|
50
|
+
|
51
|
+
# @private
|
52
|
+
class HaveSecureTokenMatcher
|
53
|
+
attr_reader :token_attribute
|
54
|
+
|
55
|
+
def initialize(token_attribute)
|
56
|
+
@token_attribute = token_attribute
|
57
|
+
@options = { ignore_check_for_db_index: false }
|
58
|
+
end
|
59
|
+
|
60
|
+
def description
|
61
|
+
"have :#{token_attribute} as a secure token"
|
62
|
+
end
|
63
|
+
|
64
|
+
def failure_message
|
65
|
+
return if !@errors
|
66
|
+
|
67
|
+
"Expected #{@subject.class} to #{description} but the following " \
|
68
|
+
"errors were found: #{@errors.join(', ')}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def failure_message_when_negated
|
72
|
+
return if !@errors
|
73
|
+
|
74
|
+
"Did not expect #{@subject.class} to have secure token " \
|
75
|
+
":#{token_attribute}"
|
76
|
+
end
|
77
|
+
|
78
|
+
def matches?(subject)
|
79
|
+
@subject = subject
|
80
|
+
@errors = run_checks
|
81
|
+
@errors.empty?
|
82
|
+
end
|
83
|
+
|
84
|
+
def ignoring_check_for_db_index
|
85
|
+
@options[:ignore_check_for_db_index] = true
|
86
|
+
self
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def run_checks
|
92
|
+
@errors = []
|
93
|
+
if !has_expected_instance_methods?
|
94
|
+
@errors << 'missing expected class and instance methods'
|
95
|
+
end
|
96
|
+
if !has_expected_db_column?
|
97
|
+
@errors << "missing correct column #{token_attribute}:string"
|
98
|
+
end
|
99
|
+
if !@options[:ignore_check_for_db_index] && !has_expected_db_index?
|
100
|
+
@errors << "missing unique index for #{table_and_column}"
|
101
|
+
end
|
102
|
+
@errors
|
103
|
+
end
|
104
|
+
|
105
|
+
def has_expected_instance_methods?
|
106
|
+
@subject.respond_to?(token_attribute.to_s) &&
|
107
|
+
@subject.respond_to?("#{token_attribute}=") &&
|
108
|
+
@subject.respond_to?("regenerate_#{token_attribute}") &&
|
109
|
+
@subject.class.respond_to?(:generate_unique_secure_token)
|
110
|
+
end
|
111
|
+
|
112
|
+
def has_expected_db_column?
|
113
|
+
matcher = HaveDbColumnMatcher.new(token_attribute).of_type(:string)
|
114
|
+
matcher.matches?(@subject)
|
115
|
+
end
|
116
|
+
|
117
|
+
def has_expected_db_index?
|
118
|
+
matcher = HaveDbIndexMatcher.new(token_attribute).unique(true)
|
119
|
+
matcher.matches?(@subject)
|
120
|
+
end
|
121
|
+
|
122
|
+
def table_and_column
|
123
|
+
"#{table_name}.#{token_attribute}"
|
124
|
+
end
|
125
|
+
|
126
|
+
def table_name
|
127
|
+
@subject.class.table_name
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -8,7 +8,7 @@ module Shoulda
|
|
8
8
|
# end
|
9
9
|
#
|
10
10
|
# # RSpec
|
11
|
-
# describe Product do
|
11
|
+
# RSpec.describe Product, type: :model do
|
12
12
|
# it { should serialize(:customizations) }
|
13
13
|
# end
|
14
14
|
#
|
@@ -38,7 +38,7 @@ module Shoulda
|
|
38
38
|
# end
|
39
39
|
#
|
40
40
|
# # RSpec
|
41
|
-
# describe Product do
|
41
|
+
# RSpec.describe Product, type: :model do
|
42
42
|
# it do
|
43
43
|
# should serialize(:specifications).
|
44
44
|
# as(ProductSpecsSerializer)
|
@@ -70,7 +70,7 @@ module Shoulda
|
|
70
70
|
# end
|
71
71
|
#
|
72
72
|
# # RSpec
|
73
|
-
# describe Product do
|
73
|
+
# RSpec.describe Product, type: :model do
|
74
74
|
# it do
|
75
75
|
# should serialize(:options).
|
76
76
|
# as_instance_of(ProductOptionsSerializer)
|
@@ -121,7 +121,9 @@ module Shoulda
|
|
121
121
|
|
122
122
|
def description
|
123
123
|
description = "serialize :#{@name}"
|
124
|
-
|
124
|
+
if @options.key?(:type)
|
125
|
+
description += " class_name => #{@options[:type]}"
|
126
|
+
end
|
125
127
|
description
|
126
128
|
end
|
127
129
|
|
@@ -141,13 +143,12 @@ module Shoulda
|
|
141
143
|
klass = serialization_coder
|
142
144
|
if klass == @options[:type]
|
143
145
|
true
|
146
|
+
elsif klass.respond_to?(:object_class) &&
|
147
|
+
klass.object_class == @options[:type]
|
148
|
+
true
|
144
149
|
else
|
145
|
-
|
146
|
-
|
147
|
-
else
|
148
|
-
@missing = ":#{@name} should be a type of #{@options[:type]}"
|
149
|
-
false
|
150
|
-
end
|
150
|
+
@missing = ":#{@name} should be a type of #{@options[:type]}"
|
151
|
+
false
|
151
152
|
end
|
152
153
|
else
|
153
154
|
true
|
@@ -176,22 +177,21 @@ module Shoulda
|
|
176
177
|
end
|
177
178
|
|
178
179
|
def expectation
|
179
|
-
expectation = "#{model_class.name} to serialize the attribute called
|
180
|
+
expectation = "#{model_class.name} to serialize the attribute called"\
|
181
|
+
" :#{@name}"
|
180
182
|
expectation += " with a type of #{@options[:type]}" if @options[:type]
|
181
|
-
|
183
|
+
if @options[:instance_type]
|
184
|
+
expectation += " with an instance of #{@options[:instance_type]}"
|
185
|
+
end
|
182
186
|
expectation
|
183
187
|
end
|
184
188
|
|
185
189
|
def attribute_is_serialized?
|
186
|
-
|
190
|
+
!!serialization_coder
|
187
191
|
end
|
188
192
|
|
189
193
|
def serialization_coder
|
190
|
-
|
191
|
-
end
|
192
|
-
|
193
|
-
def serialized_attributes
|
194
|
-
Shoulda::Matchers::RailsShim.serialized_attributes_for(model)
|
194
|
+
RailsShim.attribute_serialization_coder_for(model, @name)
|
195
195
|
end
|
196
196
|
|
197
197
|
def model
|