ci_reporter 2.0.0.alpha2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9d4fd920bd59773352edb9dd239cb99ffe419406
4
- data.tar.gz: 227712fdcd966fa2b57d5a32133e5e0587a89e03
3
+ metadata.gz: fe5f8b66682882d6a356567fcf2b9683fe5f529a
4
+ data.tar.gz: 7831002dd54de23d55414b03bfad33061d2c3359
5
5
  SHA512:
6
- metadata.gz: 094edf36eb8b168fb606a2a2ad73ea9bf3e49a078934462ff95d2b07a27f49038291789b162807fe8395f49d237887edd0926f983a1848b100e0d150ff9e2266
7
- data.tar.gz: bdde115c27717e95030df44d1accd7d79b38ba8230895faa0d13409cb4b721444efc79615241dd599e7e0ad25ada12777cad0247783d43428954a1d1298e2dd1
6
+ metadata.gz: b41cf605637d2974bb44f18698b80e682d863bae095751b4ac50f1349df7ea363a6346e4ff06e88e6ce1884c641f8277c8dac4a23240baec930157f27c791a98
7
+ data.tar.gz: 8bc3f23ee5b19300109a141a086fa64da41b0a0c647991c91b68a56adb16edb4114f8a3a8c9b46312ddb677548563e6fe378c044bb6de119553561ea477a6390
@@ -1,3 +1,13 @@
1
+ == 2.0.0 (2014-07-24)
2
+
3
+ === Changed
4
+
5
+ - Gem has been refactored into multiple framework-specific gems.
6
+
7
+ === Removed
8
+
9
+ - All methods of use except the `ci:setup:*` Rake tasks.
10
+
1
11
  == 1.9.2 (04/06/14)
2
12
 
3
13
  - GH #119: add timestamp attribute (Shawn Zhu)
data/README.md CHANGED
@@ -30,10 +30,21 @@ Each supported testing framework is provided by a separate gem:
30
30
  [ci-spin]: https://github.com/ci-reporter/ci_reporter_spinach
31
31
  [ci-tu]: https://github.com/ci-reporter/ci_reporter_test_unit
32
32
 
33
+ ### Upgrading from CI::Reporter 1.x
34
+
35
+ CI::Reporter 1.x supported all the different test frameworks in a
36
+ single gem. This was convienient, but caused issues as test frameworks
37
+ released new, sometimes incompatibile, versions. CI::Reporter 2.x has
38
+ been split into multiple gems, allowing each gem to specify the test
39
+ framework versions it supports.
40
+
41
+ To upgrade to 2.x, remove `ci_reporter` from your Gemfile and replace
42
+ it with one or more of the framework-specific gems above.
43
+
33
44
  ## Jenkins setup
34
45
 
35
- 1. Tick the box labelled "Publish JUnit test result report" in the job
36
- configuration
46
+ 1. Add the "Publish JUnit test result report" post-build step
47
+ in the job configuration.
37
48
 
38
49
  2. Enter "test/reports/*.xml,spec/reports/*.xml" in the "Test report
39
50
  XMLs" field (adjust this to suit which tests you are running)
@@ -24,5 +24,5 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_development_dependency "rake"
26
26
  spec.add_development_dependency "rdoc", "~> 4.0"
27
- spec.add_development_dependency "rspec", "~> 2.0"
27
+ spec.add_development_dependency "rspec", "~> 3.0"
28
28
  end
@@ -0,0 +1,31 @@
1
+ require 'delegate'
2
+ require 'stringio'
3
+
4
+ module CI
5
+ module Reporter
6
+ # Captures $stdout or $stderr in order report it in the XML file.
7
+ class OutputCapture
8
+ # Creates an OutputCapture and immediately starts capturing.
9
+ def self.wrap(io, &assign)
10
+ new(io, &assign).tap {|oc| oc.start}
11
+ end
12
+
13
+ def initialize(io, &assign)
14
+ @original_io = io
15
+ @captured_io = StringIO.new
16
+ @assign_block = assign
17
+ end
18
+
19
+ # Start capturing IO.
20
+ def start
21
+ @assign_block.call(@captured_io)
22
+ end
23
+
24
+ # Finalize the capture and reset to the original IO object.
25
+ def finish
26
+ @assign_block.call(@original_io)
27
+ @captured_io.string
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,50 +1,32 @@
1
- require 'delegate'
2
- require 'stringio'
3
1
  require 'time'
2
+ require 'builder'
3
+ require 'ci/reporter/output_capture'
4
4
 
5
5
  module CI
6
6
  module Reporter
7
- # Emulates/delegates IO to $stdout or $stderr in order to capture output to report in the XML file.
8
- module OutputCapture
9
- class Delegate < DelegateClass(IO)
10
- include OutputCapture
11
- def initialize(io, &assign)
12
- super(io)
13
- capture(io, &assign)
14
- end
7
+ module StructureXmlHelpers
8
+ # Struct#to_h is not available in Ruby 1.9
9
+ def attr_hash
10
+ Hash[self.members.zip(self.values)]
15
11
  end
16
12
 
17
- def self.wrap(io, &assign)
18
- Delegate.new(io, &assign)
13
+ # Removes empty attributes and truncates long attributes.
14
+ def cleaned_attributes
15
+ attr_array = attr_hash
16
+ .reject {|k,v| v.to_s.empty? }
17
+ .map {|k,v| [k, truncate_at_newline(v)] }
18
+ Hash[attr_array]
19
19
  end
20
20
 
21
- # Start capturing IO, using the given block to assign self to the proper IO global.
22
- def capture(io, &assign)
23
- @delegate_io = io
24
- @captured_io = StringIO.new
25
- @assign_block = assign
26
- @assign_block.call @captured_io
27
- end
28
-
29
- # Finalize the capture and reset to the original IO object.
30
- def finish
31
- @assign_block.call @delegate_io
32
- @captured_io.string
33
- end
34
-
35
- # setup tee methods
36
- %w(<< print printf putc puts write).each do |m|
37
- module_eval(<<-EOS, __FILE__, __LINE__)
38
- def #{m}(*args, &block)
39
- @delegate_io.send(:#{m}, *args, &block)
40
- @captured_io.send(:#{m}, *args, &block)
41
- end
42
- EOS
21
+ def truncate_at_newline(txt)
22
+ txt.to_s.sub(/\n.*/m, '...')
43
23
  end
44
24
  end
45
25
 
46
26
  # Basic structure representing the running of a test suite. Used to time tests and store results.
47
27
  class TestSuite < Struct.new(:name, :tests, :time, :failures, :errors, :skipped, :assertions, :timestamp)
28
+ include StructureXmlHelpers
29
+
48
30
  attr_accessor :testcases
49
31
  attr_accessor :stdout, :stderr
50
32
  def initialize(name)
@@ -66,39 +48,30 @@ module CI
66
48
  self.tests = testcases.size
67
49
  self.time = Time.now - @start
68
50
  self.timestamp = @start.iso8601
69
- self.failures = testcases.inject(0) {|sum,tc| sum += tc.failures.select{|f| f.failure? }.size }
70
- self.errors = testcases.inject(0) {|sum,tc| sum += tc.failures.select{|f| f.error? }.size }
71
- self.skipped = testcases.inject(0) {|sum,tc| sum += (tc.skipped? ? 1 : 0) }
51
+ self.failures = testcases.map(&:failure_count).reduce(&:+)
52
+ self.errors = testcases.map(&:error_count).reduce(&:+)
53
+ self.skipped = testcases.count(&:skipped?)
72
54
  self.stdout = @capture_out.finish if @capture_out
73
55
  self.stderr = @capture_err.finish if @capture_err
74
56
  end
75
57
 
76
- # Creates the xml builder instance used to create the report xml document.
77
- def create_builder
78
- require 'builder'
79
- # :escape_attrs is obsolete in a newer version, but should do no harm
80
- Builder::XmlMarkup.new(:indent => 2, :escape_attrs => true)
81
- end
82
-
83
58
  # Creates an xml string containing the test suite results.
84
59
  def to_xml
85
- builder = create_builder
86
- # more recent version of Builder doesn't need the escaping
87
- def builder.trunc!(txt)
88
- txt.sub(/\n.*/m, '...')
89
- end
60
+ builder = Builder::XmlMarkup.new(indent: 2)
90
61
  builder.instruct!
91
- attrs = {}
92
- each_pair {|k,v| attrs[k] = builder.trunc!(v.to_s) unless v.nil? || v.to_s.empty? }
93
- builder.testsuite(attrs) do
62
+ builder.testsuite(cleaned_attributes) do
94
63
  @testcases.each do |tc|
95
64
  tc.to_xml(builder)
96
65
  end
97
- builder.tag! "system-out" do
98
- builder.text!(self.stdout || '' )
66
+ unless self.stdout.to_s.empty?
67
+ builder.tag! "system-out" do
68
+ builder.text!(self.stdout)
69
+ end
99
70
  end
100
- builder.tag! "system-err" do
101
- builder.text!(self.stderr || '' )
71
+ unless self.stderr.to_s.empty?
72
+ builder.tag! "system-err" do
73
+ builder.text!(self.stderr)
74
+ end
102
75
  end
103
76
  end
104
77
  end
@@ -106,6 +79,8 @@ module CI
106
79
 
107
80
  # Structure used to represent an individual test case. Used to time the test and store the result.
108
81
  class TestCase < Struct.new(:name, :time, :assertions)
82
+ include StructureXmlHelpers
83
+
109
84
  attr_accessor :failures
110
85
  attr_accessor :skipped
111
86
 
@@ -126,12 +101,20 @@ module CI
126
101
 
127
102
  # Returns non-nil if the test failed.
128
103
  def failure?
129
- !failures.empty? && failures.detect {|f| f.failure? }
104
+ failures.any?(&:failure?)
130
105
  end
131
106
 
132
107
  # Returns non-nil if the test had an error.
133
108
  def error?
134
- !failures.empty? && failures.detect {|f| f.error? }
109
+ failures.any?(&:error?)
110
+ end
111
+
112
+ def failure_count
113
+ failures.count(&:failure?)
114
+ end
115
+
116
+ def error_count
117
+ failures.count(&:error?)
135
118
  end
136
119
 
137
120
  def skipped?
@@ -140,16 +123,14 @@ module CI
140
123
 
141
124
  # Writes xml representing the test result to the provided builder.
142
125
  def to_xml(builder)
143
- attrs = {}
144
- each_pair {|k,v| attrs[k] = builder.trunc!(v.to_s) unless v.nil? || v.to_s.empty?}
145
- builder.testcase(attrs) do
126
+ builder.testcase(cleaned_attributes) do
146
127
  if skipped?
147
128
  builder.skipped
148
129
  else
149
130
  failures.each do |failure|
150
131
  tag = failure.error? ? :error : :failure
151
132
 
152
- builder.tag!(tag, :type => builder.trunc!(failure.name), :message => builder.trunc!(failure.message)) do
133
+ builder.tag!(tag, type: truncate_at_newline(failure.name), message: truncate_at_newline(failure.message)) do
153
134
  builder.text!(failure.message + " (#{failure.name})\n")
154
135
  builder.text!(failure.location)
155
136
  end
@@ -1,5 +1,5 @@
1
1
  module CI
2
2
  module Reporter
3
- VERSION = "2.0.0.alpha2"
3
+ VERSION = "2.0.0"
4
4
  end
5
5
  end
@@ -2,59 +2,67 @@ require File.dirname(__FILE__) + "/../../spec_helper.rb"
2
2
  require 'rexml/document'
3
3
 
4
4
  describe "Output capture" do
5
- before(:each) do
6
- @suite = CI::Reporter::TestSuite.new "test"
7
- end
5
+ subject(:suite) { CI::Reporter::TestSuite.new "test" }
8
6
 
9
- it "should save stdout and stderr messages written during the test run" do
10
- @suite.start
7
+ it "saves stdout and stderr messages written during the test run" do
8
+ suite.start
11
9
  puts "Hello"
12
10
  $stderr.print "Hi"
13
- @suite.finish
14
- @suite.stdout.should == "Hello\n"
15
- @suite.stderr.should == "Hi"
11
+ suite.finish
12
+ expect(suite.stdout).to eql "Hello\n"
13
+ expect(suite.stderr).to eql "Hi"
16
14
  end
17
15
 
18
- it "should include system-out and system-err elements in the xml output" do
19
- @suite.start
16
+ it "includes system-out and system-err elements in the xml output" do
17
+ suite.start
20
18
  puts "Hello"
21
19
  $stderr.print "Hi"
22
- @suite.finish
20
+ suite.finish
23
21
 
24
- root = REXML::Document.new(@suite.to_xml).root
25
- root.elements.to_a('//system-out').length.should == 1
26
- root.elements.to_a('//system-err').length.should == 1
27
- root.elements.to_a('//system-out').first.texts.first.to_s.strip.should == "Hello"
28
- root.elements.to_a('//system-err').first.texts.first.to_s.strip.should == "Hi"
22
+ root = REXML::Document.new(suite.to_xml).root
23
+ expect(root.elements.to_a('//system-out').length).to eql 1
24
+ expect(root.elements.to_a('//system-err').length).to eql 1
25
+ expect(root.elements.to_a('//system-out').first.texts.first.to_s.strip).to eql "Hello"
26
+ expect(root.elements.to_a('//system-err').first.texts.first.to_s.strip).to eql "Hi"
29
27
  end
30
28
 
31
- it "should return $stdout and $stderr to original value after finish" do
32
- out, err = $stdout, $stderr
33
- @suite.start
34
- $stdout.object_id.should_not == out.object_id
35
- $stderr.object_id.should_not == err.object_id
36
- @suite.finish
37
- $stdout.object_id.should == out.object_id
38
- $stderr.object_id.should == err.object_id
29
+ it "does not include system-out or system-err elements if nothing was output" do
30
+ suite.start
31
+ suite.finish
32
+
33
+ root = REXML::Document.new(suite.to_xml).root
34
+ expect(root.elements.to_a('//system-out').length).to eql 0
35
+ expect(root.elements.to_a('//system-err').length).to eql 0
39
36
  end
40
37
 
41
- it "should capture only during run of owner test suite" do
38
+ it "captures only during run of owner test suite" do
42
39
  $stdout.print "A"
43
40
  $stderr.print "A"
44
- @suite.start
41
+ suite.start
45
42
  $stdout.print "B"
46
43
  $stderr.print "B"
47
- @suite.finish
44
+ suite.finish
48
45
  $stdout.print "C"
49
46
  $stderr.print "C"
50
- @suite.stdout.should == "B"
51
- @suite.stderr.should == "B"
47
+ expect(suite.stdout).to eql "B"
48
+ expect(suite.stderr).to eql "B"
52
49
  end
53
50
 
54
- it "should not barf when commands are executed with back-ticks" do
55
- @suite.start
56
- `echo "B"`
57
- @suite.finish
58
- end
51
+ describe CI::Reporter::OutputCapture do
52
+ subject(:capture) { CI::Reporter::OutputCapture.new($stdout) {|x| $stdout = x } }
59
53
 
54
+ it "returns the IO to the original value after finish" do
55
+ original = $stdout
56
+ capture.start
57
+ expect($stdout.object_id).to_not eql original.object_id
58
+ capture.finish
59
+ expect($stdout.object_id).to eql original.object_id
60
+ end
61
+
62
+ it "does not barf when commands are executed with back-ticks" do
63
+ capture.start
64
+ `echo "B"`
65
+ capture.finish
66
+ end
67
+ end
60
68
  end
@@ -1,75 +1,77 @@
1
1
  require File.dirname(__FILE__) + "/../../spec_helper.rb"
2
2
 
3
- describe "The ReportManager" do
4
- before(:each) do
5
- @reports_dir = REPORTS_DIR
6
- ENV.delete 'MAX_FILENAME_SIZE'
7
- end
3
+ module CI::Reporter
4
+ describe ReportManager do
5
+ before(:each) do
6
+ @reports_dir = REPORTS_DIR
7
+ ENV.delete 'MAX_FILENAME_SIZE'
8
+ end
8
9
 
9
- after(:each) do
10
- FileUtils.rm_rf @reports_dir
11
- ENV["CI_REPORTS"] = nil
12
- end
10
+ after(:each) do
11
+ FileUtils.rm_rf @reports_dir
12
+ ENV["CI_REPORTS"] = nil
13
+ end
13
14
 
14
- it "should create the report directory according to the given prefix" do
15
- CI::Reporter::ReportManager.new("spec")
16
- File.directory?(@reports_dir).should be true
17
- end
15
+ it "creates the report directory according to the given prefix" do
16
+ CI::Reporter::ReportManager.new("spec")
17
+ expect(File.directory?(@reports_dir)).to be true
18
+ end
18
19
 
19
- it "should create the report directory based on CI_REPORTS environment variable if set" do
20
- @reports_dir = "#{Dir.getwd}/dummy"
21
- ENV["CI_REPORTS"] = @reports_dir
22
- CI::Reporter::ReportManager.new("spec")
23
- File.directory?(@reports_dir).should be true
24
- end
20
+ it "creates the report directory based on CI_REPORTS environment variable if set" do
21
+ @reports_dir = "#{Dir.getwd}/dummy"
22
+ ENV["CI_REPORTS"] = @reports_dir
23
+ CI::Reporter::ReportManager.new("spec")
24
+ expect(File.directory?(@reports_dir)).to be true
25
+ end
25
26
 
26
- it "should write reports based on name and xml content of a test suite" do
27
- reporter = CI::Reporter::ReportManager.new("spec")
28
- suite = double("test suite")
29
- suite.should_receive(:name).and_return("some test suite name")
30
- suite.should_receive(:to_xml).and_return("<xml></xml>")
31
- reporter.write_report(suite)
32
- filename = "#{REPORTS_DIR}/SPEC-some-test-suite-name.xml"
33
- File.exist?(filename).should be true
34
- File.open(filename) {|f| f.read.should == "<xml></xml>"}
35
- end
27
+ it "writes reports based on name and xml content of a test suite" do
28
+ reporter = CI::Reporter::ReportManager.new("spec")
29
+ suite = double("test suite")
30
+ expect(suite).to receive(:name).and_return("some test suite name")
31
+ expect(suite).to receive(:to_xml).and_return("<xml></xml>")
32
+ reporter.write_report(suite)
33
+ filename = "#{REPORTS_DIR}/SPEC-some-test-suite-name.xml"
34
+ expect(File.exist?(filename)).to be true
35
+ expect(File.read(filename)).to eql "<xml></xml>"
36
+ end
36
37
 
37
- it "should shorten extremely long report filenames" do
38
- reporter = CI::Reporter::ReportManager.new("spec")
39
- suite = double("test suite")
40
- very_long_name = "some test suite name that goes on and on and on and on and on and on and does not look like it will end any time soon and just when you think it is almost over it just continues to go on and on and on and on and on until it is almost over but wait there is more and then el fin"
41
- suite.should_receive(:name).and_return(very_long_name)
42
- suite.should_receive(:to_xml).and_return("<xml></xml>")
43
- reporter.write_report(suite)
44
- filename = "#{REPORTS_DIR}/SPEC-#{very_long_name}"[0..CI::Reporter::ReportManager::MAX_FILENAME_SIZE].gsub(/\s/, '-') + ".xml"
45
- filename.length.should be <= 255
46
- File.exist?(filename).should be true
47
- File.open(filename) {|f| f.read.should == "<xml></xml>"}
48
- end
38
+ it "shortens extremely long report filenames" do
39
+ reporter = CI::Reporter::ReportManager.new("spec")
40
+ suite = double("test suite")
41
+ very_long_name = "some test suite name that goes on and on and on and on and on and on and does not look like it will end any time soon and just when you think it is almost over it just continues to go on and on and on and on and on until it is almost over but wait there is more and then el fin"
42
+ expect(suite).to receive(:name).and_return(very_long_name)
43
+ expect(suite).to receive(:to_xml).and_return("<xml></xml>")
44
+ reporter.write_report(suite)
45
+ filename = "#{REPORTS_DIR}/SPEC-#{very_long_name}"[0..CI::Reporter::ReportManager::MAX_FILENAME_SIZE].gsub(/\s/, '-') + ".xml"
46
+ expect(filename.length).to be <= 255
47
+ expect(File.exist?(filename)).to be true
48
+ expect(File.read(filename)).to eql "<xml></xml>"
49
+ end
49
50
 
50
- it "should shorten extremely long report filenames to custom length" do
51
- reporter = CI::Reporter::ReportManager.new("spec")
52
- suite = double("test suite")
53
- very_long_name = "some test suite name that goes on and on and on and on and on and on and does not look like it will end any time soon and just when you think it is almost over it just continues to go on and on and on and on and on until it is almost over but wait there is more and then el fin"
54
- suite.should_receive(:name).and_return(very_long_name)
55
- suite.should_receive(:to_xml).and_return("<xml></xml>")
56
- ENV['MAX_FILENAME_SIZE'] = '170'
57
- reporter.write_report(suite)
58
- filename = "#{REPORTS_DIR}/SPEC-#{very_long_name}"[0..170].gsub(/\s/, '-') + ".xml"
59
- filename.length.should be <= 188
60
- File.exist?(filename).should be true
61
- File.open(filename) {|f| f.read.should == "<xml></xml>"}
62
- end
51
+ it "shortens extremely long report filenames to custom length" do
52
+ reporter = CI::Reporter::ReportManager.new("spec")
53
+ suite = double("test suite")
54
+ very_long_name = "some test suite name that goes on and on and on and on and on and on and does not look like it will end any time soon and just when you think it is almost over it just continues to go on and on and on and on and on until it is almost over but wait there is more and then el fin"
55
+ expect(suite).to receive(:name).and_return(very_long_name)
56
+ expect(suite).to receive(:to_xml).and_return("<xml></xml>")
57
+ ENV['MAX_FILENAME_SIZE'] = '170'
58
+ reporter.write_report(suite)
59
+ filename = "#{REPORTS_DIR}/SPEC-#{very_long_name}"[0..170].gsub(/\s/, '-') + ".xml"
60
+ expect(filename.length).to be <= 188
61
+ expect(File.exist?(filename)).to be true
62
+ expect(File.read(filename)).to eql "<xml></xml>"
63
+ end
63
64
 
64
- it "sidesteps existing files by adding an incrementing number" do
65
- filename = "#{REPORTS_DIR}/SPEC-colliding-test-suite-name.xml"
66
- FileUtils.mkdir_p(File.dirname(filename))
67
- FileUtils.touch filename
68
- reporter = CI::Reporter::ReportManager.new("spec")
69
- suite = double("test suite")
70
- suite.should_receive(:name).and_return("colliding test suite name")
71
- suite.should_receive(:to_xml).and_return("<xml></xml>")
72
- reporter.write_report(suite)
73
- File.exist?(filename.sub('.xml', '.0.xml')).should be true
65
+ it "sidesteps existing files by adding an incrementing number" do
66
+ filename = "#{REPORTS_DIR}/SPEC-colliding-test-suite-name.xml"
67
+ FileUtils.mkdir_p(File.dirname(filename))
68
+ FileUtils.touch filename
69
+ reporter = CI::Reporter::ReportManager.new("spec")
70
+ suite = double("test suite")
71
+ expect(suite).to receive(:name).and_return("colliding test suite name")
72
+ expect(suite).to receive(:to_xml).and_return("<xml></xml>")
73
+ reporter.write_report(suite)
74
+ expect(File.exist?(filename.sub('.xml', '.0.xml'))).to be true
75
+ end
74
76
  end
75
77
  end
@@ -1,157 +1,152 @@
1
1
  require File.dirname(__FILE__) + "/../../spec_helper.rb"
2
2
  require 'rexml/document'
3
3
 
4
- describe "A TestSuite" do
5
- before(:each) do
6
- @suite = CI::Reporter::TestSuite.new("example suite")
7
- end
8
-
9
- it "should collect timings when start and finish are invoked in sequence" do
10
- @suite.start
11
- @suite.finish
12
- @suite.time.should >= 0
13
- end
14
-
15
- it "should aggregate tests" do
16
- @suite.start
17
- @suite.testcases << CI::Reporter::TestCase.new("example test")
18
- @suite.finish
19
- @suite.tests.should == 1
20
- end
4
+ module CI::Reporter
5
+ describe TestSuite do
6
+ subject(:suite) { CI::Reporter::TestSuite.new("example suite") }
7
+
8
+ let(:exception) do
9
+ begin
10
+ raise StandardError, "an exception occurred"
11
+ rescue => e
12
+ e
13
+ end
14
+ end
21
15
 
22
- it "should stringify the name for cases when the object passed in is not a string" do
23
- name = Object.new
24
- def name.to_s; "object name"; end
25
- CI::Reporter::TestSuite.new(name).name.should == "object name"
26
- end
16
+ let(:failure) do
17
+ double("failure",
18
+ :failure? => true,
19
+ :error? => false,
20
+ :name => "failure",
21
+ :message => "There was a failure",
22
+ :location => exception.backtrace.join("\n"))
23
+ end
27
24
 
28
- it "should indicate number of failures and errors" do
29
- failure = double("failure")
30
- failure.stub(:failure?).and_return true
31
- failure.stub(:error?).and_return false
32
-
33
- error = double("error")
34
- error.stub(:failure?).and_return false
35
- error.stub(:error?).and_return true
36
-
37
- @suite.start
38
- @suite.testcases << CI::Reporter::TestCase.new("example test")
39
- @suite.testcases << CI::Reporter::TestCase.new("failure test")
40
- @suite.testcases.last.failures << failure
41
- @suite.testcases << CI::Reporter::TestCase.new("error test")
42
- @suite.testcases.last.failures << error
43
- @suite.finish
44
- @suite.tests.should == 3
45
- @suite.failures.should == 1
46
- @suite.errors.should == 1
47
- end
48
- end
25
+ let(:error) do
26
+ double("error",
27
+ :failure? => false,
28
+ :error? => true,
29
+ :name => "error",
30
+ :message => "There was a error",
31
+ :location => exception.backtrace.join("\n"))
32
+ end
49
33
 
50
- describe "TestSuite xml" do
51
- before(:each) do
52
- ENV['CI_CAPTURE'] = nil
53
- @suite = CI::Reporter::TestSuite.new("example suite")
54
- @suite.assertions = 11
55
- begin
56
- raise StandardError, "an exception occurred"
57
- rescue => e
58
- @exception = e
34
+ it "collects timings when start and finish are invoked in sequence" do
35
+ suite.start
36
+ suite.finish
37
+ expect(suite.time).to be >= 0
59
38
  end
60
- end
61
39
 
62
- it "should render successfully with CI_CAPTURE off" do
63
- ENV['CI_CAPTURE'] = 'off'
64
- @suite.start
65
- @suite.testcases << CI::Reporter::TestCase.new("example test")
66
- @suite.finish
67
- xml = @suite.to_xml
68
- end
40
+ it "aggregates tests" do
41
+ suite.start
42
+ suite.testcases << CI::Reporter::TestCase.new("example test")
43
+ suite.finish
44
+ expect(suite.tests).to eql 1
45
+ end
69
46
 
70
- it "should contain Ant/JUnit-formatted description of entire suite" do
71
- failure = double("failure")
72
- failure.stub(:failure?).and_return true
73
- failure.stub(:error?).and_return false
74
- failure.stub(:name).and_return "failure"
75
- failure.stub(:message).and_return "There was a failure"
76
- failure.stub(:location).and_return @exception.backtrace.join("\n")
77
-
78
- error = double("error")
79
- error.stub(:failure?).and_return false
80
- error.stub(:error?).and_return true
81
- error.stub(:name).and_return "error"
82
- error.stub(:message).and_return "There was a error"
83
- error.stub(:location).and_return @exception.backtrace.join("\n")
84
-
85
- @suite.start
86
- @suite.testcases << CI::Reporter::TestCase.new("example test")
87
- @suite.testcases << CI::Reporter::TestCase.new("skipped test").tap {|tc| tc.skipped = true }
88
- @suite.testcases << CI::Reporter::TestCase.new("failure test")
89
- @suite.testcases.last.failures << failure
90
- @suite.testcases << CI::Reporter::TestCase.new("error test")
91
- @suite.testcases.last.failures << error
92
- @suite.finish
93
-
94
- xml = @suite.to_xml
95
- doc = REXML::Document.new(xml)
96
- testsuite = doc.root.elements.to_a("/testsuite")
97
- testsuite.length.should == 1
98
- testsuite = testsuite.first
99
- testsuite.attributes["name"].should == "example suite"
100
- testsuite.attributes["assertions"].should == "11"
101
- testsuite.attributes["timestamp"].should match(/(\d{4})-(\d{2})-(\d{2})T(\d{2})\:(\d{2})\:(\d{2})[+-](\d{2})\:(\d{2})/)
102
-
103
- testcases = testsuite.elements.to_a("testcase")
104
- testcases.length.should == 4
105
- end
47
+ it "stringifies the name for cases when the object passed in is not a string" do
48
+ name = Object.new
49
+ def name.to_s; "object name"; end
50
+ expect(CI::Reporter::TestSuite.new(name).name).to eql "object name"
51
+ end
106
52
 
107
- it "should contain full exception type and message in location element" do
108
- failure = double("failure")
109
- failure.stub(:failure?).and_return true
110
- failure.stub(:error?).and_return false
111
- failure.stub(:name).and_return "failure"
112
- failure.stub(:message).and_return "There was a failure"
113
- failure.stub(:location).and_return @exception.backtrace.join("\n")
114
-
115
- @suite.start
116
- @suite.testcases << CI::Reporter::TestCase.new("example test")
117
- @suite.testcases << CI::Reporter::TestCase.new("failure test")
118
- @suite.testcases.last.failures << failure
119
- @suite.finish
120
-
121
- xml = @suite.to_xml
122
- doc = REXML::Document.new(xml)
123
- elem = doc.root.elements.to_a("/testsuite/testcase[@name='failure test']/failure").first
124
- location = elem.texts.join
125
- location.should =~ Regexp.new(failure.message)
126
- location.should =~ Regexp.new(failure.name)
127
- end
53
+ it "indicates number of failures and errors" do
54
+ suite.start
55
+ suite.testcases << CI::Reporter::TestCase.new("example test")
56
+ suite.testcases << CI::Reporter::TestCase.new("failure test")
57
+ suite.testcases.last.failures << failure
58
+ suite.testcases << CI::Reporter::TestCase.new("error test")
59
+ suite.testcases.last.failures << error
60
+ suite.finish
61
+ expect(suite.tests).to eql 3
62
+ expect(suite.failures).to eql 1
63
+ expect(suite.errors).to eql 1
64
+ end
128
65
 
129
- it "should filter attributes properly for invalid characters" do
130
- failure = double("failure")
131
- failure.stub(:failure?).and_return true
132
- failure.stub(:error?).and_return false
133
- failure.stub(:name).and_return "failure"
134
- failure.stub(:message).and_return "There was a <failure>\nReason: blah"
135
- failure.stub(:location).and_return @exception.backtrace.join("\n")
136
-
137
- @suite.start
138
- @suite.testcases << CI::Reporter::TestCase.new("failure test")
139
- @suite.testcases.last.failures << failure
140
- @suite.finish
141
-
142
- xml = @suite.to_xml
143
- xml.should =~ %r/message="There was a &lt;failure&gt;\.\.\."/
66
+ context "xml" do
67
+ let(:suite) { CI::Reporter::TestSuite.new("example suite") }
68
+
69
+ before(:each) do
70
+ ENV['CI_CAPTURE'] = nil
71
+ suite.assertions = 11
72
+ end
73
+
74
+ after(:each) do
75
+ ENV['CI_CAPTURE'] = nil
76
+ end
77
+
78
+ it "renders successfully with CI_CAPTURE off" do
79
+ ENV['CI_CAPTURE'] = 'off'
80
+ suite.start
81
+ suite.testcases << CI::Reporter::TestCase.new("example test")
82
+ suite.finish
83
+ xml = suite.to_xml
84
+ end
85
+
86
+ it "contains Ant/JUnit-formatted description of entire suite" do
87
+ suite.start
88
+ suite.testcases << CI::Reporter::TestCase.new("example test")
89
+ suite.testcases << CI::Reporter::TestCase.new("skipped test").tap {|tc| tc.skipped = true }
90
+ suite.testcases << CI::Reporter::TestCase.new("failure test")
91
+ suite.testcases.last.failures << failure
92
+ suite.testcases << CI::Reporter::TestCase.new("error test")
93
+ suite.testcases.last.failures << error
94
+ suite.finish
95
+
96
+ xml = suite.to_xml
97
+ doc = REXML::Document.new(xml)
98
+ testsuite = doc.root.elements.to_a("/testsuite")
99
+ expect(testsuite.length).to eql 1
100
+ testsuite = testsuite.first
101
+ expect(testsuite.attributes["name"]).to eql "example suite"
102
+ expect(testsuite.attributes["assertions"]).to eql "11"
103
+ expect(testsuite.attributes["timestamp"]).to match(/(\d{4})-(\d{2})-(\d{2})T(\d{2})\:(\d{2})\:(\d{2})[+-](\d{2})\:(\d{2})/)
104
+
105
+ testcases = testsuite.elements.to_a("testcase")
106
+ expect(testcases.length).to eql 4
107
+ end
108
+
109
+ it "contains full exception type and message in location element" do
110
+ suite.start
111
+ suite.testcases << CI::Reporter::TestCase.new("example test")
112
+ suite.testcases << CI::Reporter::TestCase.new("failure test")
113
+ suite.testcases.last.failures << failure
114
+ suite.finish
115
+
116
+ xml = suite.to_xml
117
+ doc = REXML::Document.new(xml)
118
+ elem = doc.root.elements.to_a("/testsuite/testcase[@name='failure test']/failure").first
119
+ location = elem.texts.join
120
+ expect(location).to match Regexp.new(failure.message)
121
+ expect(location).to match Regexp.new(failure.name)
122
+ end
123
+
124
+ it "filters attributes properly for invalid characters" do
125
+ failure = double("failure",
126
+ :failure? => true,
127
+ :error? => false,
128
+ :name => "failure",
129
+ :message => "There was a <failure>\nReason: blah",
130
+ :location => exception.backtrace.join("\n"))
131
+
132
+ suite.start
133
+ suite.testcases << CI::Reporter::TestCase.new("failure test")
134
+ suite.testcases.last.failures << failure
135
+ suite.finish
136
+
137
+ xml = suite.to_xml
138
+ expect(xml).to match %r/message="There was a &lt;failure&gt;\.\.\."/
139
+ end
140
+ end
144
141
  end
145
- end
146
142
 
147
- describe "A TestCase" do
148
- before(:each) do
149
- @tc = CI::Reporter::TestCase.new("example test")
150
- end
143
+ describe TestCase do
144
+ subject(:tc) { TestCase.new("example test") }
151
145
 
152
- it "should collect timings when start and finish are invoked in sequence" do
153
- @tc.start
154
- @tc.finish
155
- @tc.time.should >= 0
146
+ it "collects timings when start and finish are invoked in sequence" do
147
+ tc.start
148
+ tc.finish
149
+ expect(tc.time).to be >= 0
150
+ end
156
151
  end
157
152
  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: 2.0.0.alpha2
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sieger
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-06-30 00:00:00.000000000 Z
12
+ date: 2014-07-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: builder
@@ -59,14 +59,14 @@ dependencies:
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '2.0'
62
+ version: '3.0'
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: '2.0'
69
+ version: '3.0'
70
70
  description: CI::Reporter is an add-on to Ruby testing frameworks that allows you
71
71
  to generate XML reports of your test runs. The resulting files can be read by a
72
72
  continuous integration system that understands Ant's JUnit report format.
@@ -91,6 +91,7 @@ files:
91
91
  - ci_reporter.gemspec
92
92
  - gemfiles/.gitignore
93
93
  - lib/ci/reporter/core.rb
94
+ - lib/ci/reporter/output_capture.rb
94
95
  - lib/ci/reporter/rake/utils.rb
95
96
  - lib/ci/reporter/report_manager.rb
96
97
  - lib/ci/reporter/test_suite.rb
@@ -114,9 +115,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
114
115
  version: '0'
115
116
  required_rubygems_version: !ruby/object:Gem::Requirement
116
117
  requirements:
117
- - - ">"
118
+ - - ">="
118
119
  - !ruby/object:Gem::Version
119
- version: 1.3.1
120
+ version: '0'
120
121
  requirements: []
121
122
  rubyforge_project:
122
123
  rubygems_version: 2.2.2