New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deprecation warnings when using different requires for spec_helper #371
Comments
You should require spec_helper the same way, and I'd recommend the short version. This is not only to silence this deprecation, but spec_helper is typically used to load other resources and reloading it has lead to some confusing bugs in the past. I'm going to leave this open as I think this warrants some documentation. |
Thanks for keeping this open! Just trapped into it. Took me quite a while to find this page. |
Short version |
You get the same warning if you have a spec file in Interestingly, if you rename the |
@steveringo - definitely hadn't considered this scenario when we introduced this in rspec/rspec-core@fc70cee. This was there to solve a problem in ruby 1.9: when a module with a method that calls super is included twice in the same runtime object, you get an infinite loop. I think we'll need to find a different way to address that. /cc @myronmarston |
Could that be solved by just detecting that RSpec.configure was called twice? (I'm not sure I fully understand yet... :) |
I think I haven't run into this because I keep two spec directories: spec and spec_no_rails |
Problem is worked around by creating a simple controller spec. Because |
It may be an edge case now, but relying on spec_helper-using specs coming first by coincidence seems a bit fragile to me. :) (I'm also on a personal crusade to get people to stop using spec_helper in most specs. ;) |
We need to support n calls to RSpec.configure, as it happens in extensions. We also need to fix this particular issue - you should be able to require or not require any spec_helper you want from wherever (as long as you don't load the same one twice). I may be confusing issues. I thought this was related to rspec/rspec-expectations@80e5300, but I'm not certain and I'm having trouble finding any other potential motivation for rspec/rspec-core@fc70cee. Let's wait for @myronmarston to weigh in. |
There's a bit of a history behind this change...let me see if I can summarize it. Ruby 1.9 has an obscure bug that triggers infinite recursion (and a
This gist demonstrates the issue. This is only a bug on 1.9; 1.8 does not have this issue. In addition, it is only triggered if the module is included in the superclass after it has already been included in the subclass. I'm guessing that ruby 1.9 uses a linked list to keep track of an object's class hierarchy, and this situation creates a circularly linked list. In RSpec, we received multiple reports about users getting
David and I (and some others on the rspec core team) discussed a few potential solutions for this issue, and decided that the best fix was to change when Correct me if I'm wrong, David, but I believe that RSpec configuration was always intended to be done before examples are defined--it just happened to always work fine before now. Looking to the future, this is a very hard feature to support, because the You can still call For those of you who are dealing with this warning--is there a way to reorganize your RSpec config files so that they always get loaded first regardless of which specs (or subset of your specs) you are running? I'm certainly open to suggestions of better ways to balance these issues. |
It sounds like you could just tell people "don't manually include RSpec::Matchers in an example group; it's done for you", even emitting a warning, but I imagine there's more to it than that. :) We could reorganize our spec directories to work around this by having a file that sorts before all of the others and loads spec_helper. But that's a pretty terrible hack. I think that load order independence should be considered part of RSpec's contract with the user. Calling RSpec.configure is optional, so some spec files will do it and some won't. And the load order is (or, IMO, should be) irrelevant to the user, so RSpec really can't count on configure being called before or after group definition. |
I think telling people stuff is not a reliable way to go. There needs to be something that tells you what's up at runtime, other than "stack level too deep".
I also think constraining directory/file structure like this is an unreasonable burden to put on users. Here are a couple of alternatives:
# in spec/support/global_configuration.rb
RSpec.configure do |c|
c.expect_with :stdlib
end
# in spec/spec_helper.rb
require 'support/global_configuration'
# in spec/spec_helper_no_rails.rb
require 'support/global_configuration'
# in a spec that needs rails
require 'spec_helper'
# in a spec that does not need rails
require 'spec_helper_no_rails' Personally, I like the first alternative :) Thoughts? |
I actually tried various flavors of fixes to RSpec::Matchers to work around this, but they were hacks, and in the end didn't work like I thought they would. I don't think the specific fix you suggest would work, anyway--if RSpec::Matchers is included in a class after it has been included in one its ancestors, it's not an issue. It's the opposite case that's the problem: when RSpec::Matchers is included in a class after it has been included in one of its subclasses. If ruby provided a Instead, how does this sound?
|
I just realized that I mistated something above:
This should read: "but is included in A after it was already included in B". |
That's what I was proposing (except as an error, not a warning) as option 2. I'm good with this option. |
I think I misread what you wrote this morning (I had just gotten up...), but yeah, I can see that now :). Would you prefer an error or a warning? |
I think it should be an error. If it's just a warning, then the specs will still run and results might be confusing. |
Sounds good. I'm really swamped at work right now (the project I've been working on for 4 months is going into production in the next week), so I may not get around to this for a while. Someone else can feel free, or I'll try to get to it when things have settled down at work a bit (and feel free to ping me to remind me if I haven't addressed this in a couple weeks). |
I just pushed a fix for this to RSpec core. |
I'm having trouble working around this warning. I've got a spec suite that runs cleanly without emitting the warning if run with "rspec spec". But the warning gets emitted when invoked via "rake spec". I think it's clear that Rake is somehow loading the spec_helper twice, but I can't figure out why/how. This behavior can be observed in the twilio-rb gem ( https://github.com/jtrupiano/twilio-rb/tree/rspec ). When I drop a debugger into spec_helper there I get these two stacktraces before the suite runs:
and
It looks like the second load of spec_helper is happening within rspec-core itself. |
After upgrading a Rails project to 2.6.0 I get the following warning when I run my spec suite with rake spec:
The issue seems to be caused by different ways of requiring spec_helper. One spec has:
Another has:
Each spec will run without warning when run individually, but when run together the warning appears. After changing the requires to both use the expanded form the deprecation notice disappears.
Not sure if this is to be considered a bug or just me doing things the wrong way.
The text was updated successfully, but these errors were encountered: