Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

stub_const("::Name", with_this) does not work #200

Closed
coreyhaines opened this Issue · 16 comments

5 participants

@coreyhaines

Gives NameError
NameError:
wrong constant name

Swapping to take out the :: seems to work. However, this was unexpected, since I'm referencing the constant that way.

@alindeman
Collaborator

Could we simply run .sub(/\A::/, "") over the first argument and get the correct behavior since the constant name must be fully-qualified?

@myronmarston myronmarston closed this issue from a commit
@myronmarston myronmarston Fix stub_const/hide_const to work properly with a const like "::Foo".
It didn't work properly with names containing leading '::' before.

Fixes #200.
17daf44
@myronmarston
Owner

@alindeman -- yep, that's the exact fix I used :).

@coreyhaines -- it should work for you now. I did want to follow up on one of your tweets, though:

@myronmarston yeah, just using stub_const("Coderetreat", …) worked. Would prefer :: syntax, since I will have another Coderetreat class

Not sure if I'm misreading you or not (twitter-forced terseness makes misunderstanding easy) but your comment suggests you might be thinking that stub_const considers the constant scoping at the point of call (at least, that's the reason I prefix a const name with ::--to prevent it from considering the current constant scoping, since that's how normal constant lookup works). I wanted to clarify that it does not. The name must always be fully qualified. So even if your'e in a scope where a raw Coderetreat constant reference would resolve to a nested constant, stub_const("Coderetreat", blah) will look for a top-level constant called Coderetreat. We tried to document this well but we're certainly open for suggestions for how to document it better.

@coreyhaines

Thanks, guys,

I'll take a look at the constant scoping, as well. I'm hoping that it shouldn't matter.

I do rely on the scoping in my code to pick up the correct constant, but I don't think it should be a huge problem, as I rarely, if ever, use the same constant name from two different scopes in the same method. That seems like it would drive one insane. :)

If I notice anything else, I'll let you guys know.

Thanks.

@richardkmichael

I see this 'wrong constant' error message with these versions of RSpec:

$ gem list | grep rspec
guard-rspec (2.4.0)
rspec (2.12.0)
rspec-core (2.12.2)
rspec-expectations (2.12.1)
rspec-mocks (2.12.1)

$ gem outdated | grep rspec
$
$ bundle exec guard
# .. snip ..
  1) CarrierWave::Storage::ActiveRecord::StorageProvider#store!(file) with ::Rails sets the URL property on the returned file
     Failure/Error: stub_const('::Rails', 'Rails')
     NameError:
       wrong constant name 
@myronmarston

@richardkmichael -- what does this display?

$ bundle show rspec-mocks

I ask because depending on how you're using bundler, gems may be installed into a local cache -- so you could potentially be using rspec-mocks 2.12.0 (which had this bug) even though gem list indicates you have rspec-mocks 2.12.1 installed in your system gems.

Assuming that's not the issue, can you provide the full backtrace? Also, if there's anyway you can provide an executable example that triggers this error, that would be helpful, too.

@richardkmichael
$ bundle show rspec-mocks
/Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1

Can I somehow ask RSpec to give me a full backtrace instead of stopping at my code? Or, I can probably insert Pry somewhere and do show-stack?

@dchelimsky
Owner

@richardkmichael if you type rspec help in a shell you'll see all of the command line options, including --backtrace, which gives you a full backtrace e.g. rspec --backtrace.

@richardkmichael

@dchelimsky Thank you. (Guard has the amusingly named wtf? method, though it is not helpful in this case.)

$ rspec --backtrace

Failures:

  1) CarrierWave::Storage::ActiveRecord::StorageProvider#store!(file) with ::Rails sets the URL property on the returned file
     Failure/Error: stub_const('::Rails', 'Rails')
     NameError:
       wrong constant name 
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/mutate_const.rb:47:in `const_defined?'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/mutate_const.rb:47:in `const_defined_on?'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/mutate_const.rb:314:in `block in mutate'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/mutate_const.rb:313:in `each'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/mutate_const.rb:313:in `inject'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/mutate_const.rb:313:in `mutate'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/mutate_const.rb:347:in `mutate'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/mutate_const.rb:173:in `stub'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-mocks-2.12.1/lib/rspec/mocks/example_methods.rb:91:in `stub_const'
     # ./spec/lib/carrierwave-activerecord/storage/storage_provider_spec.rb:58:in `block (2 levels) in <module:ActiveRecord>'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/let.rb:33:in `instance_eval'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/let.rb:33:in `block (2 levels) in let'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/let.rb:33:in `fetch'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/let.rb:33:in `block in let'
     # ./spec/lib/carrierwave-activerecord/storage/storage_provider_spec.rb:92:in `block (4 levels) in <module:ActiveRecord>'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example.rb:114:in `instance_eval'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example.rb:114:in `block in run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example.rb:254:in `with_around_each_hooks'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example.rb:111:in `run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:388:in `block in run_examples'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:384:in `map'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:384:in `run_examples'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:369:in `run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `block in run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `map'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `block in run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `map'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/command_line.rb:28:in `block (2 levels) in run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/command_line.rb:28:in `map'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/command_line.rb:28:in `block in run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/reporter.rb:34:in `report'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/command_line.rb:25:in `run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/runner.rb:80:in `run'
     # /Users/user/.rvm/gems/ruby-1.9.3-p327@carrierwave-activerecord/gems/rspec-core-2.12.2/lib/rspec/core/runner.rb:17:in `block in autorun'
@myronmarston

Thanks! That backtrace suggests that this error is happening in the specs of carrierwave-activerecord...is that the case? If so, can you give us some repro steps? Would be nice to be able to clone your repo, checkout a particular branch, bundle install and run a particular spec file to trigger the error.

@richardkmichael

I was just about to add the comment that it's from this spec: https://github.com/richardkmichael/carrierwave-activerecord/blob/master/spec/lib/carrierwave-activerecord/storage/storage_provider_spec.rb#L58

Except with stub_const("::Rails"), of course.

My apologies if it's horrible RSpec, I've perhaps done something I should not. :-)

I ran $ rspec --backtrace spec/lib/carrierwave-activerecord/storage/storage_provider_spec.rb.

I could work out a minimal case, of course.

@alindeman
Collaborator

Hmm, did you mean to stub the constant as a String? This effectively means Rails = "Rails"

@richardkmichael

Yes. It doesn't matter what it is, I handle the next, and only, message it receives afterward with stub_chain.

@myronmarston

I tried to repro the error in your project, but I can't bundle install:

The path `/Users/rmichael/Documents/Personal/Source/carrierwave` does not exist.

This is due to the hard-coded path in your Gemfile. Can you push a branch that corrects this? If you need a particular git revision, you can use the :ref option when declaring the gem in your Gemfile and give it a SHA.

@richardkmichael

Oops, sorry about that - I know it's broken for collaboration. I've been working alone and haven't cleaned it up for "release" yet, and forgot - despite asking about bundler config on their mailing list just today. :-/

I've pushed a repro branch with stub_const("::Rails"), working bundle install with a Gemfile.lock, here: https://github.com/richardkmichael/carrierwave-activerecord/tree/rspec-repro

Then: rspec --backtrace spec/lib/carrierwave-activerecord/storage/storage_provider_spec.rb

@myronmarston myronmarston referenced this issue from a commit
@myronmarston myronmarston Handle `stub_const("::SomeUndefinedConst")`.
I thought I fixed the problem in 17daf44,
but I missed this edge case.  That only fixed `stub_const("::SomeDefinedConst").

Fixes #200.
1e3f431
@myronmarston

@richardkmichael -- I just released rspec-mocks 2.12.2 with a fix for this issue (and a few other issues). If you upgrade, it should fix your issue. Thanks for reporting it!

@richardkmichael

@myronmarston Upgraded and fixed. No problem; thank you for fixing it so quickly!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.