Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

Commit 622a4b7

Browse files
committed
Fix how RSpec::Matchers is included in RSpec::Core::Example group to prevent SystemStackError on 1.9.
1 parent cfa9837 commit 622a4b7

File tree

4 files changed

+62
-4
lines changed

4 files changed

+62
-4
lines changed

lib/rspec/core/command_line.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ def run(err, out)
1616
@configuration.output_stream ||= out
1717
@options.configure(@configuration)
1818
@configuration.load_spec_files
19-
@configuration.configure_mock_framework
20-
@configuration.configure_expectation_framework
2119
@world.announce_inclusion_filter
2220
@world.announce_exclusion_filter
2321

lib/rspec/core/example_group.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,24 @@ def self.top_level?
151151
@top_level ||= superclass == ExampleGroup
152152
end
153153

154+
def self.ensure_example_groups_are_configured
155+
unless @example_groups_configured
156+
RSpec.configuration.configure_mock_framework
157+
RSpec.configuration.configure_expectation_framework
158+
@example_groups_configured = true
159+
end
160+
end
161+
154162
def self.set_it_up(*args)
163+
# Ruby 1.9 has a bug that can lead to infinite recursion and a
164+
# SystemStackError if you include a module in a superclass after
165+
# including it in a subclass: https://gist.github.com/845896
166+
# To prevent this, we must include any modules in RSpec::Core::ExampleGroup
167+
# before users create example groups and have a chance to include
168+
# the same module in a subclass of RSpec::Core::ExampleGroup.
169+
# So we need to configure example groups here.
170+
ensure_example_groups_are_configured
171+
155172
symbol_description = args.shift if args.first.is_a?(Symbol)
156173
args << build_metadata_hash_from(args)
157174
args.unshift(symbol_description) if symbol_description

spec/rspec/core/command_line_spec.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ module RSpec::Core
5050
config.stub(:run_hook)
5151

5252
config.should_receive(:load_spec_files)
53-
config.should_receive(:configure_mock_framework)
54-
config.should_receive(:configure_expectation_framework)
5553

5654
world.should_receive(:announce_inclusion_filter)
5755
world.should_receive(:announce_exclusion_filter)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
require 'spec_helper'
2+
3+
module RSpec::Matchers
4+
def __method_with_super
5+
super
6+
end
7+
8+
module ModThatIncludesMatchers
9+
include RSpec::Matchers
10+
end
11+
12+
RSpec.configure do |c|
13+
c.include RSpec::Matchers, :include_rspec_matchers => true
14+
c.include ModThatIncludesMatchers, :include_mod_that_includes_rspec_matchers => true
15+
end
16+
17+
describe self do
18+
shared_examples_for "a normal module with a method that supers" do
19+
it "raises the expected error (and not SystemStackError)" do
20+
expect { __method_with_super }.to raise_error(NoMethodError) # there is no __method_with_super in an ancestor
21+
end
22+
end
23+
24+
it_behaves_like "a normal module with a method that supers"
25+
26+
context "when RSpec::Matchers has been included in an example group" do
27+
include RSpec::Matchers
28+
it_behaves_like "a normal module with a method that supers"
29+
end
30+
31+
context "when a module that includes RSpec::Matchers has been included in an example group" do
32+
include RSpec::Matchers::ModThatIncludesMatchers
33+
it_behaves_like "a normal module with a method that supers"
34+
end
35+
36+
context "when RSpec::Matchers is included via configuration", :include_rspec_matchers => true do
37+
it_behaves_like "a normal module with a method that supers"
38+
end
39+
40+
context "when RSpec::Matchers is included in a module that is included via configuration", :include_mod_that_includes_rspec_matchers => true do
41+
it_behaves_like "a normal module with a method that supers"
42+
end
43+
end
44+
end
45+

0 commit comments

Comments
 (0)