thoughtbot / shoulda-matchers

Simple one-liner tests for common Rails functionality
https://matchers.shoulda.io
MIT License
3.51k stars 912 forks source link

wrong constant name dummy value on rails 7 #1575

Closed yanghoxom closed 8 months ago

yanghoxom commented 12 months ago

Behavior

I think shoulda matchers try to create tests with random value for a_type which should cause wrong constant name error I tried removing a_type from scope, everything works fine.

Gem

Ruby 3.1.3 Rails 7.0.4 shoulda-matchers (5.3.0)

Model

  belongs_to :a, polymorphic: true

  validates :label, presence: true,
                   length: { maximum: 200 },
                   uniqueness: { scope: [:a_id, :a_type, :parent_id] }

rspec ###

    it { should validate_uniqueness_of(:label).scoped_to([:a_id, :a_type, :parent_id]) }

Rspec result

Failure/Error: it { should validate_uniqueness_of(:label).scoped_to([:a_id, :a_type, :parent_id]) }

     NameError:
       wrong constant name dummy value

             Object.const_get(camel_cased_word)
                   ^^^^^^^^^^

Backtrace

"/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activesupport-7.0.4/lib/active_support/inflector/methods.rb:280:in `const_get'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activesupport-7.0.4/lib/active_support/inflector/methods.rb:280:in `constantize'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activesupport-7.0.4/lib/active_support/core_ext/string/inflections.rb:74:in `constantize'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activerecord-7.0.4/lib/active_record/inheritance.rb:207:in `polymorphic_class_for'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activerecord-7.0.4/lib/active_record/associations/belongs_to_polymorphic_association.rb:9:in `klass'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activerecord-7.0.4/lib/active_record/associations/association.rb:215:in `ensure_klass_exists!'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activerecord-7.0.4/lib/active_record/associations/singular_association.rb:8:in `reader'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activerecord-7.0.4/lib/active_record/associations/builder/association.rb:104:in `customizable'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activemodel-7.0.4/lib/active_model/validator.rb:150:in `block in validate'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activemodel-7.0.4/lib/active_model/validator.rb:149:in `each'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activemodel-7.0.4/lib/active_model/validator.rb:149:in `validate'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:423:in `block in make_lambda'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:199:in `block (2 levels) in halting'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:687:in `block (2 levels) in default_terminator'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:686:in `catch'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:686:in `block in default_terminator'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:200:in `block in halting'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:595:in `block in invoke_before'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:595:in `each'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:595:in `invoke_before'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:106:in `run_callbacks'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:929:in `_run_validate_callbacks'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activemodel-7.0.4/lib/active_model/validations.rb:406:in `run_validations!'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activemodel-7.0.4/lib/active_model/validations/callbacks.rb:117:in `block in run_validations!'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:107:in `run_callbacks'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activesupport-7.0.4/lib/active_support/callbacks.rb:929:in `_run_validation_callbacks'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activemodel-7.0.4/lib/active_model/validations/callbacks.rb:117:in `run_validations!'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activemodel-7.0.4/lib/active_model/validations.rb:337:in `valid?'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/activerecord-7.0.4/lib/active_record/validations.rb:68:in `valid?'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_model/validator.rb:96:in `perform_validation'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_model/validator.rb:89:in `validation_result'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_model/validator.rb:85:in `validation_error_messages'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_model/validator.rb:64:in `messages'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_model/validator.rb:25:in `has_messages?'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_model/validator.rb:55:in `messages_match?'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_model/validator.rb:21:in `call'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb:38:in `matches?'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb:42:in `does_not_match?'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb:28:in `each'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb:28:in `detect'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb:28:in `first_failing'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_model/allow_value_matcher.rb:536:in `public_send'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_model/allow_value_matcher.rb:536:in `run'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_model/allow_value_matcher.rb:395:in `matches?'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_model/validation_matcher.rb:179:in `run_allow_or_disallow_matcher'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_model/validation_matcher.rb:98:in `allows_value_of'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:760:in `block (2 levels) in matches_uniqueness_with_scopes?'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:788:in `setting_next_value_for'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:759:in `block in matches_uniqueness_with_scopes?'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:758:in `all?'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:758:in `matches_uniqueness_with_scopes?'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/shoulda-matchers-5.3.0/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:338:in `matches?'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-expectations-3.12.1/lib/rspec/expectations/handler.rb:51:in `block in handle_matcher'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-expectations-3.12.1/lib/rspec/expectations/handler.rb:27:in `with_matcher'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-expectations-3.12.1/lib/rspec/expectations/handler.rb:48:in `handle_matcher'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/memoized_helpers.rb:82:in `should'",
 "/home/hung/test_project/spec/models/a_spec.rb:16:in `block (3 levels) in <top (required)>'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example.rb:263:in `instance_exec'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example.rb:263:in `block in run'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example.rb:511:in `block in with_around_and_singleton_context_hooks'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example.rb:468:in `block in with_around_example_hooks'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/hooks.rb:486:in `block in run'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/hooks.rb:626:in `block in run_around_example_hooks_for'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example.rb:352:in `call'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-rails-6.0.1/lib/rspec/rails/adapters.rb:75:in `block (2 levels) in <module:MinitestLifecycleAdapter>'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example.rb:457:in `instance_exec'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example.rb:457:in `instance_exec'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/hooks.rb:390:in `execute_with'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/hooks.rb:628:in `block (2 levels) in run_around_example_hooks_for'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example.rb:352:in `call'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/webmock-3.19.1/lib/webmock/rspec.rb:39:in `block (2 levels) in <top (required)>'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example.rb:457:in `instance_exec'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example.rb:457:in `instance_exec'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/hooks.rb:390:in `execute_with'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/hooks.rb:628:in `block (2 levels) in run_around_example_hooks_for'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example.rb:352:in `call'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/hooks.rb:629:in `run_around_example_hooks_for'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/hooks.rb:486:in `run'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example.rb:468:in `with_around_example_hooks'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example.rb:511:in `with_around_and_singleton_context_hooks'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example.rb:259:in `run'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example_group.rb:646:in `block in run_examples'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example_group.rb:642:in `map'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example_group.rb:642:in `run_examples'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example_group.rb:607:in `run'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example_group.rb:608:in `block in run'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example_group.rb:608:in `map'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/example_group.rb:608:in `run'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/runner.rb:121:in `block (3 levels) in run_specs'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/runner.rb:121:in `map'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/runner.rb:121:in `block (2 levels) in run_specs'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/configuration.rb:2070:in `with_suite_hooks'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/runner.rb:116:in `block in run_specs'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/reporter.rb:74:in `report'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/runner.rb:115:in `run_specs'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/runner.rb:89:in `run'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/runner.rb:71:in `run'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/lib/rspec/core/runner.rb:45:in `invoke'",
 "/home/hung/.asdf/installs/ruby/3.1.3/lib/ruby/gems/3.1.0/gems/rspec-core-3.12.0/exe/rspec:4:in `<top (required)>'",
 "/home/hung/.asdf/installs/ruby/3.1.3/bin/rspec:25:in `load'",
 "/home/hung/.asdf/installs/ruby/3.1.3/bin/rspec:25:in `<main>'"
skalibog commented 11 months ago

@yanghoxom Look at this issue #1052. Last comments will help you. This issue not related to shoulda. It is related to ActiveRecord *_type reserved methods for STI as I remember.

vsppedro commented 8 months ago

Thank you, @skalibog, for finding that issue and adding here.

Hey, @yanghoxom, I'm planning to close this issue since it doesn't appear to be related to this project. However, if you believe the problem still lies within sholda-matchers, we can reopen it. Thanks for your understanding.

benbonnet commented 7 months ago

@skalibog the proposed workarounds does not really solves anything; or maybe i'm missing the point

Tried to disable sti on the given model, used described_class.new and factory to instantiate the subject; the very same error remains

vsppedro commented 7 months ago

Hey, @benbonnet, thanks for the report!

Would you mind replicating the issue in a minimal Rails application? It would greatly assist us in troubleshooting.

Thanks again.

benbonnet commented 7 months ago

my bad reviewing the factory and correctly defining it before the assertion made it all pass