Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix how RSpec::Matchers is included in RSpec::Core::Example group to …
…prevent SystemStackError on 1.9.
  • Loading branch information
myronmarston committed Mar 7, 2011
1 parent cfa9837 commit 622a4b7
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 4 deletions.
2 changes: 0 additions & 2 deletions lib/rspec/core/command_line.rb
Expand Up @@ -16,8 +16,6 @@ def run(err, out)
@configuration.output_stream ||= out
@options.configure(@configuration)
@configuration.load_spec_files
@configuration.configure_mock_framework
@configuration.configure_expectation_framework
@world.announce_inclusion_filter
@world.announce_exclusion_filter

Expand Down
17 changes: 17 additions & 0 deletions lib/rspec/core/example_group.rb
Expand Up @@ -151,7 +151,24 @@ def self.top_level?
@top_level ||= superclass == ExampleGroup
end

def self.ensure_example_groups_are_configured
unless @example_groups_configured
RSpec.configuration.configure_mock_framework
RSpec.configuration.configure_expectation_framework
@example_groups_configured = true
end
end

def self.set_it_up(*args)
# Ruby 1.9 has a bug that can lead to infinite recursion and a
# SystemStackError if you include a module in a superclass after
# including it in a subclass: https://gist.github.com/845896
# To prevent this, we must include any modules in RSpec::Core::ExampleGroup
# before users create example groups and have a chance to include
# the same module in a subclass of RSpec::Core::ExampleGroup.
# So we need to configure example groups here.
ensure_example_groups_are_configured

symbol_description = args.shift if args.first.is_a?(Symbol)
args << build_metadata_hash_from(args)
args.unshift(symbol_description) if symbol_description
Expand Down
2 changes: 0 additions & 2 deletions spec/rspec/core/command_line_spec.rb
Expand Up @@ -50,8 +50,6 @@ module RSpec::Core
config.stub(:run_hook)

config.should_receive(:load_spec_files)
config.should_receive(:configure_mock_framework)
config.should_receive(:configure_expectation_framework)

world.should_receive(:announce_inclusion_filter)
world.should_receive(:announce_exclusion_filter)
Expand Down
45 changes: 45 additions & 0 deletions spec/rspec/core/rspec_matchers_spec.rb
@@ -0,0 +1,45 @@
require 'spec_helper'

module RSpec::Matchers
def __method_with_super
super
end

module ModThatIncludesMatchers
include RSpec::Matchers
end

RSpec.configure do |c|
c.include RSpec::Matchers, :include_rspec_matchers => true
c.include ModThatIncludesMatchers, :include_mod_that_includes_rspec_matchers => true
end

describe self do
shared_examples_for "a normal module with a method that supers" do
it "raises the expected error (and not SystemStackError)" do
expect { __method_with_super }.to raise_error(NoMethodError) # there is no __method_with_super in an ancestor
end
end

it_behaves_like "a normal module with a method that supers"

context "when RSpec::Matchers has been included in an example group" do
include RSpec::Matchers
it_behaves_like "a normal module with a method that supers"
end

context "when a module that includes RSpec::Matchers has been included in an example group" do
include RSpec::Matchers::ModThatIncludesMatchers
it_behaves_like "a normal module with a method that supers"
end

context "when RSpec::Matchers is included via configuration", :include_rspec_matchers => true do
it_behaves_like "a normal module with a method that supers"
end

context "when RSpec::Matchers is included in a module that is included via configuration", :include_mod_that_includes_rspec_matchers => true do
it_behaves_like "a normal module with a method that supers"
end
end
end

0 comments on commit 622a4b7

Please sign in to comment.