diff --git a/.travis.yml b/.travis.yml index a55392d..5a79c59 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ rvm: - - 1.9.3 - 2.0 - 2.1 + - 2.3.1 diff --git a/acceptance/spinach/features/spinach_example_no_feature_definition.feature b/acceptance/spinach/features/spinach_example_no_feature_definition.feature new file mode 100644 index 0000000..d753484 --- /dev/null +++ b/acceptance/spinach/features/spinach_example_no_feature_definition.feature @@ -0,0 +1,14 @@ +Feature: Example Spinach no feature + As a conscientious developer who writes features + I want to be able to see my features passing on the CI Server + So that I can bask in the glow of a green bar + + Scenario: Scenario 1 + Given that I am a conscientious developer + And I write cucumber features + Then I should see a green bar + + Scenario: Another scenario + Given a step + When I do something + Then I see nothing diff --git a/acceptance/verification_spec.rb b/acceptance/verification_spec.rb index 96ae38a..cee866c 100644 --- a/acceptance/verification_spec.rb +++ b/acceptance/verification_spec.rb @@ -9,9 +9,8 @@ include CI::Reporter::TestUtils::SharedExamples Accessor = CI::Reporter::TestUtils::Accessor - let(:report_path) { File.join(REPORTS_DIR, 'FEATURES-Example-Spinach-feature.xml') } - context "the feature" do + let(:report_path) { File.join(REPORTS_DIR, 'FEATURES-Example-Spinach-feature.xml') } subject(:result) { Accessor.new(load_xml_result(report_path)) } it { is_expected.to have(2).errors } @@ -65,6 +64,40 @@ end end + context "no feature definition found" do + let(:report_path) { File.join(REPORTS_DIR, 'FEATURES-Example-Spinach-no-feature.xml') } + subject(:result) { Accessor.new(load_xml_result(report_path)) } + + describe "scenario 1" do + subject(:testcase) { result.testcase('Scenario 1') } + + it { is_expected.to have(1).errors } + + describe "the failure" do + subject(:failure) { testcase.errors.first } + + it "has a type" do + expect(failure.type).to match /StandardError/ + end + end + end + + describe "Another scenario" do + subject(:testcase) { result.testcase('Another scenario') } + + it { is_expected.to have(1).errors } + + describe "the failure" do + subject(:failure) { testcase.errors.first } + + it "has a type" do + expect(failure.type).to match /StandardError/ + end + end + end + end + + def load_xml_result(path) File.open(path) do |f| REXML::Document.new(f) diff --git a/ci_reporter_spinach.gemspec b/ci_reporter_spinach.gemspec index 7430d49..5d32d15 100644 --- a/ci_reporter_spinach.gemspec +++ b/ci_reporter_spinach.gemspec @@ -18,7 +18,7 @@ Gem::Specification.new do |spec| spec.require_paths = ["lib"] spec.add_dependency "ci_reporter", "~> 2.0" - spec.add_dependency "spinach", "~> 0.8.7" + spec.add_dependency "spinach", ">= 0.8.7" spec.add_development_dependency "bundler", "~> 1.6" spec.add_development_dependency "rake" diff --git a/lib/ci/reporter/spinach.rb b/lib/ci/reporter/spinach.rb index d04b7fb..9292cd2 100644 --- a/lib/ci/reporter/spinach.rb +++ b/lib/ci/reporter/spinach.rb @@ -22,6 +22,18 @@ def before_scenario_run(scenario, step_definitions = nil) @test_case.start end + def on_feature_not_found(feature) + feature.scenarios.map do |scenario| + test_case = TestCase.new(scenario.name) + test_case.start + error = StandardError.new('Undefined feature') + error.set_backtrace([]) + test_case.failures << SpinachFailure.new(:error, feature, error, nil) + test_case.finish + @test_suite.testcases << test_case + end + end + def on_undefined_step(step, failure, step_definitions = nil) @test_case.failures << SpinachFailure.new(:error, step, failure, nil) end diff --git a/verification_spec.rb b/verification_spec.rb new file mode 100644 index 0000000..e114def --- /dev/null +++ b/verification_spec.rb @@ -0,0 +1,87 @@ +require 'rexml/document' +require 'ci/reporter/test_utils/accessor' +require 'ci/reporter/test_utils/shared_examples' +require 'rspec/collection_matchers' + +REPORTS_DIR = File.dirname(__FILE__) + '/reports' + +describe "Spinach acceptance" do + include CI::Reporter::TestUtils::SharedExamples + Accessor = CI::Reporter::TestUtils::Accessor + + context "scenario level failures" do + let(:report_path) { File.join(REPORTS_DIR, 'FEATURES-Example-Spinach-feature.xml') } + + subject(:result) { Accessor.new(load_xml_result(report_path)) } + + it { is_expected.to have(2).errors } + it { is_expected.to have(1).failures } + it { is_expected.to have(4).testcases } + + it_behaves_like "a report with consistent attribute counts" + it_behaves_like "assertions are not tracked" + it_behaves_like "nothing was output" + + describe "the test the lazy hacker wrote" do + subject(:testcase) { result.testcase('Lazy hacker') } + + it { is_expected.to have(1).failures } + + describe "the failure" do + subject(:failure) { testcase.failures.first } + + it "has a type" do + expect(failure.type).to match /ExpectationNotMetError/ + end + end + end + + describe "the test with missing steps" do + subject(:testcase) { result.testcase('Missing steps') } + + it { is_expected.to have(1).errors } + + describe "the failure" do + subject(:failure) { testcase.errors.first } + + it "has a type" do + expect(failure.type).to match /StepNotDefinedException/ + end + end + end + + describe "the test the bad coder wrote" do + subject(:testcase) { result.testcase('Bad coder') } + + it { is_expected.to have(1).errors } + + describe "the failure" do + subject(:failure) { testcase.errors.first } + + it "has a type" do + expect(failure.type).to match /RuntimeError/ + end + end + end + end + + context "feature level failures" do + let(:report_path) { File.join(REPORTS_DIR, 'FEATURES-Example-Spinach-no-feature.xml') } + subject(:result) { Accessor.new(load_xml_result(report_path)) } + + describe "the failure" do + let(:testcase) { result.testcase('Conscientious developer') } + let(:failure) { testcase.errors.first } + + it "has a type" do + expect(failure.type).to match /StepNotDefinedException/ + end + end + end + + def load_xml_result(path) + File.open(path) do |f| + REXML::Document.new(f) + end + end +end