rspec_junit_formatter 0.4.0.pre2 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data/LICENSE +1 -1
- data/README.md +46 -16
- data/lib/rspec_junit_formatter/rspec2.rb +14 -0
- data/lib/rspec_junit_formatter/rspec3.rb +19 -0
- data/lib/rspec_junit_formatter.rb +22 -5
- data.tar.gz.sig +0 -0
- metadata +52 -32
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e2262f9dd5b2368ab268f8f251b528b7ae60816accb3192bd1dd0b250ef097bc
|
4
|
+
data.tar.gz: dd120f276314e33ec44ad6982b3ef9371519a38d770a3de33800ef8015067275
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6733eaf055a5019767ea3586e426088ebe1eb3f57d5dcb2e6dba9d51bfa1543b36d410f5ac19142c512a4096976a8a02a23d7d55160f8028cbe9807d98c344f
|
7
|
+
data.tar.gz: 9bd13f22884872acb215295c6b45b0a332c3c510918be068b6e7619479db8ca9d991df124ab47a535c164fac42e424c8b6152158acab1839c07bf7de95eaa43b
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
# RSpec JUnit Formatter
|
2
2
|
|
3
|
-
[![Build results](
|
3
|
+
[![Build results](https://github.com/sj26/rspec_junit_formatter/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/sj26/rspec_junit_formatter/actions/workflows/ci.yml?branch=main)
|
4
4
|
[![Gem version](http://img.shields.io/gem/v/rspec_junit_formatter.svg)](https://rubygems.org/gems/rspec_junit_formatter)
|
5
5
|
|
6
|
-
[RSpec][rspec] 2 & 3 results that [Jenkins][jenkins]
|
6
|
+
[RSpec][rspec] 2 & 3 results that your CI can read. [Jenkins][jenkins-junit], [Buildkite][buildkite-junit], [CircleCI][circleci-junit], [Gitlab][gitlab-junit], and probably more, too.
|
7
7
|
|
8
|
-
|
8
|
+
[rspec]: http://rspec.info/
|
9
|
+
[jenkins-junit]: https://jenkins.io/doc/pipeline/steps/junit/
|
10
|
+
[buildkite-junit]: https://github.com/buildkite/rspec-junit-example
|
11
|
+
[circleci-junit]: https://circleci.com/docs/2.0/collect-test-data/
|
12
|
+
[gitlab-junit]: https://docs.gitlab.com/ee/ci/junit_test_reports.html#ruby-example
|
9
13
|
|
10
14
|
## Usage
|
11
15
|
|
@@ -29,6 +33,8 @@ You can use it in combination with other [formatters][rspec-formatters], too:
|
|
29
33
|
rspec --format progress --format RspecJunitFormatter --out rspec.xml
|
30
34
|
```
|
31
35
|
|
36
|
+
[rspec-formatters]: https://relishapp.com/rspec/rspec-core/v/3-6/docs/formatters
|
37
|
+
|
32
38
|
### Using in your project with Bundler
|
33
39
|
|
34
40
|
Add it to your Gemfile if you're using [Bundler][bundler]. Put it in the same groups as rspec.
|
@@ -46,6 +52,8 @@ Put the same arguments as the commands above in [your `.rspec`][rspec-file]:
|
|
46
52
|
--format RspecJunitFormatter
|
47
53
|
--out rspec.xml
|
48
54
|
```
|
55
|
+
[bundler]: https://bundler.io
|
56
|
+
[rspec-file]: https://relishapp.com/rspec/rspec-core/v/3-6/docs/configuration/read-command-line-configuration-options-from-files
|
49
57
|
|
50
58
|
### Parallel tests
|
51
59
|
|
@@ -58,17 +66,43 @@ For use with `parallel_tests`, add `$TEST_ENV_NUMBER` in the output file option
|
|
58
66
|
|
59
67
|
The formatter includes `$TEST_ENV_NUMBER` in the test suite name within the XML, too.
|
60
68
|
|
69
|
+
### Capturing output
|
70
|
+
|
71
|
+
If you like, you can capture the standard output and error streams of each test into the `:stdout` and `:stderr` example metadata which will be added to the junit report, e.g.:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
# spec_helper.rb
|
75
|
+
|
76
|
+
RSpec.configure do |config|
|
77
|
+
# register around filter that captures stdout and stderr
|
78
|
+
config.around(:each) do |example|
|
79
|
+
$stdout = StringIO.new
|
80
|
+
$stderr = StringIO.new
|
81
|
+
|
82
|
+
example.run
|
83
|
+
|
84
|
+
example.metadata[:stdout] = $stdout.string
|
85
|
+
example.metadata[:stderr] = $stderr.string
|
86
|
+
|
87
|
+
$stdout = STDOUT
|
88
|
+
$stderr = STDERR
|
89
|
+
end
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
Note that this example captures all output from every example all the time, potentially interfering with local debugging. You might like to restrict this to only on CI, or by using [rspec filters](https://relishapp.com/rspec/rspec-core/docs/hooks/filters).
|
94
|
+
|
61
95
|
## Caveats
|
62
96
|
|
63
97
|
* XML can only represent a [limited subset of characters][xml-charsets] which excludes null bytes and most control characters. This gem will use character entities where possible and fall back to replacing invalid characters with Ruby-like escape codes otherwise. For example, the null byte becomes `\0`.
|
64
98
|
|
65
|
-
|
66
|
-
|
67
|
-
* It would be nice to split things up into individual test suites, although would this correspond to example groups? The subject? The spec file? Not sure yet.
|
99
|
+
[xml-charsets]: https://www.w3.org/TR/xml/#charsets
|
68
100
|
|
69
101
|
## Development
|
70
102
|
|
71
|
-
Run the specs with `bundle exec rake
|
103
|
+
Run the specs with `bundle exec rake`, which uses [Appraisal][appraisal] to run the specs against all supported versions of rspec.
|
104
|
+
|
105
|
+
[appraisal]: https://github.com/thoughtbot/appraisal
|
72
106
|
|
73
107
|
## Releasing
|
74
108
|
|
@@ -76,16 +110,12 @@ Bump the gem version in the gemspec, and commit. Then `bundle exec rake build` t
|
|
76
110
|
|
77
111
|
## License
|
78
112
|
|
79
|
-
The MIT License, see [LICENSE]
|
113
|
+
The MIT License, see [LICENSE](./LICENSE).
|
114
|
+
|
115
|
+
## Thanks
|
116
|
+
|
117
|
+
Inspired by the work of [Diego Souza][dgvncsz0f] on [RSpec Formatters][dgvncsz0f/rspec_formatters] after frustration with [CI Reporter][ci_reporter].
|
80
118
|
|
81
|
-
[rspec]: http://rspec.info/
|
82
|
-
[rspec-formatters]: https://relishapp.com/rspec/rspec-core/v/3-6/docs/formatters
|
83
|
-
[rspec-file]: https://relishapp.com/rspec/rspec-core/v/3-6/docs/configuration/read-command-line-configuration-options-from-files
|
84
|
-
[jenkins]: http://jenkins-ci.org/
|
85
119
|
[dgvncsz0f]: https://github.com/dgvncsz0f
|
86
120
|
[dgvncsz0f/rspec_formatters]: https://github.com/dgvncsz0f/rspec_formatters
|
87
121
|
[ci_reporter]: https://github.com/nicksieger/ci_reporter
|
88
|
-
[bundler]: http://gembundler.com/
|
89
|
-
[fuubar]: http://jeffkreeftmeijer.com/2010/fuubar-the-instafailing-rspec-progress-bar-formatter/
|
90
|
-
[license]: https://github.com/sj26/rspec-junit-formatter/blob/master/LICENSE
|
91
|
-
[xml-charsets]: https://www.w3.org/TR/xml/#charsets
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class RSpecJUnitFormatter < RSpec::Core::Formatters::BaseFormatter
|
2
4
|
attr_reader :started
|
3
5
|
|
@@ -62,6 +64,10 @@ private
|
|
62
64
|
"#{message}\n#{backtrace.join("\n")}"
|
63
65
|
end
|
64
66
|
|
67
|
+
def error_count
|
68
|
+
0
|
69
|
+
end
|
70
|
+
|
65
71
|
def find_shared_group(example)
|
66
72
|
group_and_parent_groups(example).find { |group| group.metadata[:shared_group_name] }
|
67
73
|
end
|
@@ -69,4 +75,12 @@ private
|
|
69
75
|
def group_and_parent_groups(example)
|
70
76
|
example.example_group.parent_groups + [example.example_group]
|
71
77
|
end
|
78
|
+
|
79
|
+
def stdout_for(example)
|
80
|
+
example.metadata[:stdout]
|
81
|
+
end
|
82
|
+
|
83
|
+
def stderr_for(example)
|
84
|
+
example.metadata[:stderr]
|
85
|
+
end
|
72
86
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class RSpecJUnitFormatter < RSpec::Core::Formatters::BaseFormatter
|
2
4
|
RSpec::Core::Formatters.register self,
|
3
5
|
:start,
|
@@ -43,6 +45,15 @@ private
|
|
43
45
|
@examples_notification.notifications
|
44
46
|
end
|
45
47
|
|
48
|
+
def error_count
|
49
|
+
# Introduced in rspec 3.6
|
50
|
+
if @summary_notification.respond_to?(:errors_outside_of_examples_count)
|
51
|
+
@summary_notification.errors_outside_of_examples_count
|
52
|
+
else
|
53
|
+
0
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
46
57
|
def result_of(notification)
|
47
58
|
notification.example.execution_result.status
|
48
59
|
end
|
@@ -122,6 +133,14 @@ private
|
|
122
133
|
yield
|
123
134
|
end
|
124
135
|
end
|
136
|
+
|
137
|
+
def stdout_for(example_notification)
|
138
|
+
example_notification.example.metadata[:stdout]
|
139
|
+
end
|
140
|
+
|
141
|
+
def stderr_for(example_notification)
|
142
|
+
example_notification.example.metadata[:stderr]
|
143
|
+
end
|
125
144
|
end
|
126
145
|
|
127
146
|
# rspec-core 3.0.x forgot to mark this as a module function which causes:
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "socket"
|
2
4
|
require "time"
|
3
5
|
|
@@ -18,7 +20,7 @@ private
|
|
18
20
|
output << %{ tests="#{example_count}"}
|
19
21
|
output << %{ skipped="#{pending_count}"}
|
20
22
|
output << %{ failures="#{failure_count}"}
|
21
|
-
output << %{ errors="
|
23
|
+
output << %{ errors="#{error_count}"}
|
22
24
|
output << %{ time="#{escape("%.6f" % duration)}"}
|
23
25
|
output << %{ timestamp="#{escape(started.iso8601)}"}
|
24
26
|
output << %{ hostname="#{escape(Socket.gethostname)}"}
|
@@ -71,12 +73,27 @@ private
|
|
71
73
|
output << %{ time="#{escape("%.6f" % duration_for(example))}"}
|
72
74
|
output << %{>}
|
73
75
|
yield if block_given?
|
76
|
+
xml_dump_output(example)
|
74
77
|
output << %{</testcase>\n}
|
75
78
|
end
|
76
79
|
|
80
|
+
def xml_dump_output(example)
|
81
|
+
if (stdout = stdout_for(example)) && !stdout.empty?
|
82
|
+
output << %{<system-out>}
|
83
|
+
output << escape(stdout)
|
84
|
+
output << %{</system-out>}
|
85
|
+
end
|
86
|
+
|
87
|
+
if (stderr = stderr_for(example)) && !stderr.empty?
|
88
|
+
output << %{<system-err>}
|
89
|
+
output << escape(stderr)
|
90
|
+
output << %{</system-err>}
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
77
94
|
# Inversion of character range from https://www.w3.org/TR/xml/#charsets
|
78
95
|
ILLEGAL_REGEXP = Regexp.new(
|
79
|
-
"[^" <<
|
96
|
+
"[^".dup <<
|
80
97
|
"\u{9}" << # => \t
|
81
98
|
"\u{a}" << # => \n
|
82
99
|
"\u{d}" << # => \r
|
@@ -108,7 +125,7 @@ private
|
|
108
125
|
# Discouraged characters from https://www.w3.org/TR/xml/#charsets
|
109
126
|
# Plus special characters with well-known entity replacements
|
110
127
|
DISCOURAGED_REGEXP = Regexp.new(
|
111
|
-
"[" <<
|
128
|
+
"[".dup <<
|
112
129
|
"\u{22}" << # => "
|
113
130
|
"\u{26}" << # => &
|
114
131
|
"\u{27}" << # => '
|
@@ -150,8 +167,8 @@ private
|
|
150
167
|
text.to_s.encode(Encoding::UTF_8).gsub(ILLEGAL_REGEXP, ILLEGAL_REPLACEMENT).gsub(DISCOURAGED_REGEXP, DISCOURAGED_REPLACEMENTS)
|
151
168
|
end
|
152
169
|
|
153
|
-
STRIP_DIFF_COLORS_BLOCK_REGEXP = /^ ( [ ]* ) Diff: (?: \e\[
|
154
|
-
STRIP_DIFF_COLORS_CODES_REGEXP = /\e\[\d+m/
|
170
|
+
STRIP_DIFF_COLORS_BLOCK_REGEXP = /^ ( [ ]* ) Diff: (?: \e\[ 0 m )? (?: \n \1 \e\[ \d+ (?: ; \d+ )* m .* )* /x
|
171
|
+
STRIP_DIFF_COLORS_CODES_REGEXP = /\e\[ \d+ (?: ; \d+ )* m/x
|
155
172
|
|
156
173
|
def strip_diff_colors(string)
|
157
174
|
# XXX: RSpec diffs are appended to the message lines fairly early and will
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec_junit_formatter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Cochran
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain:
|
11
11
|
- |
|
12
12
|
-----BEGIN CERTIFICATE-----
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MIIDKDCCAhCgAwIBAgIBCDANBgkqhkiG9w0BAQsFADA6MQ0wCwYDVQQDDARzajI2
|
14
|
+
MRQwEgYKCZImiZPyLGQBGRYEc2oyNjETMBEGCgmSJomT8ixkARkWA2NvbTAeFw0y
|
15
|
+
MTA0MjcwMzIxMjZaFw0yMjA0MjcwMzIxMjZaMDoxDTALBgNVBAMMBHNqMjYxFDAS
|
16
16
|
BgoJkiaJk/IsZAEZFgRzajI2MRMwEQYKCZImiZPyLGQBGRYDY29tMIIBIjANBgkq
|
17
17
|
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr60Eo/ttCk8GMTMFiPr3GoYMIMFvLak
|
18
18
|
xSmTk9YGCB6UiEePB4THSSA5w6IPyeaCF/nWkDp3/BAam0eZMWG1IzYQB23TqIM0
|
@@ -21,14 +21,14 @@ cert_chain:
|
|
21
21
|
4O/FL2ChjL2CPCpLZW55ShYyrzphWJwLOJe+FJ/ZBl6YXwrzQM9HKnt4titSNvyU
|
22
22
|
KzE3L63A3PZvExzLrN9u09kuWLLJfXB2sGOlw3n9t72rJiuBr3/OQQIDAQABozkw
|
23
23
|
NzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU99dfRjEKFyczTeIz
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
24
|
+
m3ZsDWrNC80wDQYJKoZIhvcNAQELBQADggEBAInkmTwBeGEJ7Xu9jjZIuFaE197m
|
25
|
+
YfvrzVoE6Q1DlWXpgyhhxbPIKg2acvM/Z18A7kQrF7paYl64Ti84dC64seOFIBNx
|
26
|
+
Qj/lxzPHMBoAYqeXYJhnYIXnvGCZ4Fkic5Bhs+VdcDP/uwYp3adqy+4bT/XDFZQg
|
27
|
+
tSjrAOTg3wck5aI+Tz90ONQJ83bnCRr1UPQ0T3PbWMjnNsEa9CAxUB845Sg+9yUz
|
28
|
+
Tvf+pbX8JT9rawFDogxPhL7eRAbjg4MH9amp5l8HTVCAsW8vqv7wM4rtMNAaXmik
|
29
|
+
LJghfDEf70fTtbs4Zv57pPhn1b7wBNf8fh+TZOlYAA6dFtQXoCwfE6bWgQU=
|
30
30
|
-----END CERTIFICATE-----
|
31
|
-
date:
|
31
|
+
date: 2022-01-06 00:00:00.000000000 Z
|
32
32
|
dependencies:
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: rspec-core
|
@@ -60,58 +60,78 @@ dependencies:
|
|
60
60
|
name: bundler
|
61
61
|
requirement: !ruby/object:Gem::Requirement
|
62
62
|
requirements:
|
63
|
-
- - "
|
63
|
+
- - ">="
|
64
64
|
- !ruby/object:Gem::Version
|
65
|
-
version: '
|
65
|
+
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
68
|
version_requirements: !ruby/object:Gem::Requirement
|
69
69
|
requirements:
|
70
|
-
- - "
|
70
|
+
- - ">="
|
71
71
|
- !ruby/object:Gem::Version
|
72
|
-
version: '
|
72
|
+
version: '0'
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: appraisal
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
type: :development
|
81
|
+
prerelease: false
|
82
|
+
version_requirements: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
73
87
|
- !ruby/object:Gem::Dependency
|
74
88
|
name: nokogiri
|
75
89
|
requirement: !ruby/object:Gem::Requirement
|
76
90
|
requirements:
|
77
91
|
- - "~>"
|
78
92
|
- !ruby/object:Gem::Version
|
79
|
-
version: '1.
|
93
|
+
version: '1.8'
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.8.2
|
80
97
|
type: :development
|
81
98
|
prerelease: false
|
82
99
|
version_requirements: !ruby/object:Gem::Requirement
|
83
100
|
requirements:
|
84
101
|
- - "~>"
|
85
102
|
- !ruby/object:Gem::Version
|
86
|
-
version: '1.
|
103
|
+
version: '1.8'
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: 1.8.2
|
87
107
|
- !ruby/object:Gem::Dependency
|
88
108
|
name: rake
|
89
109
|
requirement: !ruby/object:Gem::Requirement
|
90
110
|
requirements:
|
91
|
-
- - "
|
111
|
+
- - ">="
|
92
112
|
- !ruby/object:Gem::Version
|
93
|
-
version: '
|
113
|
+
version: '0'
|
94
114
|
type: :development
|
95
115
|
prerelease: false
|
96
116
|
version_requirements: !ruby/object:Gem::Requirement
|
97
117
|
requirements:
|
98
|
-
- - "
|
118
|
+
- - ">="
|
99
119
|
- !ruby/object:Gem::Version
|
100
|
-
version: '
|
120
|
+
version: '0'
|
101
121
|
- !ruby/object:Gem::Dependency
|
102
122
|
name: coderay
|
103
123
|
requirement: !ruby/object:Gem::Requirement
|
104
124
|
requirements:
|
105
|
-
- - "
|
125
|
+
- - ">="
|
106
126
|
- !ruby/object:Gem::Version
|
107
|
-
version: '
|
127
|
+
version: '0'
|
108
128
|
type: :development
|
109
129
|
prerelease: false
|
110
130
|
version_requirements: !ruby/object:Gem::Requirement
|
111
131
|
requirements:
|
112
|
-
- - "
|
132
|
+
- - ">="
|
113
133
|
- !ruby/object:Gem::Version
|
114
|
-
version: '
|
134
|
+
version: '0'
|
115
135
|
description: RSpec results that your continuous integration service can read.
|
116
136
|
email: sj26@sj26.com
|
117
137
|
executables: []
|
@@ -123,11 +143,12 @@ files:
|
|
123
143
|
- lib/rspec_junit_formatter.rb
|
124
144
|
- lib/rspec_junit_formatter/rspec2.rb
|
125
145
|
- lib/rspec_junit_formatter/rspec3.rb
|
126
|
-
homepage:
|
146
|
+
homepage: https://github.com/sj26/rspec_junit_formatter
|
127
147
|
licenses:
|
128
148
|
- MIT
|
129
|
-
metadata:
|
130
|
-
|
149
|
+
metadata:
|
150
|
+
changelog_uri: https://github.com/sj26/rspec_junit_formatter/blob/HEAD/CHANGELOG.md
|
151
|
+
post_install_message:
|
131
152
|
rdoc_options: []
|
132
153
|
require_paths:
|
133
154
|
- lib
|
@@ -142,9 +163,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
142
163
|
- !ruby/object:Gem::Version
|
143
164
|
version: 2.0.0
|
144
165
|
requirements: []
|
145
|
-
|
146
|
-
|
147
|
-
signing_key:
|
166
|
+
rubygems_version: 3.2.26
|
167
|
+
signing_key:
|
148
168
|
specification_version: 4
|
149
169
|
summary: RSpec JUnit XML formatter
|
150
170
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|