Permalink
Browse files

switch to rspec mocking (instead of mocha); README updates

  • Loading branch information...
1 parent c102559 commit 5ba6081aa112e994fee2b50b4995a77a67a99080 @glv committed Mar 5, 2010
Showing with 141 additions and 106 deletions.
  1. +1 −0 .gitignore
  2. +41 −10 README.md
  3. +2 −0 Rakefile
  4. +85 −84 lib/rspec/unit/test_case.rb
  5. +3 −1 spec/spec_helper.rb
  6. +9 −11 spec/test_case_spec.rb
View
@@ -3,3 +3,4 @@
coverage
rdoc
pkg
+rspec-dev-setup.rb
View
@@ -1,6 +1,6 @@
# rspec-unit
-Test::Unit compatibility for Rspec.
+Test::Unit compatibility for Rspec 2.
Just add this to your code:
@@ -33,20 +33,51 @@ You can also attach metadata to the entire class with the
end
Each instance of `Rspec::Unit::TestCase` is equivalent to an
-Rspec `describe` block, so it can also include `it` blocks,
+Rspec `describe` block, so it can also include `example` blocks,
`before` and `after` blocks, and nested `describe` blocks. Test
-methods and `it` blocks can contain either assertions or `should`
+methods and `example` blocks can contain either assertions or `should`
expressions. `test` blocks (as found in Rails 2.x) also work.
Additionally, assertions can be used inside ordinary Rspec
examples.
## Rationale
-I originally wrote test/unit compatibility for Micronaut, a lightweight
-Rspec clone by Chad Humphries. Micronaut has been rolled into Rspec as
-the core of Rspec 2, and I was able to move the test/unit compatibility
-over with minimal changes.
+This gem is the rough equivalent, for Rspec 2, of the test/unit
+compatibility that was a part of the core Rspec gem in Rspec 1.
+The new Rspec runner design makes it quite easy to implement this
+functionality as a separate gem, which seems like a better choice
+in many ways.
+
+Currently, test/unit compatibility is much more limited than in
+Rspec 1. The goal is not to make Rspec 2 a drop-in replacement for
+test/unit; rather, we have two more limited goals:
+
+1. to allow Rspec 2 examples to easily make use of test/unit assertions
+ in cases where those assertions are valuable, or where assertions
+ might be the best way to express particular expectations.
+2. to make it *easy* for a project to switch an existing test/unit
+ suite over to run under Rspec, as the start of a gradual, piecemeal
+ conversion to Rspec.
+
+As such, there are some things we don''t support:
+
+* The top-level module name is different. For example, one requires
+ `rspec/unit` rather than `test/unit`, and extends `Rspec::Unit::TestCase`
+ rather than `Test::Unit::TestCase`.
+* TestSuite is not supported. The Rspec 2 metadata features are
+ far more flexible than test/unit-style suites.
+* Because of the very different implementation, many test/unit extensions
+ will not run properly.
+* All test output and summaries are in Rspec style; test/unit-compatible
+ output is not supported.
+
+We will certainly consider supporting those things if there is demand.
+
+I originally wrote this test/unit compatibility gem for Micronaut, a
+lightweight Rspec clone by Chad Humphries. Micronaut has been rolled
+into Rspec as the core of Rspec 2, and I was able to move the test/unit
+compatibility over with minimal changes.
The point of this gem is not that I think test/unit is a better way
to write tests than the Rspec style. I admit that I'm a TDD oldtimer
@@ -57,9 +88,9 @@ nature has its limits, and I do find specs a big improvement.
So why rspec-unit? Three reasons:
1. I wanted to show off the generality of Micronaut's (and now Rspec's)
- architecture. I hope rspec-unit can
- serve as an example for anyone who wants to experiment with new
- ways of expressing tests and specs on top of Rspec.
+ architecture. I hope rspec-unit can serve as an example for anyone
+ who wants to experiment with new ways of expressing tests and specs
+ on top of Rspec.
2. Many projects with existing test/unit test suites might want to
benefit from the [metadata goodness][metadata] in Rspec 2, or begin
a gradual, piecemeal change to an Rspec style. That's pretty
View
@@ -1,6 +1,8 @@
require 'rubygems'
require 'rake'
+require File.dirname(__FILE__) + '/rspec-dev-setup' if File.exists?(File.dirname(__FILE__) + '/rspec-dev-setup.rb')
+
begin
require 'jeweler'
Jeweler::Tasks.new do |gem|
View
@@ -25,96 +25,97 @@ class TestCase < Rspec::Core::ExampleGroup
@configuration = Rspec::Core.configuration
- class <<self
- def inherited(klass)
- super
-
- install_setup_and_teardown(klass)
-
- name = test_case_name(klass)
- _build(klass, caller, [name, {}])
- klass.metadata[:example_group][:test_unit] = true
- end
-
- def test_case_info(options)
- metadata[:example_group].update(options)
- end
-
- def test_info(options)
- @_metadata_for_next = options
- end
-
- def method_added(id)
- name = id.to_s
- caller_lines[name] = caller
- if test_method?(name)
- test_method_metadata[name] = @_metadata_for_next
- @_metadata_for_next = nil
- end
- end
-
- def examples
- @tc_examples ||= ExamplesCollection.new(self, super)
- end
-
- def ancestors(superclass_last=false)
- superclass_last ? super[0..-2] : super[1..-1]
- end
-
- def to_s
- self == Rspec::Unit::TestCase ? 'Rspec::Unit::TestCase' : super
- end
-
- private
-
- def test_case_name(klass)
- class_name = klass.name(false)
- (class_name.nil? || class_name.empty?) ? 'Anonymous TestCase' : "TestCase #{class_name}"
- end
-
- def caller_lines
- @_caller_lines ||= {}
- end
+ def self.inherited(klass)
+ super
- def test_method_metadata
- @_test_method_metadata ||= {}
+ install_setup_and_teardown(klass)
+
+ name = test_case_name(klass)
+ _build(klass, caller, [name, {}])
+ klass.metadata[:example_group][:test_unit] = true
+ end
+
+ def self.test_case_info(options)
+ metadata[:example_group].update(options)
+ end
+
+ def self.test_info(options)
+ @_metadata_for_next = options
+ end
+
+ def self.method_added(id)
+ name = id.to_s
+ caller_lines[name] = caller
+ if test_method?(name)
+ test_method_metadata[name] = @_metadata_for_next
+ @_metadata_for_next = nil
end
+ end
+
+ def self.examples
+ @tc_examples ||= ExamplesCollection.new(self, super)
+ end
+
+ def self.ancestors(superclass_last=false)
+ superclass_last ? super[0..-2] : super[1..-1]
+ end
+
+ def self.to_s
+ self == Rspec::Unit::TestCase ? 'Rspec::Unit::TestCase' : super
+ end
- def install_setup_and_teardown(klass)
- # Only do this for direct descendants, because test/unit chains
- # fixtures through explicit calls to super.
- if self == Rspec::Unit::TestCase
- klass.class_eval do
- before {setup}
- after {teardown}
- end
+ def self.test_case_name(klass)
+ class_name = klass.name(false)
+ (class_name.nil? || class_name.empty?) ? 'Anonymous TestCase' : "TestCase #{class_name}"
+ end
+
+ def self.caller_lines
+ @_caller_lines ||= {}
+ end
+
+ def self.test_method_metadata
+ @_test_method_metadata ||= {}
+ end
+
+ def self.install_setup_and_teardown(klass)
+ # Only do this for direct descendants, because test/unit chains
+ # fixtures through explicit calls to super.
+ if self == Rspec::Unit::TestCase
+ klass.class_eval do
+ before {setup}
+ after {teardown}
end
end
-
- def test_method?(method_name)
- method_name =~ TEST_METHOD_PATTERN &&
- public_method_defined?(method_name) &&
- (-1..0).include?(instance_method(method_name).arity)
- end
-
- def test_methods
- public_instance_methods(true).select{|m| test_method?(m)}
- end
-
- def number_of_tests
- test_methods.size
- end
-
- def tests
- @tests ||= test_methods.sort.map do |m|
- name = "#{metadata[:example_group][:name]}##{m}"
- meta = (test_method_metadata[m] || {}).merge({:caller => caller_lines[m],
- :full_description => name,
- :test_unit => true})
- Core::Example.new(self, m, meta, proc{execute(m)})
- end
+ end
+
+ def self.test_method?(method_name)
+ method_name =~ TEST_METHOD_PATTERN &&
+ public_method_defined?(method_name) &&
+ (-1..0).include?(instance_method(method_name).arity)
+ end
+
+ def self.test_methods
+ public_instance_methods(true).select{|m| test_method?(m)}
+ end
+
+ def self.number_of_tests
+ test_methods.size
+ end
+
+ def self.tests
+ @tests ||= test_methods.sort.map do |m|
+ name = "#{metadata[:example_group][:name]}##{m}"
+ meta = (test_method_metadata[m] || {}).merge({:caller => caller_lines[m],
+ :full_description => name,
+ :test_unit => true})
+ Core::Example.new(self, m, meta, proc{execute(m)})
end
-
+ end
+
+ class <<self
+ private :test_case_name, :caller_lines, :test_method_metadata,
+ :install_setup_and_teardown, :test_method?, :test_methods,
+ :number_of_tests, :tests
end
def initialize
View
@@ -1,5 +1,7 @@
require 'rubygems'
+require File.dirname(__FILE__) + '/../rspec-dev-setup' if File.exists?(File.dirname(__FILE__) + '/../rspec-dev-setup.rb')
+
require 'rspec'
gem 'mocha'
@@ -31,7 +33,7 @@ def in_editor?
end
Rspec.configure do |c|
- c.mock_framework = :mocha
+ c.mock_framework = :rspec
c.filter_run :focused => true
c.run_all_when_everything_filtered = true
c.color_enabled = !in_editor?
View
@@ -103,7 +103,7 @@ def test_bar; end
@foo.class_eval do
def test_bar; end
end
- @foo.expects(:test_bar).once
+ @foo.should_receive(:test_bar).once
run_tests(@foo)
end
end
@@ -115,14 +115,12 @@ def test_bar; end
def test_baz; end
end
- test_run = sequence('test_run')
-
- @foo.expects(:setup) .once.in_sequence(test_run)
- @foo.expects(:test_bar).once.in_sequence(test_run)
- @foo.expects(:teardown).once.in_sequence(test_run)
- @foo.expects(:setup) .once.in_sequence(test_run)
- @foo.expects(:test_baz).once.in_sequence(test_run)
- @foo.expects(:teardown).once.in_sequence(test_run)
+ @foo.should_receive(:setup) .once.ordered
+ @foo.should_receive(:test_bar).once.ordered
+ @foo.should_receive(:teardown).once.ordered
+ @foo.should_receive(:setup) .once.ordered
+ @foo.should_receive(:test_baz).once.ordered
+ @foo.should_receive(:teardown).once.ordered
run_tests(@foo)
end
@@ -361,7 +359,7 @@ def test_quux; end
def test_bar; end
end
- @foo.expects(:bar).once
+ @foo.should_receive(:bar).once
run_tests(@foo)
end
end
@@ -373,7 +371,7 @@ def test_bar; end
def test_bar; end
end
- @foo.expects(:bar).once
+ @foo.should_receive(:bar).once
run_tests(@foo)
end
end

0 comments on commit 5ba6081

Please sign in to comment.