Permalink
Browse files

Get working with modern Cucumber, drop support for 0.3

  • Loading branch information...
1 parent f13124a commit fc3cef0d1a72f5d8896511457726fdc38cd061f2 @nicksieger nicksieger committed Oct 11, 2010
Showing with 163 additions and 121 deletions.
  1. +1 −0 Rakefile
  2. +21 −34 acceptance/verification_spec.rb
  3. +55 −27 lib/ci/reporter/cucumber.rb
  4. +86 −60 spec/ci/reporter/cucumber_spec.rb
View
1 Rakefile
@@ -37,6 +37,7 @@ end
# !@#$ no easy way to empty the default list of prerequisites
# Leave my tasks alone, Hoe
%w(default spec rcov).each do |task|
+ next unless Rake::Task.task_defined?(task)
Rake::Task[task].prerequisites.clear
Rake::Task[task].actions.clear
end
View
55 acceptance/verification_spec.rb
@@ -68,48 +68,35 @@
describe "Cucumber acceptance" do
it "should generate three XML files" do
- File.exist?(File.join(REPORTS_DIR, 'FEATURES-Feature-Example-feature-Conscientious-developer.xml')).should == true
- File.exist?(File.join(REPORTS_DIR, 'FEATURES-Feature-Example-feature-Lazy-hacker.xml')).should == true
- File.exist?(File.join(REPORTS_DIR, 'FEATURES-Feature-Example-feature-Bad-coder.xml')).should == true
+ File.exist?(File.join(REPORTS_DIR, 'FEATURES-Example-feature.xml')).should == true
- Dir["#{REPORTS_DIR}/FEATURES-*.xml"].length.should == 3
+ Dir["#{REPORTS_DIR}/FEATURES-*.xml"].length.should == 1
end
- it "should have three tests and no failures for the conscientious developer" do
- doc = File.open(File.join(REPORTS_DIR, 'FEATURES-Feature-Example-feature-Conscientious-developer.xml')) do |f|
- REXML::Document.new(f)
+ context "FEATURES report file" do
+ before :each do
+ @doc = File.open(File.join(REPORTS_DIR, 'FEATURES-Example-feature.xml')) do |f|
+ REXML::Document.new(f)
+ end
end
- doc.root.attributes["errors"].should == "0"
- doc.root.attributes["failures"].should == "0"
- doc.root.attributes["tests"].should == "3"
- doc.root.elements.to_a("/testsuite/testcase").size.should == 3
- end
- it "should have three tests and one failure for the lazy hacker" do
- doc = File.open(File.join(REPORTS_DIR, 'FEATURES-Feature-Example-feature-Lazy-hacker.xml')) do |f|
- REXML::Document.new(f)
+ it "should have three tests and two failures" do
+ @doc.root.attributes["errors"].should == "0"
+ @doc.root.attributes["failures"].should == "2"
+ @doc.root.attributes["tests"].should == "3"
+ @doc.root.elements.to_a("/testsuite/testcase").size.should == 3
end
- doc.root.attributes["errors"].should == "0"
- doc.root.attributes["failures"].should == "1"
- doc.root.attributes["tests"].should == "3"
- doc.root.elements.to_a("/testsuite/testcase").size.should == 3
-
- failures = doc.root.elements.to_a("/testsuite/testcase/failure")
- failures.size.should == 1
- failures.first.attributes["type"].should == "Spec::Expectations::ExpectationNotMetError"
- end
- it "should have three tests and one failure for the bad coder" do
- doc = File.open(File.join(REPORTS_DIR, 'FEATURES-Feature-Example-feature-Bad-coder.xml')) do |f|
- REXML::Document.new(f)
+ it "should have one failure for the lazy hacker" do
+ failures = @doc.root.elements.to_a("/testsuite/testcase[@name='Lazy hacker']/failure")
+ failures.size.should == 1
+ failures.first.attributes["type"].should == "Spec::Expectations::ExpectationNotMetError"
end
- doc.root.attributes["errors"].should == "0"
- doc.root.attributes["failures"].should == "1"
- doc.root.attributes["tests"].should == "3"
- doc.root.elements.to_a("/testsuite/testcase").size.should == 3
- failures = doc.root.elements.to_a("/testsuite/testcase/failure")
- failures.size.should == 1
- failures.first.attributes["type"].should == "RuntimeError"
+ it "should have one failure for the bad coder" do
+ failures = @doc.root.elements.to_a("/testsuite/testcase[@name='Bad coder']/failure")
+ failures.size.should == 1
+ failures.first.attributes["type"].should == "RuntimeError"
+ end
end
end
View
82 lib/ci/reporter/cucumber.rb
@@ -46,53 +46,81 @@ def location
end
end
- class Cucumber < ::Cucumber::Ast::Visitor
-
- attr_accessor :test_suite, :report_manager, :feature_name
+ class Cucumber
+ attr_accessor :report_manager, :test_suite, :name
def initialize(step_mother, io, options)
- self.report_manager = ReportManager.new("features")
- super(step_mother)
+ @report_manager = ReportManager.new("features")
end
- def visit_feature_name(name)
- self.feature_name = name.split("\n").first
- super
+ def before_feature(feature)
+ self.test_suite = TestSuite.new(@name)
+ test_suite.start
end
- def visit_feature_element(feature_element)
- self.test_suite = TestSuite.new("#{feature_name} #{feature_element.instance_variable_get("@name")}")
- test_suite.start
+ def after_feature(feature)
+ test_suite.name = @name
+ test_suite.finish
+ report_manager.write_report(@test_suite)
+ @test_suite = nil
+ end
- return_value = super
+ def before_background(*args)
+ end
- test_suite.finish
- report_manager.write_report(test_suite)
- self.test_suite = nil
+ def after_background(*args)
+ end
- return_value
+ def feature_name(keyword, name)
+ @name = (name || "Unnamed feature").split("\n").first
end
- def visit_step(step)
- test_case = TestCase.new(step.name)
- test_case.start
+ def scenario_name(keyword, name, *args)
+ @scenario = (name || "Unnamed scenario").split("\n").first
+ end
- return_value = super
+ def before_steps(steps)
+ @test_case = TestCase.new(@scenario)
+ @test_case.start
+ end
- test_case.finish
+ def after_steps(steps)
+ @test_case.finish
- case step.status
+ case steps.status
when :pending, :undefined
- test_case.name = "#{test_case.name} (PENDING)"
+ @test_case.name = "#{@test_case.name} (PENDING)"
when :skipped
- test_case.name = "#{test_case.name} (SKIPPED)"
+ @test_case.name = "#{@test_case.name} (SKIPPED)"
when :failed
- test_case.failures << CucumberFailure.new(step)
+ @test_case.failures << CucumberFailure.new(steps)
end
- test_suite.testcases << test_case
+ test_suite.testcases << @test_case
+ @test_case = nil
+ end
- return_value
+ def before_examples(*args)
+ @header_row = true
+ end
+
+ def after_examples(*args)
+ end
+
+ def before_table_row(table_row)
+ @test_case = TestCase.new("#@scenario (outline: #{table_row.name})")
+ @test_case.start
+ end
+
+ def after_table_row(table_row)
+ if @header_row
+ @header_row = false
+ return
+ end
+ @test_case.finish
+ @test_case.failures << CucumberFailure.new(table_row) if table_row.failed?
+ test_suite.testcases << @test_case
+ @test_case = nil
end
end
end
View
146 spec/ci/reporter/cucumber_spec.rb
@@ -73,54 +73,69 @@ def new_instance
it "should record the feature name when a new feature is visited" do
cucumber = new_instance
- cucumber.visit_feature_name("Some feature name")
- cucumber.feature_name.should == "Some feature name"
+ cucumber.feature_name(nil, "Some feature name")
+ cucumber.name.should == "Some feature name"
end
it "should record only the first line of a feature name" do
cucumber = new_instance
- cucumber.visit_feature_name("Some feature name\nLonger description")
- cucumber.feature_name.should == "Some feature name"
+ cucumber.feature_name(nil, "Some feature name\nLonger description")
+ cucumber.name.should == "Some feature name"
end
- describe "when visiting a new scenario" do
+ context "applied to a feature" do
before(:each) do
@cucumber = new_instance
- @cucumber.visit_feature_name("Demo feature")
+ @cucumber.feature_name(nil, "Demo feature")
- @test_suite = mock("test_suite", :start => nil, :finish => nil)
+ @test_suite = mock("test_suite", :start => nil, :finish => nil, :name= => nil)
CI::Reporter::TestSuite.stub!(:new).and_return(@test_suite)
- @feature_element = mock("feature_element", :accept => true)
+ @feature = mock("feature")
@report_manager.stub!(:write_report)
end
- it "should create a new test suite" do
- # FIXME: @name is feature_element purely as a by-product of the
- # mocking framework implementation. But then again, using
- # +instance_variable_get+ in the first place is a bit icky.
- CI::Reporter::TestSuite.should_receive(:new).with("Demo feature feature_element")
- @cucumber.visit_feature_element(@feature_element)
- end
+ context "before" do
+ it "should create a new test suite" do
+ CI::Reporter::TestSuite.should_receive(:new).with(/Demo feature/)
+ @cucumber.before_feature(@feature)
+ end
- it "should indicate that the test suite has started" do
- @test_suite.should_receive(:start)
- @cucumber.visit_feature_element(@feature_element)
+ it "should indicate that the test suite has started" do
+ @test_suite.should_receive(:start)
+ @cucumber.before_feature(@feature)
+ end
end
- it "should indicate that the test suite has finished" do
- @test_suite.should_receive(:finish)
- @cucumber.visit_feature_element(@feature_element)
- end
+ context "after" do
+ before :each do
+ @cucumber = new_instance
+ @cucumber.feature_name(nil, "Demo feature")
+
+ @test_suite = mock("test_suite", :start => nil, :finish => nil, :name= => nil)
+ CI::Reporter::TestSuite.stub!(:new).and_return(@test_suite)
+
+ @feature = mock("feature")
+
+ @report_manager.stub!(:write_report)
- it "should ask the report manager to write a report" do
- @report_manager.should_receive(:write_report).with(@test_suite)
- @cucumber.visit_feature_element(@feature_element)
+ @cucumber.before_feature(@feature)
+ end
+
+ it "should indicate that the test suite has finished" do
+ @test_suite.should_receive(:finish)
+ @cucumber.after_feature(@feature)
+ end
+
+ it "should ask the report manager to write a report" do
+ @report_manager.should_receive(:write_report).with(@test_suite)
+ @cucumber.after_feature(@feature)
+ end
end
end
- describe "when visiting a step inside a scenario" do
+ context "inside a scenario" do
before(:each) do
@testcases = []
@@ -132,48 +147,57 @@ def new_instance
@test_case = mock("test_case", :start => nil, :finish => nil, :name => "Step Name")
CI::Reporter::TestCase.stub!(:new).and_return(@test_case)
- @step = mock("step", :accept => true, :status => :passed)
+ @step = mock("step", :status => :passed)
@step.stub!(:name).and_return("Step Name")
end
- it "should create a new test case" do
- CI::Reporter::TestCase.should_receive(:new).with("Step Name")
- @cucumber.visit_step(@step)
- end
+ context "before steps" do
+ it "should create a new test case" do
+ CI::Reporter::TestCase.should_receive(:new).with("Step Name")
+ @cucumber.scenario_name(nil, "Step Name")
+ @cucumber.before_steps(@step)
+ end
- it "should indicate that the test case has started" do
- @test_case.should_receive(:start)
- @cucumber.visit_step(@step)
+ it "should indicate that the test case has started" do
+ @test_case.should_receive(:start)
+ @cucumber.before_steps(@step)
+ end
end
- it "should indicate that the test case has finished" do
- @test_case.should_receive(:finish)
- @cucumber.visit_step(@step)
- end
+ context "after steps" do
+ before :each do
+ @cucumber.before_steps(@step)
+ end
- it "should add the test case to the suite's list of cases" do
- @testcases.should be_empty
- @cucumber.visit_step(@step)
- @testcases.should_not be_empty
- @testcases.first.should == @test_case
- end
+ it "should indicate that the test case has finished" do
+ @test_case.should_receive(:finish)
+ @cucumber.after_steps(@step)
+ end
- it "should alter the name of a test case that is pending to include '(PENDING)'" do
- @step.stub!(:status).and_return(:pending)
- @test_case.should_receive(:name=).with("Step Name (PENDING)")
- @cucumber.visit_step(@step)
- end
+ it "should add the test case to the suite's list of cases" do
+ @testcases.should be_empty
+ @cucumber.after_steps(@step)
+ @testcases.should_not be_empty
+ @testcases.first.should == @test_case
+ end
- it "should alter the name of a test case that is undefined to include '(PENDING)'" do
- @step.stub!(:status).and_return(:undefined)
- @test_case.should_receive(:name=).with("Step Name (PENDING)")
- @cucumber.visit_step(@step)
- end
+ it "should alter the name of a test case that is pending to include '(PENDING)'" do
+ @step.stub!(:status).and_return(:pending)
+ @test_case.should_receive(:name=).with("Step Name (PENDING)")
+ @cucumber.after_steps(@step)
+ end
+
+ it "should alter the name of a test case that is undefined to include '(PENDING)'" do
+ @step.stub!(:status).and_return(:undefined)
+ @test_case.should_receive(:name=).with("Step Name (PENDING)")
+ @cucumber.after_steps(@step)
+ end
- it "should alter the name of a test case that was skipped to include '(SKIPPED)'" do
- @step.stub!(:status).and_return(:skipped)
- @test_case.should_receive(:name=).with("Step Name (SKIPPED)")
- @cucumber.visit_step(@step)
+ it "should alter the name of a test case that was skipped to include '(SKIPPED)'" do
+ @step.stub!(:status).and_return(:skipped)
+ @test_case.should_receive(:name=).with("Step Name (SKIPPED)")
+ @cucumber.after_steps(@step)
+ end
end
describe "that fails" do
@@ -183,18 +207,20 @@ def new_instance
@failures = []
@test_case.stub!(:failures).and_return(@failures)
+ @cucumber.before_steps(@step)
+
@cucumber_failure = mock("cucumber_failure")
CI::Reporter::CucumberFailure.stub!(:new).and_return(@cucumber_failure)
end
it "should create a new cucumber failure with that step" do
CI::Reporter::CucumberFailure.should_receive(:new).with(@step)
- @cucumber.visit_step(@step)
+ @cucumber.after_steps(@step)
end
it "should add the failure to the suite's list of failures" do
@failures.should be_empty
- @cucumber.visit_step(@step)
+ @cucumber.after_steps(@step)
@failures.should_not be_empty
@failures.first.should == @cucumber_failure
end

0 comments on commit fc3cef0

Please sign in to comment.