ci_reporter 1.5.3 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ == 1.6.0
2
+
3
+ - Add support for Cucumber (tested against 0.3.0 - 0.3.2); (Graeme Mathieson)
4
+
1
5
  == 1.5.3
2
6
 
3
7
  - Compatibility with latest RSpec (1.2.4); (Paul Boone)
data/Manifest.txt CHANGED
@@ -5,6 +5,9 @@ LICENSE.txt
5
5
  Rakefile
6
6
  stub.rake
7
7
  lib/ci/reporter/core.rb
8
+ lib/ci/reporter/cucumber.rb
9
+ lib/ci/reporter/rake/cucumber.rb
10
+ lib/ci/reporter/rake/cucumber_loader.rb
8
11
  lib/ci/reporter/rake/rspec.rb
9
12
  lib/ci/reporter/rake/rspec_loader.rb
10
13
  lib/ci/reporter/rake/test_unit.rb
@@ -14,6 +17,7 @@ lib/ci/reporter/rspec.rb
14
17
  lib/ci/reporter/test_suite.rb
15
18
  lib/ci/reporter/test_unit.rb
16
19
  lib/ci/reporter/version.rb
20
+ spec/ci/reporter/cucumber_spec.rb
17
21
  spec/ci/reporter/output_capture_spec.rb
18
22
  spec/ci/reporter/rake/rake_tasks_spec.rb
19
23
  spec/ci/reporter/report_manager_spec.rb
data/README.txt CHANGED
@@ -1,4 +1,4 @@
1
- CI::Reporter is an add-on to Test::Unit and RSpec that allows you to generate XML reports of your test and/or spec runs. The resulting files can be read by a continuous integration system that understands Ant's JUnit report XML format, thus allowing your CI system to track test/spec successes and failures.
1
+ CI::Reporter is an add-on to Test::Unit, RSpec and Cucumber that allows you to generate XML reports of your test, spec and/or feature runs. The resulting files can be read by a continuous integration system that understands Ant's JUnit report XML format, thus allowing your CI system to track test/spec successes and failures.
2
2
 
3
3
  == Dependencies
4
4
 
@@ -22,14 +22,15 @@ CI::Reporter works best with projects that use a +Rakefile+ along with the stand
22
22
 
23
23
  require 'rubygems'
24
24
  gem 'ci_reporter'
25
- require 'ci/reporter/rake/rspec' # use this if you're using RSpec
25
+ require 'ci/reporter/rake/rspec' # use this if you're using RSpec
26
+ require 'ci/reporter/rake/cucumber' # use this if you're using Cucumber
26
27
  require 'ci/reporter/rake/test_unit' # use this if you're using Test::Unit
27
28
 
28
- 2. Next, either modify your Rakefile to make the <code>ci:setup:rspec</code> or <code>ci:setup:testunit</code> task a dependency of your test tasks, or include them on the Rake command-line before the name of the task that runs the tests or specs.
29
+ 2. Next, either modify your Rakefile to make the <code>ci:setup:rspec</code>, <code>ci:setup:cucumber</code> or <code>ci:setup:testunit</code> task a dependency of your test tasks, or include them on the Rake command-line before the name of the task that runs the tests or specs.
29
30
 
30
31
  rake ci:setup:testunit test
31
32
 
32
- Report files are written, by default, to the <code>test/reports</code> or <code>spec/reports</code> subdirectory of your project. If you wish to customize the location, simply set the environment variable CI_REPORTS (either in the environment, on the Rake command line, or in your Rakefile) to the location where they should go.
33
+ Report files are written, by default, to the <code>test/reports</code>, <code>features/reports</code> or <code>spec/reports</code> subdirectory of your project. If you wish to customize the location, simply set the environment variable CI_REPORTS (either in the environment, on the Rake command line, or in your Rakefile) to the location where they should go.
33
34
 
34
35
  == Advanced Usage
35
36
 
@@ -37,14 +38,21 @@ If you don't have control over the Rakefile or don't want to modify it, CI::Repo
37
38
 
38
39
  rake -f GEM_PATH/stub.rake ci:setup:testunit test
39
40
  rake -f GEM_PATH/stub.rake ci:setup:rspec spec
41
+ rake -f GEM_PATH/stub.rake ci:setup:cucumber features
40
42
 
41
43
  If for some reason you can't use the above technique to inject CI::Reporter (e.g., you're not using Rake), you'll have to do one of these:
42
44
 
43
45
  1. If you're using <code>Test::Unit</code>, ensure the <code>ci/reporter/rake/test_unit_loader.rb</code> file is loaded or required at some point before the tests are run.
46
+
44
47
  2. If you're using +RSpec+, you'll need to pass the following arguments to the +spec+ command:
48
+
45
49
  --require GEM_PATH/lib/ci/reporter/rake/rspec_loader
46
50
  --format CI::Reporter::RSpec
47
51
 
52
+ 3. If you're using Cucumber, you'll need to cheat slightly so that Cucumber's step definition autoloading will still work. Instead of calling the +cucumber+ script directly, run:
53
+
54
+ ruby -r GEM_PATH/lib/ci/reporter/rake/cucumber_loader -S cucumber --format CI::Reporter::Cucumber
55
+
48
56
  There's a bit of a chicken and egg problem because rubygems needs to be loaded before you can require any CI::Reporter files. If you cringe hard-coding a full path to a specific version of the gem, you can also copy the +rspec_loader+ file into your project and require it directly -- the contents are version-agnostic and are not likely to change in future releases.
49
57
 
50
58
  == Environment Variables
data/Rakefile CHANGED
@@ -58,11 +58,12 @@ end
58
58
  task :rcov => "spec:rcov"
59
59
 
60
60
  task :generate_output do
61
- rm_f "acceptance/reports/*.xml"
61
+ rm_rf "acceptance/reports"
62
62
  ENV['CI_REPORTS'] = "acceptance/reports"
63
63
  begin
64
64
  `ruby -Ilib acceptance/test_unit_example_test.rb` rescue nil
65
65
  `ruby -Ilib -S spec --require ci/reporter/rake/rspec_loader --format CI::Reporter::RSpec acceptance/rspec_example_spec.rb` rescue nil
66
+ `ruby -Ilib -rci/reporter/rake/cucumber_loader -S cucumber --format CI::Reporter::Cucumber acceptance/cucumber` rescue nil
66
67
  ensure
67
68
  ENV.delete 'CI_REPORTS'
68
69
  end
@@ -0,0 +1,99 @@
1
+ # (c) Copyright 2006-2009 Nick Sieger <nicksieger@gmail.com>
2
+ # See the file LICENSE.txt included with the distribution for
3
+ # software license details.
4
+
5
+ require 'ci/reporter/core'
6
+ tried_gem = false
7
+ begin
8
+ require 'cucumber'
9
+ require 'cucumber/ast/visitor'
10
+ rescue LoadError
11
+ unless tried_gem
12
+ tried_gem = true
13
+ require 'rubygems'
14
+ gem 'cucumber'
15
+ retry
16
+ end
17
+ end
18
+
19
+ module CI
20
+ module Reporter
21
+ class CucumberFailure
22
+ attr_reader :step
23
+
24
+ def initialize(step)
25
+ @step = step
26
+ end
27
+
28
+ def failure?
29
+ true
30
+ end
31
+
32
+ def error?
33
+ !failure?
34
+ end
35
+
36
+ def name
37
+ step.exception.class.name
38
+ end
39
+
40
+ def message
41
+ step.exception.message
42
+ end
43
+
44
+ def location
45
+ step.exception.backtrace.join("\n")
46
+ end
47
+ end
48
+
49
+ class Cucumber < ::Cucumber::Ast::Visitor
50
+
51
+ attr_accessor :test_suite, :report_manager, :feature_name
52
+
53
+ def initialize(step_mother, io, options)
54
+ self.report_manager = ReportManager.new("features")
55
+ super(step_mother)
56
+ end
57
+
58
+ def visit_feature_name(name)
59
+ self.feature_name = name.split("\n").first
60
+ super
61
+ end
62
+
63
+ def visit_feature_element(feature_element)
64
+ self.test_suite = TestSuite.new("#{feature_name} #{feature_element.instance_variable_get("@name")}")
65
+ test_suite.start
66
+
67
+ return_value = super
68
+
69
+ test_suite.finish
70
+ report_manager.write_report(test_suite)
71
+ self.test_suite = nil
72
+
73
+ return_value
74
+ end
75
+
76
+ def visit_step(step)
77
+ test_case = TestCase.new(step.name)
78
+ test_case.start
79
+
80
+ return_value = super
81
+
82
+ test_case.finish
83
+
84
+ case step.status
85
+ when :pending, :undefined
86
+ test_case.name = "#{test_case.name} (PENDING)"
87
+ when :skipped
88
+ test_case.name = "#{test_case.name} (SKIPPED)"
89
+ when :failed
90
+ test_case.failures << CucumberFailure.new(step)
91
+ end
92
+
93
+ test_suite.testcases << test_case
94
+
95
+ return_value
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,17 @@
1
+ # (c) Copyright 2006-2007 Nick Sieger <nicksieger@gmail.com>
2
+ # See the file LICENSE.txt included with the distribution for
3
+ # software license details.
4
+
5
+ namespace :ci do
6
+ namespace :setup do
7
+ task :cucumber_report_cleanup do
8
+ rm_rf ENV["CI_REPORTS"] || "features/reports"
9
+ end
10
+
11
+ task :cucumber => :cucumber_report_cleanup do
12
+ spec_opts = ["--require", "#{File.dirname(__FILE__)}/cucumber_loader.rb",
13
+ "--format", "CI::Reporter::Cucumber"].join(" ")
14
+ ENV["CUCUMBER_OPTS"] = "#{ENV['CUCUMBER_OPTS']} #{spec_opts}"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ # (c) Copyright 2006-2007 Nick Sieger <nicksieger@gmail.com>
2
+ # See the file LICENSE.txt included with the distribution for
3
+ # software license details.
4
+
5
+ $: << File.dirname(__FILE__) + "/../../.."
6
+ require 'ci/reporter/cucumber'
@@ -1,5 +1,5 @@
1
1
  module CI
2
2
  module Reporter
3
- VERSION = "1.5.3"
3
+ VERSION = "1.6.0"
4
4
  end
5
5
  end
@@ -0,0 +1,204 @@
1
+ # (c) Copyright 2006-2008 Nick Sieger <nicksieger@gmail.com>
2
+ # See the file LICENSE.txt included with the distribution for
3
+ # software license details.
4
+
5
+ require File.dirname(__FILE__) + "/../../spec_helper.rb"
6
+ require 'ci/reporter/cucumber'
7
+
8
+ describe "The Cucumber reporter" do
9
+ describe CI::Reporter::CucumberFailure do
10
+ before(:each) do
11
+ @klass = mock("class")
12
+ @klass.stub!(:name).and_return("Exception name")
13
+
14
+ @exception = mock("exception")
15
+ @exception.stub!(:class).and_return(@klass)
16
+ @exception.stub!(:message).and_return("Exception message")
17
+ @exception.stub!(:backtrace).and_return(["First line", "Second line"])
18
+
19
+ @step = mock("step")
20
+ @step.stub!(:exception).and_return(@exception)
21
+
22
+ @cucumber_failure = CI::Reporter::CucumberFailure.new(@step)
23
+ end
24
+
25
+ it "should always return true for failure?" do
26
+ @cucumber_failure.should be_failure
27
+ end
28
+
29
+ it "should always return false for error?" do
30
+ @cucumber_failure.should_not be_error
31
+ end
32
+
33
+ it "should propagate the name as the underlying exception's class name" do
34
+ @step.should_receive(:exception)
35
+ @exception.should_receive(:class)
36
+ @klass.should_receive(:name)
37
+
38
+ @cucumber_failure.name.should == "Exception name"
39
+ end
40
+
41
+ it "should propagate the message as the underlying exception's message" do
42
+ @step.should_receive(:exception)
43
+ @exception.should_receive(:message)
44
+
45
+ @cucumber_failure.message.should == "Exception message"
46
+ end
47
+
48
+ it "should propagate and format the exception's backtrace" do
49
+ @step.should_receive(:exception)
50
+ @exception.should_receive(:backtrace)
51
+
52
+ @cucumber_failure.location.should == "First line\nSecond line"
53
+ end
54
+ end
55
+
56
+ describe CI::Reporter::Cucumber do
57
+ before(:each) do
58
+ @step_mother = mock("step_mother")
59
+ @io = mock("io")
60
+
61
+ @report_manager = mock("report_manager")
62
+ CI::Reporter::ReportManager.stub!(:new).and_return(@report_manager)
63
+ end
64
+
65
+ def new_instance
66
+ CI::Reporter::Cucumber.new(@step_mother, @io, {})
67
+ end
68
+
69
+ it "should create a new report manager to report on test success/failure" do
70
+ CI::Reporter::ReportManager.should_receive(:new)
71
+ new_instance
72
+ end
73
+
74
+ it "should record the feature name when a new feature is visited" do
75
+ cucumber = new_instance
76
+ cucumber.visit_feature_name("Some feature name")
77
+ cucumber.feature_name.should == "Some feature name"
78
+ end
79
+
80
+ it "should record only the first line of a feature name" do
81
+ cucumber = new_instance
82
+ cucumber.visit_feature_name("Some feature name\nLonger description")
83
+ cucumber.feature_name.should == "Some feature name"
84
+ end
85
+
86
+ describe "when visiting a new scenario" do
87
+ before(:each) do
88
+ @cucumber = new_instance
89
+ @cucumber.visit_feature_name("Demo feature")
90
+
91
+ @test_suite = mock("test_suite", :start => nil, :finish => nil)
92
+ CI::Reporter::TestSuite.stub!(:new).and_return(@test_suite)
93
+
94
+ @feature_element = mock("feature_element", :accept => true)
95
+
96
+ @report_manager.stub!(:write_report)
97
+ end
98
+
99
+ it "should create a new test suite" do
100
+ # FIXME: @name is feature_element purely as a by-product of the
101
+ # mocking framework implementation. But then again, using
102
+ # +instance_variable_get+ in the first place is a bit icky.
103
+ CI::Reporter::TestSuite.should_receive(:new).with("Demo feature feature_element")
104
+ @cucumber.visit_feature_element(@feature_element)
105
+ end
106
+
107
+ it "should indicate that the test suite has started" do
108
+ @test_suite.should_receive(:start)
109
+ @cucumber.visit_feature_element(@feature_element)
110
+ end
111
+
112
+ it "should indicate that the test suite has finished" do
113
+ @test_suite.should_receive(:finish)
114
+ @cucumber.visit_feature_element(@feature_element)
115
+ end
116
+
117
+ it "should ask the report manager to write a report" do
118
+ @report_manager.should_receive(:write_report).with(@test_suite)
119
+ @cucumber.visit_feature_element(@feature_element)
120
+ end
121
+ end
122
+
123
+ describe "when visiting a step inside a scenario" do
124
+ before(:each) do
125
+ @testcases = []
126
+
127
+ @test_suite = mock("test_suite", :testcases => @testcases)
128
+
129
+ @cucumber = new_instance
130
+ @cucumber.stub!(:test_suite).and_return(@test_suite)
131
+
132
+ @test_case = mock("test_case", :start => nil, :finish => nil, :name => "Step Name")
133
+ CI::Reporter::TestCase.stub!(:new).and_return(@test_case)
134
+
135
+ @step = mock("step", :accept => true, :status => :passed)
136
+ @step.stub!(:name).and_return("Step Name")
137
+ end
138
+
139
+ it "should create a new test case" do
140
+ CI::Reporter::TestCase.should_receive(:new).with("Step Name")
141
+ @cucumber.visit_step(@step)
142
+ end
143
+
144
+ it "should indicate that the test case has started" do
145
+ @test_case.should_receive(:start)
146
+ @cucumber.visit_step(@step)
147
+ end
148
+
149
+ it "should indicate that the test case has finished" do
150
+ @test_case.should_receive(:finish)
151
+ @cucumber.visit_step(@step)
152
+ end
153
+
154
+ it "should add the test case to the suite's list of cases" do
155
+ @testcases.should be_empty
156
+ @cucumber.visit_step(@step)
157
+ @testcases.should_not be_empty
158
+ @testcases.first.should == @test_case
159
+ end
160
+
161
+ it "should alter the name of a test case that is pending to include '(PENDING)'" do
162
+ @step.stub!(:status).and_return(:pending)
163
+ @test_case.should_receive(:name=).with("Step Name (PENDING)")
164
+ @cucumber.visit_step(@step)
165
+ end
166
+
167
+ it "should alter the name of a test case that is undefined to include '(PENDING)'" do
168
+ @step.stub!(:status).and_return(:undefined)
169
+ @test_case.should_receive(:name=).with("Step Name (PENDING)")
170
+ @cucumber.visit_step(@step)
171
+ end
172
+
173
+ it "should alter the name of a test case that was skipped to include '(SKIPPED)'" do
174
+ @step.stub!(:status).and_return(:skipped)
175
+ @test_case.should_receive(:name=).with("Step Name (SKIPPED)")
176
+ @cucumber.visit_step(@step)
177
+ end
178
+
179
+ describe "that fails" do
180
+ before(:each) do
181
+ @step.stub!(:status).and_return(:failed)
182
+
183
+ @failures = []
184
+ @test_case.stub!(:failures).and_return(@failures)
185
+
186
+ @cucumber_failure = mock("cucumber_failure")
187
+ CI::Reporter::CucumberFailure.stub!(:new).and_return(@cucumber_failure)
188
+ end
189
+
190
+ it "should create a new cucumber failure with that step" do
191
+ CI::Reporter::CucumberFailure.should_receive(:new).with(@step)
192
+ @cucumber.visit_step(@step)
193
+ end
194
+
195
+ it "should add the failure to the suite's list of failures" do
196
+ @failures.should be_empty
197
+ @cucumber.visit_step(@step)
198
+ @failures.should_not be_empty
199
+ @failures.first.should == @cucumber_failure
200
+ end
201
+ end
202
+ end
203
+ end
204
+ end
@@ -71,3 +71,30 @@ describe "ci_reporter ci:setup:rspec task" do
71
71
  ENV["SPEC_OPTS"].should =~ /somevalue.*--require.*rspec_loader.*--format.*CI::Reporter::RSpec/
72
72
  end
73
73
  end
74
+
75
+ describe "ci_reporter ci:setup:cucumber task" do
76
+ before(:each) do
77
+ @rake = Rake::Application.new
78
+ Rake.application = @rake
79
+ load CI_REPORTER_LIB + '/ci/reporter/rake/cucumber.rb'
80
+ save_env "CI_REPORTS"
81
+ save_env "CUCUMBER_OPTS"
82
+ ENV["CI_REPORTS"] = "some-bogus-nonexistent-directory-that-wont-fail-rm_rf"
83
+ end
84
+ after(:each) do
85
+ restore_env "CUCUMBER_OPTS"
86
+ restore_env "CI_REPORTS"
87
+ Rake.application = nil
88
+ end
89
+
90
+ it "should set ENV['CUCUMBER_OPTS'] to include cucumber formatter args" do
91
+ @rake["ci:setup:cucumber"].invoke
92
+ ENV["CUCUMBER_OPTS"].should =~ /--require.*cucumber_loader.*--format.*CI::Reporter::Cucumber/
93
+ end
94
+
95
+ it "should append to ENV['CUCUMBER_OPTS'] if it already contains a value" do
96
+ ENV["CUCUMBER_OPTS"] = "somevalue".freeze
97
+ @rake["ci:setup:cucumber"].invoke
98
+ ENV["CUCUMBER_OPTS"].should =~ /somevalue.*--require.*cucumber_loader.*--format.*CI::Reporter::Cucumber/
99
+ end
100
+ end
data/stub.rake CHANGED
@@ -9,5 +9,6 @@
9
9
  #
10
10
 
11
11
  load File.dirname(__FILE__) + '/lib/ci/reporter/rake/rspec.rb'
12
+ load File.dirname(__FILE__) + '/lib/ci/reporter/rake/cucumber.rb'
12
13
  load File.dirname(__FILE__) + '/lib/ci/reporter/rake/test_unit.rb'
13
14
  load 'Rakefile'
@@ -4,13 +4,15 @@
4
4
 
5
5
  begin
6
6
  gem 'ci_reporter'
7
- rescue
7
+ rescue Gem::LoadError
8
8
  $: << File.dirname(__FILE__) + "/../lib"
9
9
  end
10
10
  require 'ci/reporter/rake/rspec'
11
+ require 'ci/reporter/rake/cucumber'
11
12
  require 'ci/reporter/rake/test_unit'
12
13
 
13
14
  namespace :ci do
14
15
  task :setup_rspec => "ci:setup:rspec"
16
+ task :setup_cucumber => "ci:setup:cucumber"
15
17
  task :setup_testunit => "ci:setup:testunit"
16
18
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ci_reporter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.3
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sieger
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-18 00:00:00 -05:00
12
+ date: 2009-05-05 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,7 +22,7 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: 2.1.2
24
24
  version:
25
- description: CI::Reporter is an add-on to Test::Unit and RSpec that allows you to generate XML reports of your test and/or spec runs. The resulting files can be read by a continuous integration system that understands Ant's JUnit report XML format, thus allowing your CI system to track test/spec successes and failures.
25
+ description: CI::Reporter is an add-on to Test::Unit, RSpec and Cucumber that allows you to generate XML reports of your test, spec and/or feature runs. The resulting files can be read by a continuous integration system that understands Ant's JUnit report XML format, thus allowing your CI system to track test/spec successes and failures.
26
26
  email: nick@nicksieger.com
27
27
  executables: []
28
28
 
@@ -41,6 +41,9 @@ files:
41
41
  - Rakefile
42
42
  - stub.rake
43
43
  - lib/ci/reporter/core.rb
44
+ - lib/ci/reporter/cucumber.rb
45
+ - lib/ci/reporter/rake/cucumber.rb
46
+ - lib/ci/reporter/rake/cucumber_loader.rb
44
47
  - lib/ci/reporter/rake/rspec.rb
45
48
  - lib/ci/reporter/rake/rspec_loader.rb
46
49
  - lib/ci/reporter/rake/test_unit.rb
@@ -50,6 +53,7 @@ files:
50
53
  - lib/ci/reporter/test_suite.rb
51
54
  - lib/ci/reporter/test_unit.rb
52
55
  - lib/ci/reporter/version.rb
56
+ - spec/ci/reporter/cucumber_spec.rb
53
57
  - spec/ci/reporter/output_capture_spec.rb
54
58
  - spec/ci/reporter/rake/rake_tasks_spec.rb
55
59
  - spec/ci/reporter/report_manager_spec.rb
@@ -86,6 +90,7 @@ signing_key:
86
90
  specification_version: 2
87
91
  summary: CI::Reporter allows you to generate reams of XML for use with continuous integration systems.
88
92
  test_files:
93
+ - spec/ci/reporter/cucumber_spec.rb
89
94
  - spec/ci/reporter/output_capture_spec.rb
90
95
  - spec/ci/reporter/rake/rake_tasks_spec.rb
91
96
  - spec/ci/reporter/report_manager_spec.rb