ci_reporter 2.0.0.alpha2 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yaml +27 -0
- data/.github/workflows/release.yaml +41 -0
- data/History.txt +25 -0
- data/README.md +18 -8
- data/Rakefile +0 -1
- data/ci_reporter.gemspec +2 -1
- data/lib/ci/reporter/monotonic_time.rb +22 -0
- data/lib/ci/reporter/output_capture.rb +31 -0
- data/lib/ci/reporter/report_manager.rb +2 -2
- data/lib/ci/reporter/test_suite.rb +52 -67
- data/lib/ci/reporter/version.rb +1 -1
- data/spec/ci/reporter/output_capture_spec.rb +42 -34
- data/spec/ci/reporter/report_manager_spec.rb +66 -64
- data/spec/ci/reporter/test_suite_spec.rb +136 -141
- metadata +25 -10
- data/.travis.yml +0 -5
- data/gemfiles/.gitignore +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a528a2fafebcc8be684a8ca7dc12acef432ac82dec567d5b1176bdfdb5377ffb
|
4
|
+
data.tar.gz: 97d80b1b12e409a0d9ad4d5a9592800a30492b41050787c43a16d86128687167
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af641871ec70d11f86d1afa32590d848a8e3118bb5fd494f07005f8f97421242f365c74197e6cee1b606b4c817622539b5b9d4df4e65449c4c8f745d8c49dafc
|
7
|
+
data.tar.gz: e9cbaff5e0ec53a727791a81645282653ac8d29ed68e0970bc454d5c84b05bf170adb4b1ce5f1a8cd2f895b0adfaba9b07ae9a72c34b5115aae12a7189ce8907
|
@@ -0,0 +1,27 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- main
|
7
|
+
pull_request:
|
8
|
+
branches:
|
9
|
+
- main
|
10
|
+
|
11
|
+
jobs:
|
12
|
+
test:
|
13
|
+
name: test
|
14
|
+
strategy:
|
15
|
+
matrix:
|
16
|
+
ruby: ['2.6', '2.7', '3.0', '3.1', '3.2', head, jruby, jruby-head]
|
17
|
+
runs-on: ubuntu-latest
|
18
|
+
steps:
|
19
|
+
- uses: actions/checkout@v3
|
20
|
+
- uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{ matrix.ruby }}
|
23
|
+
bundler-cache: true
|
24
|
+
- name: Tests
|
25
|
+
run: bundle exec rake
|
26
|
+
- name: Gem build
|
27
|
+
run: bundle exec rake build
|
@@ -0,0 +1,41 @@
|
|
1
|
+
name: Release
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
tags:
|
6
|
+
- "v[0-9]+.[0-9]+.[0-9]+"
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
release:
|
10
|
+
name: release
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
steps:
|
13
|
+
- uses: actions/checkout@v3
|
14
|
+
|
15
|
+
- uses: ruby/setup-ruby@v1
|
16
|
+
with:
|
17
|
+
ruby-version: '3.2'
|
18
|
+
bundler-cache: true
|
19
|
+
|
20
|
+
- name: Log into Rubygems
|
21
|
+
run: |
|
22
|
+
mkdir -p ~/.local/share/gem
|
23
|
+
echo ":rubygems_api_key: ${{ secrets.RUBYGEMS_API_KEY }}" > ~/.local/share/gem/credentials
|
24
|
+
chmod 600 ~/.local/share/gem/credentials
|
25
|
+
|
26
|
+
- name: Release
|
27
|
+
run: |
|
28
|
+
set -e
|
29
|
+
PKG="$(echo *.gemspec | sed 's/.gemspec//')"
|
30
|
+
VERSION="${GITHUB_REF#refs/tags/v}"
|
31
|
+
bundle exec rake build
|
32
|
+
GEM="pkg/$PKG-$VERSION.gem"
|
33
|
+
if [ -f "$GEM" ]; then
|
34
|
+
gem push $GEM
|
35
|
+
echo "Release $VERSION done."
|
36
|
+
else
|
37
|
+
echo "Build did not create a $VERSION release gem."
|
38
|
+
echo "Please check the version in the gemspec and try again."
|
39
|
+
cat *.gemspec | grep '\.version'
|
40
|
+
exit 1
|
41
|
+
fi
|
data/History.txt
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
== 2.1.0 (2023/02/09)
|
2
|
+
|
3
|
+
=== Changed
|
4
|
+
|
5
|
+
- Testing on Ruby 2.6 - HEAD, JRuby 9.x latest, JRuby HEAD
|
6
|
+
- CI changed to GitHub Actions
|
7
|
+
- Tracking branch changed to `main`
|
8
|
+
- GH #160: Add monotonic time (Michal Cichra)
|
9
|
+
- GH #148: fix deprecation issues (Akira Matsuda)
|
10
|
+
- GH #149: fix for RSpec 3.1.2 (Akira Matsuda)
|
11
|
+
|
12
|
+
=== Removed
|
13
|
+
|
14
|
+
- Testing on versions of Ruby < 2.6
|
15
|
+
|
16
|
+
== 2.0.0 (2014-07-24)
|
17
|
+
|
18
|
+
=== Changed
|
19
|
+
|
20
|
+
- Gem has been refactored into multiple framework-specific gems.
|
21
|
+
|
22
|
+
=== Removed
|
23
|
+
|
24
|
+
- All methods of use except the `ci:setup:*` Rake tasks.
|
25
|
+
|
1
26
|
== 1.9.2 (04/06/14)
|
2
27
|
|
3
28
|
- GH #119: add timestamp attribute (Shawn Zhu)
|
data/README.md
CHANGED
@@ -5,8 +5,7 @@ system that understands Ant's JUnit report XML format, thus allowing
|
|
5
5
|
your CI system to track test/spec successes and failures.
|
6
6
|
|
7
7
|
[![Gem Version](https://badge.fury.io/rb/ci_reporter.svg)](http://badge.fury.io/rb/ci_reporter)
|
8
|
-
[![Build Status](https://
|
9
|
-
[![Dependency Status](https://gemnasium.com/ci-reporter/ci_reporter.svg)](https://gemnasium.com/ci-reporter/ci_reporter)
|
8
|
+
[![Build Status](https://github.com/ci-reporter/ci_reporter/actions/workflows/ci.yaml/badge.svg)](https://github.com/ci-reporter/ci_reporter/actions/workflows/ci.yaml)
|
10
9
|
[![Code Climate](https://codeclimate.com/github/ci-reporter/ci_reporter.png)](https://codeclimate.com/github/ci-reporter/ci_reporter)
|
11
10
|
|
12
11
|
## Usage
|
@@ -30,12 +29,23 @@ Each supported testing framework is provided by a separate gem:
|
|
30
29
|
[ci-spin]: https://github.com/ci-reporter/ci_reporter_spinach
|
31
30
|
[ci-tu]: https://github.com/ci-reporter/ci_reporter_test_unit
|
32
31
|
|
32
|
+
### Upgrading from CI::Reporter 1.x
|
33
|
+
|
34
|
+
CI::Reporter 1.x supported all the different test frameworks in a
|
35
|
+
single gem. This was convenient, but caused issues as test frameworks
|
36
|
+
released new, sometimes incompatibile, versions. CI::Reporter 2.x has
|
37
|
+
been split into multiple gems, allowing each gem to specify the test
|
38
|
+
framework versions it supports.
|
39
|
+
|
40
|
+
To upgrade to 2.x, remove `ci_reporter` from your Gemfile and replace
|
41
|
+
it with one or more of the framework-specific gems above.
|
42
|
+
|
33
43
|
## Jenkins setup
|
34
44
|
|
35
|
-
1.
|
36
|
-
configuration
|
45
|
+
1. Add the "Publish JUnit test result report" post-build step
|
46
|
+
in the job configuration.
|
37
47
|
|
38
|
-
2. Enter "test/reports
|
48
|
+
2. Enter "test/reports/\*.xml,spec/reports/\*.xml" in the "Test report
|
39
49
|
XMLs" field (adjust this to suit which tests you are running)
|
40
50
|
|
41
51
|
Report files are written, by default, to the
|
@@ -58,7 +68,7 @@ will be invoked:
|
|
58
68
|
```ruby
|
59
69
|
if ENV['GENERATE_REPORTS'] == 'true'
|
60
70
|
require 'ci/reporter/rake/rspec'
|
61
|
-
task :
|
71
|
+
task :spec => 'ci:setup:rspec'
|
62
72
|
end
|
63
73
|
```
|
64
74
|
|
@@ -66,7 +76,7 @@ You can either inject this variable in your CI or simply call `rake`
|
|
66
76
|
with the environment variable set:
|
67
77
|
|
68
78
|
```
|
69
|
-
GENERATE_REPORTS=true rake
|
79
|
+
GENERATE_REPORTS=true rake spec
|
70
80
|
```
|
71
81
|
|
72
82
|
### With CI-specific Rake tasks
|
@@ -75,7 +85,7 @@ Instead of modifying your existing Rake tasks, create new ones:
|
|
75
85
|
|
76
86
|
```ruby
|
77
87
|
namespace :ci do
|
78
|
-
task :all => ['ci:setup:rspec', '
|
88
|
+
task :all => ['ci:setup:rspec', 'spec']
|
79
89
|
end
|
80
90
|
```
|
81
91
|
|
data/Rakefile
CHANGED
data/ci_reporter.gemspec
CHANGED
@@ -21,8 +21,9 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.extra_rdoc_files = ["History.txt", "LICENSE.txt", "README.md"]
|
22
22
|
|
23
23
|
spec.add_dependency "builder", ">= 2.1.2"
|
24
|
+
spec.add_dependency "rexml"
|
24
25
|
|
25
26
|
spec.add_development_dependency "rake"
|
26
27
|
spec.add_development_dependency "rdoc", "~> 4.0"
|
27
|
-
spec.add_development_dependency "rspec", "~>
|
28
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
28
29
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module CI
|
2
|
+
module Reporter
|
3
|
+
module MonotonicTime
|
4
|
+
module_function
|
5
|
+
|
6
|
+
if defined?(Process::CLOCK_MONOTONIC)
|
7
|
+
def time_in_nanoseconds
|
8
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC, :nanosecond)
|
9
|
+
end
|
10
|
+
else
|
11
|
+
def time_in_nanoseconds
|
12
|
+
t = Time.now
|
13
|
+
t.to_i * 10 ** 9 + t.nsec
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def time_in_seconds
|
18
|
+
time_in_nanoseconds / 10 ** 9.0
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
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
|
@@ -31,7 +31,7 @@ module CI #:nodoc:
|
|
31
31
|
# with N < 100000, to prevent endless sidestep loops
|
32
32
|
MAX_SIDESTEPS = 100000
|
33
33
|
MAX_FILENAME_SIZE = 240
|
34
|
-
|
34
|
+
|
35
35
|
def filename_for(suite)
|
36
36
|
basename = "#{@basename}-#{suite.name.gsub(/[^a-zA-Z0-9]+/, '-')}"
|
37
37
|
suffix = "xml"
|
@@ -48,7 +48,7 @@ module CI #:nodoc:
|
|
48
48
|
# if the initial filename is already in use
|
49
49
|
# do sidesteps, beginning with SPEC-MailsController.0.xml
|
50
50
|
i = 0
|
51
|
-
while File.
|
51
|
+
while File.exist?(filename) && i < MAX_SIDESTEPS
|
52
52
|
filename = [basename, i, suffix].join(".")
|
53
53
|
i += 1
|
54
54
|
end
|
@@ -1,60 +1,46 @@
|
|
1
|
-
require 'delegate'
|
2
|
-
require 'stringio'
|
3
1
|
require 'time'
|
2
|
+
require 'builder'
|
3
|
+
require 'ci/reporter/output_capture'
|
4
|
+
require 'ci/reporter/monotonic_time'
|
4
5
|
|
5
6
|
module CI
|
6
7
|
module Reporter
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def initialize(io, &assign)
|
12
|
-
super(io)
|
13
|
-
capture(io, &assign)
|
14
|
-
end
|
8
|
+
module StructureXmlHelpers
|
9
|
+
# Struct#to_h is not available in Ruby 1.9
|
10
|
+
def attr_hash
|
11
|
+
Hash[self.members.zip(self.values)]
|
15
12
|
end
|
16
13
|
|
17
|
-
|
18
|
-
|
14
|
+
# Removes empty attributes and truncates long attributes.
|
15
|
+
def cleaned_attributes
|
16
|
+
attr_array = attr_hash
|
17
|
+
.reject {|k,v| v.to_s.empty? }
|
18
|
+
.map {|k,v| [k, truncate_at_newline(v)] }
|
19
|
+
Hash[attr_array]
|
19
20
|
end
|
20
21
|
|
21
|
-
|
22
|
-
|
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
|
22
|
+
def truncate_at_newline(txt)
|
23
|
+
txt.to_s.sub(/\n.*/m, '...')
|
43
24
|
end
|
44
25
|
end
|
45
26
|
|
46
27
|
# Basic structure representing the running of a test suite. Used to time tests and store results.
|
47
28
|
class TestSuite < Struct.new(:name, :tests, :time, :failures, :errors, :skipped, :assertions, :timestamp)
|
29
|
+
include StructureXmlHelpers
|
30
|
+
|
48
31
|
attr_accessor :testcases
|
49
32
|
attr_accessor :stdout, :stderr
|
50
33
|
def initialize(name)
|
51
34
|
super(name.to_s) # RSpec passes a "description" object instead of a string
|
52
35
|
@testcases = []
|
36
|
+
@capture_out = nil
|
37
|
+
@capture_err = nil
|
53
38
|
end
|
54
39
|
|
55
40
|
# Starts timing the test suite.
|
56
41
|
def start
|
57
|
-
@
|
42
|
+
@start_time = Time.now
|
43
|
+
@start = MonotonicTime.time_in_seconds
|
58
44
|
unless ENV['CI_CAPTURE'] == "off"
|
59
45
|
@capture_out = OutputCapture.wrap($stdout) {|io| $stdout = io }
|
60
46
|
@capture_err = OutputCapture.wrap($stderr) {|io| $stderr = io }
|
@@ -64,41 +50,32 @@ module CI
|
|
64
50
|
# Finishes timing the test suite.
|
65
51
|
def finish
|
66
52
|
self.tests = testcases.size
|
67
|
-
self.time =
|
68
|
-
self.timestamp = @
|
69
|
-
self.failures = testcases.
|
70
|
-
self.errors = testcases.
|
71
|
-
self.skipped = testcases.
|
53
|
+
self.time = MonotonicTime.time_in_seconds - @start
|
54
|
+
self.timestamp = @start_time.iso8601
|
55
|
+
self.failures = testcases.map(&:failure_count).reduce(&:+)
|
56
|
+
self.errors = testcases.map(&:error_count).reduce(&:+)
|
57
|
+
self.skipped = testcases.count(&:skipped?)
|
72
58
|
self.stdout = @capture_out.finish if @capture_out
|
73
59
|
self.stderr = @capture_err.finish if @capture_err
|
74
60
|
end
|
75
61
|
|
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
62
|
# Creates an xml string containing the test suite results.
|
84
63
|
def to_xml
|
85
|
-
builder =
|
86
|
-
# more recent version of Builder doesn't need the escaping
|
87
|
-
def builder.trunc!(txt)
|
88
|
-
txt.sub(/\n.*/m, '...')
|
89
|
-
end
|
64
|
+
builder = Builder::XmlMarkup.new(indent: 2)
|
90
65
|
builder.instruct!
|
91
|
-
|
92
|
-
each_pair {|k,v| attrs[k] = builder.trunc!(v.to_s) unless v.nil? || v.to_s.empty? }
|
93
|
-
builder.testsuite(attrs) do
|
66
|
+
builder.testsuite(cleaned_attributes) do
|
94
67
|
@testcases.each do |tc|
|
95
68
|
tc.to_xml(builder)
|
96
69
|
end
|
97
|
-
|
98
|
-
builder.
|
70
|
+
unless self.stdout.to_s.empty?
|
71
|
+
builder.tag! "system-out" do
|
72
|
+
builder.text!(self.stdout)
|
73
|
+
end
|
99
74
|
end
|
100
|
-
|
101
|
-
builder.
|
75
|
+
unless self.stderr.to_s.empty?
|
76
|
+
builder.tag! "system-err" do
|
77
|
+
builder.text!(self.stderr)
|
78
|
+
end
|
102
79
|
end
|
103
80
|
end
|
104
81
|
end
|
@@ -106,6 +83,8 @@ module CI
|
|
106
83
|
|
107
84
|
# Structure used to represent an individual test case. Used to time the test and store the result.
|
108
85
|
class TestCase < Struct.new(:name, :time, :assertions)
|
86
|
+
include StructureXmlHelpers
|
87
|
+
|
109
88
|
attr_accessor :failures
|
110
89
|
attr_accessor :skipped
|
111
90
|
|
@@ -116,22 +95,30 @@ module CI
|
|
116
95
|
|
117
96
|
# Starts timing the test.
|
118
97
|
def start
|
119
|
-
@start =
|
98
|
+
@start = MonotonicTime.time_in_seconds
|
120
99
|
end
|
121
100
|
|
122
101
|
# Finishes timing the test.
|
123
102
|
def finish
|
124
|
-
self.time =
|
103
|
+
self.time = MonotonicTime.time_in_seconds - @start
|
125
104
|
end
|
126
105
|
|
127
106
|
# Returns non-nil if the test failed.
|
128
107
|
def failure?
|
129
|
-
|
108
|
+
failures.any?(&:failure?)
|
130
109
|
end
|
131
110
|
|
132
111
|
# Returns non-nil if the test had an error.
|
133
112
|
def error?
|
134
|
-
|
113
|
+
failures.any?(&:error?)
|
114
|
+
end
|
115
|
+
|
116
|
+
def failure_count
|
117
|
+
failures.count(&:failure?)
|
118
|
+
end
|
119
|
+
|
120
|
+
def error_count
|
121
|
+
failures.count(&:error?)
|
135
122
|
end
|
136
123
|
|
137
124
|
def skipped?
|
@@ -140,16 +127,14 @@ module CI
|
|
140
127
|
|
141
128
|
# Writes xml representing the test result to the provided builder.
|
142
129
|
def to_xml(builder)
|
143
|
-
|
144
|
-
each_pair {|k,v| attrs[k] = builder.trunc!(v.to_s) unless v.nil? || v.to_s.empty?}
|
145
|
-
builder.testcase(attrs) do
|
130
|
+
builder.testcase(cleaned_attributes) do
|
146
131
|
if skipped?
|
147
132
|
builder.skipped
|
148
133
|
else
|
149
134
|
failures.each do |failure|
|
150
135
|
tag = failure.error? ? :error : :failure
|
151
136
|
|
152
|
-
builder.tag!(tag, :
|
137
|
+
builder.tag!(tag, type: truncate_at_newline(failure.name), message: truncate_at_newline(failure.message)) do
|
153
138
|
builder.text!(failure.message + " (#{failure.name})\n")
|
154
139
|
builder.text!(failure.location)
|
155
140
|
end
|
data/lib/ci/reporter/version.rb
CHANGED
@@ -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
|
-
|
6
|
-
@suite = CI::Reporter::TestSuite.new "test"
|
7
|
-
end
|
5
|
+
subject(:suite) { CI::Reporter::TestSuite.new "test" }
|
8
6
|
|
9
|
-
it "
|
10
|
-
|
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
|
-
|
14
|
-
|
15
|
-
|
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 "
|
19
|
-
|
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
|
-
|
20
|
+
suite.finish
|
23
21
|
|
24
|
-
root = REXML::Document.new(
|
25
|
-
root.elements.to_a('//system-out').length.
|
26
|
-
root.elements.to_a('//system-err').length.
|
27
|
-
root.elements.to_a('//system-out').first.texts.first.to_s.strip.
|
28
|
-
root.elements.to_a('//system-err').first.texts.first.to_s.strip.
|
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 "
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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 "
|
38
|
+
it "captures only during run of owner test suite" do
|
42
39
|
$stdout.print "A"
|
43
40
|
$stderr.print "A"
|
44
|
-
|
41
|
+
suite.start
|
45
42
|
$stdout.print "B"
|
46
43
|
$stderr.print "B"
|
47
|
-
|
44
|
+
suite.finish
|
48
45
|
$stdout.print "C"
|
49
46
|
$stderr.print "C"
|
50
|
-
|
51
|
-
|
47
|
+
expect(suite.stdout).to eql "B"
|
48
|
+
expect(suite.stderr).to eql "B"
|
52
49
|
end
|
53
50
|
|
54
|
-
|
55
|
-
|
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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
after(:each) do
|
11
|
+
FileUtils.rm_rf @reports_dir
|
12
|
+
ENV["CI_REPORTS"] = nil
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
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
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
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
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
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 <failure>\.\.\."/
|
139
|
+
end
|
140
|
+
end
|
144
141
|
end
|
145
|
-
end
|
146
142
|
|
147
|
-
describe
|
148
|
-
|
149
|
-
@tc = CI::Reporter::TestCase.new("example test")
|
150
|
-
end
|
143
|
+
describe TestCase do
|
144
|
+
subject(:tc) { TestCase.new("example test") }
|
151
145
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
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.
|
4
|
+
version: 2.1.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:
|
12
|
+
date: 2023-02-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: builder
|
@@ -25,6 +25,20 @@ dependencies:
|
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: 2.1.2
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rexml
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
28
42
|
- !ruby/object:Gem::Dependency
|
29
43
|
name: rake
|
30
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,14 +73,14 @@ dependencies:
|
|
59
73
|
requirements:
|
60
74
|
- - "~>"
|
61
75
|
- !ruby/object:Gem::Version
|
62
|
-
version: '
|
76
|
+
version: '3.0'
|
63
77
|
type: :development
|
64
78
|
prerelease: false
|
65
79
|
version_requirements: !ruby/object:Gem::Requirement
|
66
80
|
requirements:
|
67
81
|
- - "~>"
|
68
82
|
- !ruby/object:Gem::Version
|
69
|
-
version: '
|
83
|
+
version: '3.0'
|
70
84
|
description: CI::Reporter is an add-on to Ruby testing frameworks that allows you
|
71
85
|
to generate XML reports of your test runs. The resulting files can be read by a
|
72
86
|
continuous integration system that understands Ant's JUnit report format.
|
@@ -80,17 +94,19 @@ extra_rdoc_files:
|
|
80
94
|
- LICENSE.txt
|
81
95
|
- README.md
|
82
96
|
files:
|
97
|
+
- ".github/workflows/ci.yaml"
|
98
|
+
- ".github/workflows/release.yaml"
|
83
99
|
- ".gitignore"
|
84
100
|
- ".rspec"
|
85
|
-
- ".travis.yml"
|
86
101
|
- Gemfile
|
87
102
|
- History.txt
|
88
103
|
- LICENSE.txt
|
89
104
|
- README.md
|
90
105
|
- Rakefile
|
91
106
|
- ci_reporter.gemspec
|
92
|
-
- gemfiles/.gitignore
|
93
107
|
- lib/ci/reporter/core.rb
|
108
|
+
- lib/ci/reporter/monotonic_time.rb
|
109
|
+
- lib/ci/reporter/output_capture.rb
|
94
110
|
- lib/ci/reporter/rake/utils.rb
|
95
111
|
- lib/ci/reporter/report_manager.rb
|
96
112
|
- lib/ci/reporter/test_suite.rb
|
@@ -114,12 +130,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
114
130
|
version: '0'
|
115
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
132
|
requirements:
|
117
|
-
- - "
|
133
|
+
- - ">="
|
118
134
|
- !ruby/object:Gem::Version
|
119
|
-
version:
|
135
|
+
version: '0'
|
120
136
|
requirements: []
|
121
|
-
|
122
|
-
rubygems_version: 2.2.2
|
137
|
+
rubygems_version: 3.4.1
|
123
138
|
signing_key:
|
124
139
|
specification_version: 4
|
125
140
|
summary: Connects Ruby test frameworks to CI systems via JUnit reports.
|
data/gemfiles/.gitignore
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
Gemfile.*.lock
|