Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Global before :all hooks with specified :type are not run with 2.14.0 #825

Closed
jarmo opened this Issue · 5 comments

2 participants

@jarmo

Specifying global before :all hooks for specified :type does not work with rspec-rails version 2.14.0.

Here's how to reproduce it:

1) generate an empty project

> rails -v
Rails 4.0.0

> rails new rspec-rails-broken
      create
      create  README.rdoc
      create  Rakefile
      create  config.ru
      ...

2) add rspec-rails into Gemfile:

# Gemfile

group :development, :test do
  gem 'rspec-rails', '2.14.0'
end

3) setup it:

> bundle install
> rails g rspec:install

4) add a before hook with specific type into spec_helper:

RSpec.configure do |config|
  config.before :all, type: :request do
    raise "should fail!"
  end
end

5) create a request spec:

# spec/requests/failing_spec.rb

require "spec_helper"

describe "always failing" do
  it "should fail" do
  end
end

6) execute the spec and hope for failure:

> bundle exec rake db:migrate spec
ruby -S rspec ./spec/requests/failing_spec.rb
.

Finished in 0.002 seconds
1 example, 0 failures

7) the spec did not fail! This is because that before :all got not executed. The same happens when using different type - controller for example for spec/controllers/*_spec.rb.

It will work as inspected if using before :each instead or if downgrading to 2.13.2

@JonRowe
Owner

Trying to debug this, what happens if you put type: :request into your describe e.g.:

describe "always failing", type: :request do
  it "should fail" do
  end
end
@jarmo

Forgot to mention, that when nesting with context, then it seems to work as expected:

# spec/requests/working_spec.rb

describe "working" do
  context "yup, working" do
    it "will fail, as expected because before all hook will raise" do
    end
  end
end

Also, when removing type: :request filter from that global hook and checking the type, then it is :request for all the example groups in requests directory as expected:

# spec_helper.rb

before :all do
  p self.class.metadata[:type]
end
@JonRowe
Owner

Yeah but there could be an ordering issue between rspec-rails automagically categorising specs and when your config is loaded.

@jarmo

It might be that the problem is in fact in one of the rspec-rails rspec* dependencies.

@JonRowe
Owner

In case anyone else gets time to work on this before I do, the problem here seems to be that the metadata is not being set on the top level ExampleGroup only the child Examples and ExampleGroups causing before(:all) to not trigger for the top level group.

@myronmarston myronmarston referenced this issue from a commit
@myronmarston myronmarston Fix spec type inferrence.
- In #970 we added `infer_spec_type_from_file_location!` but forgot
  to remove the code in `lib/rspec/rails/configuration.rb` that
  made it always infer - so the opt-in API was there but it
  was always enabled. Here I've made it truly opt-in.
- The logic of `infer_spec_type_from_file_location!` also setup
  the helper module inclusion via explicit `:type` metadata but
  was only intended to setup the implicit mapping of spec file
  location to type.  Here I've made the module inclusion via
  `:type` always work w/o an explicit config option needed to
  enable it.
- We used to mutate the `:type` metadata on inclusion of the helper
  module, but this caused bugs such as #825. The problem is that
  rspec-core uses a raw hash for the metadata and doesn't re-apply
  filtering/inclusion logic when the metadata hash is mutated.
  Instead, we use a new explicit `define_derived_metadata` API.

Fixes #825 and closes #829.
e135076
@myronmarston myronmarston referenced this issue from a commit
@myronmarston myronmarston Fix spec type inference.
- In #970 we added `infer_spec_type_from_file_location!` but forgot
  to remove the code in `lib/rspec/rails/configuration.rb` that
  made it always infer - so the opt-in API was there but it
  was always enabled. Here I've made it truly opt-in.
- The logic of `infer_spec_type_from_file_location!` also setup
  the helper module inclusion via explicit `:type` metadata but
  was only intended to setup the implicit mapping of spec file
  location to type.  Here I've made the module inclusion via
  `:type` always work w/o an explicit config option needed to
  enable it.
- We used to mutate the `:type` metadata on inclusion of the helper
  module, but this caused bugs such as #825. The problem is that
  rspec-core uses a raw hash for the metadata and doesn't re-apply
  filtering/inclusion logic when the metadata hash is mutated.
  Instead, we use a new explicit `define_derived_metadata` API.

Fixes #825 and closes #829.
0387ff2
@myronmarston myronmarston referenced this issue from a commit
@myronmarston myronmarston Stop mutating metadata.
There's no need to anymore, and it created some surprising
bugs (such as #825: `before(:all)` hooks would not properly
be applied because they were registered before the modules
were included).
7971bef
@myronmarston myronmarston referenced this issue in rspec/rspec-core
Merged

Define derived metadata. #1496

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.