Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fix inclusion order of RSpec::Matchers in Test::Unit and MiniTest.

Due to a bug in ruby 1.9, RSpec::Matchers must be included in the superclass (MiniTest::Unit::TestCase) before it is included in a subclass (Test::Unit::TestCase) or we may get infinite recursion and a SystemStackError from our `super` call in our method_missing hook.  See this gist for more info about the ruby 1.9 bug:

https://gist.github.com/845896

Closes #67.
  • Loading branch information...
commit 790a84982a9f1e95a48e846a75a471cd176d7a31 1 parent 0a29866
@myronmarston myronmarston authored
View
13 lib/rspec/matchers.rb
@@ -155,13 +155,18 @@ module RSpec
# end
#
module Matchers
- # Include Matchers for other test frameworks
- if defined?(Test::Unit::TestCase)
- Test::Unit::TestCase.send(:include, self)
- end
+ # Include Matchers for other test frameworks.
+ # Note that MiniTest _must_ come before TU because on ruby 1.9,
+ # T::U::TC is a subclass of MT::U::TC and a 1.9 bug can lead
+ # to infinite recursion from the `super` call in our method_missing
+ # hook. See this gist for more info:
+ # https://gist.github.com/845896
if defined?(MiniTest::Unit::TestCase)
MiniTest::Unit::TestCase.send(:include, self)
end
+ if defined?(Test::Unit::TestCase)
+ Test::Unit::TestCase.send(:include, self)
+ end
end
end
View
4 spec/rspec/matchers/be_spec.rb
@@ -1,10 +1,6 @@
require 'spec_helper'
describe "should be_predicate" do
- it "allows other undefined methods to raise errors as normal" do
- expect { some_undefined_method }.to raise_error(NameError)
- end
-
it "passes when actual returns true for :predicate?" do
actual = stub("actual", :happy? => true)
actual.should be_happy
View
24 spec/rspec/matchers/matchers_spec.rb
@@ -1,19 +1,5 @@
require 'spec_helper'
-module Test
- module Unit
- class TestCase
- end
- end
-end
-
-module MiniTest
- module Unit
- class TestCase
- end
- end
-end
-
module RSpec
describe Matchers do
@@ -25,12 +11,6 @@ module RSpec
end
context "once required" do
-
- before(:all) do
- path = File.expand_path("../../../../#{path}", __FILE__)
- load File.join(path, 'lib/rspec/matchers.rb')
- end
-
it "includes itself in Test::Unit::TestCase" do
test_unit_case = Test::Unit::TestCase.new
sample_matchers.each do |sample_matcher|
@@ -38,8 +18,8 @@ module RSpec
end
end
- it "includes itself in MiniTest::Unit::TestCase" do
- minitest_case = MiniTest::Unit::TestCase.new
+ it "includes itself in MiniTest::Unit::TestCase", :if => defined?(MiniTest) do
+ minitest_case = MiniTest::Unit::TestCase.new(nil)
sample_matchers.each do |sample_matcher|
minitest_case.should respond_to(sample_matcher)
end
View
23 spec/rspec/matchers/method_missing_spec.rb
@@ -0,0 +1,23 @@
+require 'spec_helper'
+
+shared_examples_for "a well-behaved method_missing hook" do
+ it "raises a NoMethodError (and not SystemStackError) for an undefined method" do
+ expect { subject.some_undefined_method }.to raise_error(NoMethodError)
+ end
+end
+
+describe "RSpec::Matchers method_missing hook" do
+ subject { self }
+ it_behaves_like "a well-behaved method_missing hook"
+
+ context 'when invoked in a Test::Unit::TestCase' do
+ subject { Test::Unit::TestCase.new }
+ it_behaves_like "a well-behaved method_missing hook"
+ end
+
+ context 'when invoked in a MiniTest::Unit::TestCase', :if => defined?(MiniTest) do
+ subject { MiniTest::Unit::TestCase.new(nil) }
+ it_behaves_like "a well-behaved method_missing hook"
+ end
+end
+
View
8 spec/spec_helper.rb
@@ -7,6 +7,14 @@ def add_to_load_path(path, prepend=false)
end
end
+require 'test/unit'
+
+# Make it easy to instantiate test cases for our specs.
+# Test::Unit::TestCase#initialize is picky about what arguments it expects.
+class Test::Unit::TestCase
+ def initialize; end
+end
+
add_to_load_path("rspec-expectations", :prepend)
add_to_load_path("rspec-core")
add_to_load_path("rspec-mocks")
Please sign in to comment.
Something went wrong with that request. Please try again.