Skip to content

Commit 7cb796d

Browse files
author
Sam Phippen
committed
Warn if a fixture method is called from a before(:context) block.
Fixes #1442. The basic approach here is to capture the addition of the fixture methods to the example group instance and then monkeypatch them. The monkeypatch checks to see if we're currently in a before(:context) hook and if we are then it prints a warning and doesn't invoke the method. The warning here is a little sparse at the moment, and I'd like to make it more clear. One thing that's a little gross about this implementation is that it uses the inspect string of the example group to determine if we're in a before(:context) hook. As far as I can tell there isn't a better way to make that determination, but maybe someone's got a clever trick.
1 parent 05a1d7f commit 7cb796d

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

example_app_generator/generate_stuff.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ def setup_tasks
1414

1515
def final_tasks
1616
copy_file 'spec/verify_active_record_spec.rb'
17+
copy_file 'spec/verify_fixture_warning_spec.rb'
1718
run('bin/rake db:migrate')
1819
if ::Rails::VERSION::STRING.to_f < 4.1
1920
run('bin/rake db:migrate RAILS_ENV=test')
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
require 'rails_helper'
2+
3+
RSpec.describe "Fixture warnings" do
4+
def generate_fixture_example_group(hook_type)
5+
RSpec.describe do
6+
include RSpec::Rails::RailsExampleGroup
7+
fixtures :things
8+
9+
before(hook_type) do
10+
things :a
11+
end
12+
13+
it "" do
14+
15+
end
16+
end
17+
end
18+
19+
it "Warns when a fixture call is made in a before :context call" do
20+
expect(RSpec).to receive(:warn_with).with(match(/Calling fixture method in before :context/))
21+
22+
generate_fixture_example_group(:context).run
23+
end
24+
25+
it "Does not warn when a fixture call is made in a before :each call" do
26+
expect(RSpec).not_to receive(:warn_with)
27+
28+
generate_fixture_example_group(:each).run
29+
end
30+
31+
end
32+
33+
RSpec.describe "Global fixture warnings" do
34+
def generate_fixture_example_group(hook_type)
35+
RSpec.describe do
36+
include RSpec::Rails::RailsExampleGroup
37+
38+
before(hook_type) do
39+
things :a
40+
end
41+
42+
it "" do
43+
44+
end
45+
end
46+
end
47+
around do |ex|
48+
RSpec.configuration.global_fixtures = [:things]
49+
ex.call
50+
RSpec.configuration.global_fixtures = []
51+
end
52+
53+
it "warns when a global fixture call is made in a before :context call" do
54+
expect(RSpec).to receive(:warn_with).with(match(/Calling fixture method in before :context/))
55+
56+
generate_fixture_example_group(:context).run
57+
end
58+
59+
it "does not warn when a global fixture call is made in a before :each call" do
60+
expect(RSpec).not_to receive(:warn_with)
61+
62+
generate_fixture_example_group(:each).run
63+
end
64+
end

lib/rspec/rails/fixture_support.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,28 @@ module FixtureSupport
2828
self.use_transactional_fixtures = RSpec.configuration.use_transactional_fixtures
2929
end
3030
self.use_instantiated_fixtures = RSpec.configuration.use_instantiated_fixtures
31+
32+
def self.fixtures(*args)
33+
orig_methods = private_instance_methods
34+
super.tap do
35+
new_methods = private_instance_methods - orig_methods
36+
new_methods.each do |method_name|
37+
proxy_method_warning_if_called_in_before_context_scope(method_name)
38+
end
39+
end
40+
end
41+
42+
def self.proxy_method_warning_if_called_in_before_context_scope(method_name)
43+
orig_implementation = instance_method(method_name)
44+
define_method(method_name) do |*args, &blk|
45+
if inspect.include?("before(:context)")
46+
RSpec.warn_with("Calling fixture method in before :context ")
47+
else
48+
orig_implementation.bind(self).call(*args, &blk)
49+
end
50+
end
51+
end
52+
3153
fixtures RSpec.configuration.global_fixtures if RSpec.configuration.global_fixtures
3254
end
3355
end

0 commit comments

Comments
 (0)