added RSpec and RSpec on Rails

This commit is contained in:
Xin Zheng 2008-01-22 16:39:09 +00:00
parent ddd5b4cf19
commit 3f607d565b
316 changed files with 23828 additions and 0 deletions

View file

@ -0,0 +1,5 @@
require File.join(File.dirname(__FILE__), *%w[helper])
["example_groups","interop"].each do |dir|
require File.join(File.dirname(__FILE__), "#{dir}/stories")
end

View file

@ -0,0 +1,45 @@
Story: autogenerated docstrings
As an RSpec user
I want examples to generate their own names
So that I can reduce duplication between example names and example code
Scenario: run passing examples with ruby
Given the file ../../examples/pure/autogenerated_docstrings_example.rb
When I run it with the ruby interpreter -fs
Then the stdout should match /should equal 5/
And the stdout should match /should be < 5/
And the stdout should match /should include "a"/
And the stdout should match /should respond to #size/
Scenario: run failing examples with ruby
Given the file ../../failing_examples/failing_autogenerated_docstrings_example.rb
When I run it with the ruby interpreter -fs
Then the stdout should match /should equal 2/
And the stdout should match /should be > 5/
And the stdout should match /should include "b"/
And the stdout should match /should not respond to #size/
Scenario: run passing examples with spec
Given the file ../../examples/pure/autogenerated_docstrings_example.rb
When I run it with the spec script -fs
Then the stdout should match /should equal 5/
And the stdout should match /should be < 5/
And the stdout should match /should include "a"/
And the stdout should match /should respond to #size/
Scenario: run failing examples with spec
Given the file ../../failing_examples/failing_autogenerated_docstrings_example.rb
When I run it with the spec script -fs
Then the stdout should match /should equal 2/
And the stdout should match /should be > 5/
And the stdout should match /should include "b"/
And the stdout should match /should not respond to #size/

View file

@ -0,0 +1,17 @@
Story: Spec::ExampleGroup with should methods
As an RSpec adopter accustomed to classes and methods
I want to use should_* methods in an ExampleGroup
So that I use RSpec with classes and methods that look more like RSpec examples
Scenario: Run with ruby
Given the file spec/example_group_with_should_methods.rb
When I run it with the ruby interpreter
Then the exit code should be 256
And the stdout should match "2 examples, 1 failure"
Scenario: Run with spec
Given the file spec/example_group_with_should_methods.rb
When I run it with the spec script
Then the exit code should be 256
And the stdout should match "2 examples, 1 failure"

View file

@ -0,0 +1,17 @@
Story: Nested example groups
As an RSpec user
I want to nest examples groups
So that I can better organize my examples
Scenario: Run with ruby
Given the file ../../examples/pure/stack_spec_with_nested_example_groups.rb
When I run it with the ruby interpreter -fs
Then the stdout should match /Stack \(empty\)/
And the stdout should match /Stack \(full\)/
Scenario: Run with ruby
Given the file ../../examples/pure/stack_spec_with_nested_example_groups.rb
When I run it with the spec script -fs
Then the stdout should match /Stack \(empty\)/
And the stdout should match /Stack \(full\)/

View file

@ -0,0 +1,25 @@
Story: Getting correct output
As an RSpec user
I want to see output only once
So that I don't get confused
Scenario: Run with ruby
Given the file spec/simple_spec.rb
When I run it with the ruby interpreter
Then the exit code should be 0
And the stdout should not match /\d+ tests, \d+ assertions, \d+ failures, \d+ errors/m
And the stdout should match "1 example, 0 failures"
Scenario: Run with CommandLine object
Given the file spec/simple_spec.rb
When I run it with the CommandLine object
Then the exit code should be 0
And the stdout should not match "Loaded suite"
And the stdout should not match /\d+ tests, \d+ assertions, \d+ failures, \d+ errors/m
And the stdout should match "1 example, 0 failures"
Scenario: Tweak backtrace
Given the file stories/failing_story.rb
When I run it with the ruby interpreter
Then the stdout should not match /\/lib\/spec\//

View file

@ -0,0 +1,7 @@
require File.join(File.dirname(__FILE__), *%w[.. helper])
with_steps_for :running_rspec do
Dir["#{File.dirname(__FILE__)}/*"].each do |file|
run file if File.file?(file) && !(file =~ /\.rb$/)
end
end

View file

@ -0,0 +1,6 @@
$LOAD_PATH.unshift File.expand_path("#{File.dirname(__FILE__)}/../lib")
require 'spec'
require 'tempfile'
require File.join(File.dirname(__FILE__), *%w[resources matchers smart_match])
require File.join(File.dirname(__FILE__), *%w[resources helpers story_helper])
require File.join(File.dirname(__FILE__), *%w[resources steps running_rspec])

View file

@ -0,0 +1,30 @@
Story: Spec and test together
As an RSpec adopter with existing Test::Unit tests
I want to run a few specs alongside my existing Test::Unit tests
So that I can experience a smooth, gradual migration path
Scenario: Run with ruby
Given the file test/spec_and_test_together.rb
When I run it with the ruby interpreter -fs
Then the exit code should be 256
And the stdout should match "ATest"
And the stdout should match "Test::Unit::AssertionFailedError in 'An Example should fail with assert'"
And the stdout should match "'An Example should fail with should' FAILED"
And the stdout should match "10 examples, 6 failures"
And the stdout should match /expected: 40,\s*got: 4/m
And the stdout should match /expected: 50,\s*got: 5/m
Scenario: Run with spec
Given the file test/spec_and_test_together.rb
When I run it with the spec script -fs
Then the exit code should be 256
Ands the stdout should match "ATest"
And the stdout should match "Test::Unit::AssertionFailedError in 'An Example should fail with assert'"
And the stdout should match "'An Example should fail with should' FAILED"
And the stdout should match "10 examples, 6 failures"
And the stdout should match /expected: 40,\s*got: 4/m
And the stdout should match /expected: 50,\s*got: 5/m

View file

@ -0,0 +1,7 @@
require File.join(File.dirname(__FILE__), *%w[.. helper])
with_steps_for :running_rspec do
Dir["#{File.dirname(__FILE__)}/*"].each do |file|
run file if File.file?(file) && !(file =~ /\.rb$/)
end
end

View file

@ -0,0 +1,17 @@
Story: Test::Unit::TestCase extended by rspec with should methods
As an RSpec adopter with existing Test::Unit tests
I want to use should_* methods in a Test::Unit::TestCase
So that I use RSpec with classes and methods that look more like RSpec examples
Scenario: Run with ruby
Given the file test/test_case_with_should_methods.rb
When I run it with the ruby interpreter
Then PENDING the exit code should be 256
And the stdout should match "5 examples, 3 failures"
Scenario: Run with spec
Given the file test/test_case_with_should_methods.rb
When I run it with the spec script
Then the exit code should be 256
And the stdout should match "5 examples, 3 failures"

View file

@ -0,0 +1,3 @@
This directory contains stories that are currently not passing
because they are new or they represent regressions.

View file

@ -0,0 +1,9 @@
$:.push File.join(File.dirname(__FILE__), *%w[.. .. .. lib])
require 'spec'
# Uncommenting next line will break the output story (no output!!)
# rspec_options
options = Spec::Runner::OptionParser.parse(
ARGV, $stderr, $stdout
)
Spec::Runner::CommandLine.run(options)

View file

@ -0,0 +1,16 @@
require 'spec/story'
require File.dirname(__FILE__) + '/../../../spec/ruby_forker'
module StoryHelper
include RubyForker
def spec(args, stderr)
ruby("#{File.dirname(__FILE__) + '/../../../bin/spec'} #{args}", stderr)
end
def cmdline(args, stderr)
ruby("#{File.dirname(__FILE__) + '/../../resources/helpers/cmdline.rb'} #{args}", stderr)
end
Spec::Story::World.send :include, self
end

View file

@ -0,0 +1,37 @@
module Spec
module Matchers
class SmartMatch
def initialize(expected)
@expected = expected
end
def matches?(actual)
@actual = actual
# Satisfy expectation here. Return false or raise an error if it's not met.
if @expected =~ /^\/.*\/?$/ || @expected =~ /^".*"$/
regex_or_string = eval(@expected)
if Regexp === regex_or_string
(@actual =~ regex_or_string) ? true : false
else
@actual.index(regex_or_string) != nil
end
else
false
end
end
def failure_message
"expected #{@actual.inspect} to smart_match #{@expected.inspect}, but it didn't"
end
def negative_failure_message
"expected #{@actual.inspect} not to smart_match #{@expected.inspect}, but it did"
end
end
def smart_match(expected)
SmartMatch.new(expected)
end
end
end

View file

@ -0,0 +1,12 @@
$:.push File.join(File.dirname(__FILE__), *%w[.. .. .. lib])
require 'spec'
class MySpec < Spec::ExampleGroup
def should_pass_with_should
1.should == 1
end
def should_fail_with_should
1.should == 2
end
end

View file

@ -0,0 +1,8 @@
$:.push File.join(File.dirname(__FILE__), *%w[.. .. .. lib])
require 'spec'
describe "Running an Example" do
it "should not output twice" do
true.should be_true
end
end

View file

@ -0,0 +1,50 @@
steps_for :running_rspec do
Given("the file $relative_path") do |relative_path|
@path = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "resources", relative_path))
unless File.exist?(@path)
raise "could not find file at #{@path}"
end
end
When("I run it with the $interpreter") do |interpreter|
stderr_file = Tempfile.new('rspec')
stderr_file.close
@stdout = case(interpreter)
when /^ruby interpreter/
args = interpreter.gsub('ruby interpreter','')
ruby("#{@path}#{args}", stderr_file.path)
when /^spec script/
args = interpreter.gsub('spec script','')
spec("#{@path}#{args}", stderr_file.path)
when 'CommandLine object' then cmdline(@path, stderr_file.path)
else raise "Unknown interpreter: #{interpreter}"
end
@stderr = IO.read(stderr_file.path)
@exit_code = $?.to_i
end
Then("the exit code should be $exit_code") do |exit_code|
if @exit_code != exit_code.to_i
raise "Did not exit with #{exit_code}, but with #{@exit_code}. Standard error:\n#{@stderr}"
end
end
Then("the $stream should match $regex") do |stream, string_or_regex|
written = case(stream)
when 'stdout' then @stdout
when 'stderr' then @stderr
else raise "Unknown stream: #{stream}"
end
written.should smart_match(string_or_regex)
end
Then("the $stream should not match $regex") do |stream, string_or_regex|
written = case(stream)
when 'stdout' then @stdout
when 'stderr' then @stderr
else raise "Unknown stream: #{stream}"
end
written.should_not smart_match(string_or_regex)
end
end

View file

@ -0,0 +1,15 @@
$:.push File.join(File.dirname(__FILE__), *%w[.. .. .. lib])
require 'spec/story'
Story "Failing story",
%(As an RSpec user
I want a failing test
So that I can observe the output) do
Scenario "Failing scenario" do
Then "true should be false" do
true.should == false
end
end
end

View file

@ -0,0 +1,57 @@
$:.push File.join(File.dirname(__FILE__), *%w[.. .. .. lib])
require 'spec'
# TODO - this should not be necessary, ay?
require 'spec/interop/test'
describe "An Example" do
it "should pass with assert" do
assert true
end
it "should fail with assert" do
assert false
end
it "should pass with should" do
1.should == 1
end
it "should fail with should" do
1.should == 2
end
end
class ATest < Test::Unit::TestCase
def test_should_pass_with_assert
assert true
end
def test_should_fail_with_assert
assert false
end
def test_should_pass_with_should
1.should == 1
end
def test_should_fail_with_should
1.should == 2
end
def setup
@from_setup ||= 3
@from_setup += 1
end
def test_should_fail_with_setup_method_variable
@from_setup.should == 40
end
before do
@from_before = @from_setup + 1
end
def test_should_fail_with_before_block_variable
@from_before.should == 50
end
end

View file

@ -0,0 +1,30 @@
$:.push File.join(File.dirname(__FILE__), *%w[.. .. .. lib])
require 'test/unit'
require 'spec'
require 'spec/interop/test'
class MySpec < Test::Unit::TestCase
def should_pass_with_should
1.should == 1
end
def should_fail_with_should
1.should == 2
end
def should_pass_with_assert
assert true
end
def should_fail_with_assert
assert false
end
def test
raise "This is not a real test"
end
def test_ify
raise "This is a real test"
end
end