minitest-junit 1.0.0 → 2.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb01cc706e87563df21ee3ac59414bea9dc4a72b321daa289daf264e4b69625f
4
- data.tar.gz: 79494de211ef61d553f06fd802708b6364514b7143f7f010ba604283c5a751a9
3
+ metadata.gz: 518beb2f7cb77d8e953d77f9b4342c5ec1d20603b8807782f71305b58a0f985d
4
+ data.tar.gz: d3dec1da3aa864c7e92a80628353e24c75a465df90d7e60fddb134a1dc725d89
5
5
  SHA512:
6
- metadata.gz: 917d4fb7ce3de650069496ed1b599e30661040cac256f543263cc0104d73d82823f291c336040a0dc8f588c7a4b46a1ce1f61b9a06382d880c729c5034a5a7b1
7
- data.tar.gz: 5ed9083720ab9b4f9b0caa185cfe8d1577b216f2c82b808c70d9a08df3bc6daab61472d2ed97e4479803cce8d84fa93dae56e3c070c4a9542b55493afd0d2852
6
+ metadata.gz: 1c2bc15ede221fc4128d62be93abd9dc6eb6137dd409faf763507c938b9d4bfdb4dd79af78d7de3f195ce1758dc72d5b6d1096c9b28893062c54db90c1a179bc
7
+ data.tar.gz: 32a0b2014027182f2c357b76defd7402fbc4996d994c5e8f3189844c66d634c16cfd26b9e0c524af3328bf347c5bbf608a480d85f927a021de81ce037543b760
@@ -0,0 +1,32 @@
1
+ name: Main
2
+ on:
3
+ push:
4
+ workflow_dispatch:
5
+
6
+ jobs:
7
+ tests:
8
+ name: Tests
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ fail-fast: false
12
+ matrix:
13
+ ruby: ["2.7", "3.0", "3.1", "3.2"]
14
+
15
+ steps:
16
+ - name: Checkout code
17
+ uses: actions/checkout@v4
18
+
19
+ - name: Setup Ruby
20
+ uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: ${{ matrix.ruby }}
23
+ bundler-cache: true
24
+
25
+ - name: Generate lockfile
26
+ run: bundle lock
27
+
28
+ - name: Bundle
29
+ run: bundle check || bundle install
30
+
31
+ - name: Run tests
32
+ run: bundle exec rake test
@@ -1,6 +1,6 @@
1
1
  module Minitest
2
2
  # :nodoc:
3
3
  module Junit
4
- VERSION = '1.0.0'
4
+ VERSION = '2.0.0'
5
5
  end
6
6
  end
@@ -1,6 +1,8 @@
1
1
  require 'minitest/junit/version'
2
2
  require 'minitest'
3
- require 'builder'
3
+ require 'ox'
4
+ require 'socket'
5
+ require 'time'
4
6
 
5
7
  # :nodoc:
6
8
  module Minitest
@@ -11,6 +13,8 @@ module Minitest
11
13
  @io = io
12
14
  @results = []
13
15
  @options = options
16
+ @options[:timestamp] = options.fetch(:timestamp, Time.now.iso8601)
17
+ @options[:hostname] = options.fetch(:hostname, Socket.gethostname)
14
18
  end
15
19
 
16
20
  def passed?
@@ -24,25 +28,51 @@ module Minitest
24
28
  end
25
29
 
26
30
  def report
27
- @io.puts '<testsuite>'
28
- @results.each { |result| @io.puts format(result) }
29
- @io.puts '</testsuite>'
31
+ doc = Ox::Document.new(:version => '1.0')
32
+ instruct = Ox::Instruct.new(:xml)
33
+ instruct[:version] = '1.0'
34
+ instruct[:encoding] = 'UTF-8'
35
+ doc << instruct
36
+ testsuite = Ox::Element.new('testsuite')
37
+ testsuite['name'] = @options[:name] || 'minitest'
38
+ testsuite['timestamp'] = @options[:timestamp]
39
+ testsuite['hostname'] = @options[:hostname]
40
+ testsuite['tests'] = @results.size
41
+ testsuite['skipped'] = @results.count(&:skipped?)
42
+ testsuite['failures'] = @results.count { |result| !result.error? && result.failure }
43
+ testsuite['errors'] = @results.count(&:error?)
44
+ testsuite['time'] = format_time(@results.map(&:time).inject(0, :+))
45
+ @results.each do |result|
46
+ testsuite << format(result)
47
+ end
48
+
49
+ doc << testsuite
50
+ @io << Ox.dump(doc)
30
51
  end
31
52
 
32
- def format(result)
33
- xml = Builder::XmlMarkup.new
34
- xml.testcase classname: format_class(result), name: format_name(result),
35
- time: result.time, assertions: result.assertions do |t|
36
- if result.skipped?
37
- t.skipped message: result
38
- else
39
- result.failures.each do |failure|
40
- type = classify failure
41
- xml.tag! type, format_backtrace(failure), message: result
42
- end
53
+ def format(result, parent = nil)
54
+ testcase = Ox::Element.new('testcase')
55
+ testcase['classname'] = format_class(result)
56
+ testcase['name'] = format_name(result)
57
+ testcase['time'] = format_time(result.time)
58
+ testcase['file'] = relative_to_cwd(result.source_location.first)
59
+ testcase['line'] = result.source_location.last
60
+ testcase['assertions'] = result.assertions
61
+ if result.skipped?
62
+ skipped = Ox::Element.new('skipped')
63
+ skipped['message'] = result
64
+ skipped << ""
65
+ testcase << skipped
66
+ else
67
+ result.failures.each do |failure|
68
+ failure_tag = Ox::Element.new(classify(failure))
69
+ failure_tag['message'] = result
70
+ failure_tag << format_backtrace(failure)
71
+ testcase << failure_tag
43
72
  end
44
73
  end
45
- xml.target!
74
+
75
+ testcase
46
76
  end
47
77
 
48
78
  private
@@ -55,8 +85,22 @@ module Minitest
55
85
  end
56
86
  end
57
87
 
88
+ def working_directory
89
+ @working_directory ||= Dir.getwd
90
+ end
91
+
92
+ def failure_message(result)
93
+ "#{result.klass}##{result.name}: #{result.failure}"
94
+ end
95
+
96
+ def relative_to_cwd(path)
97
+ path.sub(working_directory, '.')
98
+ end
99
+
58
100
  def format_backtrace(failure)
59
- failure.backtrace.join("\n")
101
+ Minitest.filter_backtrace(failure.backtrace).map do |line|
102
+ relative_to_cwd(line)
103
+ end.join("\n")
60
104
  end
61
105
 
62
106
  def format_class(result)
@@ -70,6 +114,10 @@ module Minitest
70
114
  def format_name(result)
71
115
  result.name
72
116
  end
117
+
118
+ def format_time(time)
119
+ Kernel::format('%.6f', time)
120
+ end
73
121
  end
74
122
  end
75
123
  end
@@ -19,9 +19,11 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ['lib']
20
20
 
21
21
  spec.add_dependency 'minitest', '~> 5.11'
22
- spec.add_dependency 'builder', '~> 3.2'
22
+ spec.add_dependency 'ox', '~> 2', '>= 2.14.2'
23
23
 
24
24
  spec.add_development_dependency 'bundler'
25
- spec.add_development_dependency 'rake', '~> 10.3.2'
26
- spec.add_development_dependency 'rubocop', '~> 0.24.1'
25
+ spec.add_development_dependency 'nokogiri'
26
+ spec.add_development_dependency 'pry-byebug'
27
+ spec.add_development_dependency 'rake', '~> 13'
28
+ spec.add_development_dependency 'rubocop', '~> 1'
27
29
  end
@@ -1,43 +1,95 @@
1
1
  require 'minitest/autorun'
2
2
  require 'stringio'
3
3
  require 'time'
4
+ require 'nokogiri'
4
5
 
5
6
  require 'minitest/junit'
6
7
 
8
+ class FakeTestName; end
9
+
7
10
  class ReporterTest < Minitest::Test
8
11
  def test_no_tests_generates_an_empty_suite
9
12
  reporter = create_reporter
10
13
 
11
14
  reporter.report
12
15
 
13
- assert_equal "<testsuite>\n</testsuite>\n", reporter.output
16
+ assert_match(
17
+ %r{<?xml version="1.0" encoding="UTF-8"\?>\n<testsuite name="minitest" timestamp="[^"]+" hostname="[^"]+" tests="0" skipped="0" failures="0" errors="0" time="0.000000"\/>},
18
+ reporter.output
19
+ )
14
20
  end
15
21
 
16
- def test_formats_each_result_with_a_formatter
22
+ def test_formats_each_successful_result_with_a_formatter
17
23
  reporter = create_reporter
18
- results = rand(100).times.map do |i|
19
- result = "test_name#{i}"
24
+
25
+ results = do_formatting_test(reporter, count: rand(100), cause_failures: 0)
26
+
27
+ results.each do |result|
28
+ assert_match("<testcase classname=\"FakeTestName\" name=\"#{result.name}\"", reporter.output)
29
+ end
30
+ end
31
+
32
+ def test_formats_each_failed_result_with_a_formatter
33
+ reporter = create_reporter
34
+
35
+ results = do_formatting_test(reporter, count: rand(100), cause_failures: 1)
36
+ parsed_report = Nokogiri::XML(reporter.output)
37
+ results.each do |result|
38
+ parsed_report.xpath("//testcase[@name='#{result.name}']").any?
39
+ end
40
+ # Check if some testcase has a failure
41
+ assert parsed_report.xpath("//testcase//failure").any?
42
+ end
43
+
44
+ def test_xml_nodes_has_file_and_line_attributes
45
+ reporter = create_reporter
46
+ results = do_formatting_test(reporter, count: 2, cause_failures: 1)
47
+ parsed_report = Nokogiri::XML(reporter.output)
48
+ example_node = parsed_report.xpath("//testcase").first
49
+ assert example_node.has_attribute?('file')
50
+ assert example_node.has_attribute?('line')
51
+ assert_equal 'unknown', example_node.attribute('file').value
52
+ assert_equal '-1', example_node.attribute('line').value
53
+ end
54
+
55
+ private
56
+
57
+ def do_formatting_test(reporter, count: 1, cause_failures: 0)
58
+ results = count.times.map do |i|
59
+ result = create_test_result(methodname: "test_name#{i}", failures: cause_failures)
20
60
  reporter.record result
21
61
  result
22
62
  end
23
63
 
24
64
  reporter.report
25
65
 
26
- expected = "<testsuite>\n#{results.join "\n"}\n</testsuite>\n"
27
- assert_equal expected, reporter.output
66
+ results
28
67
  end
29
68
 
30
- private
69
+ def create_test_result(name: FakeTestName, methodname: 'test_method_name', successes: 1, failures: 0)
70
+ test = Class.new Minitest::Test do
71
+ define_method 'class' do
72
+ name
73
+ end
74
+ end.new methodname
75
+ test.time = rand(100)
76
+ test.assertions = successes + failures
77
+ test.failures = failures.times.map do |i|
78
+ Class.new Minitest::Assertion do
79
+ define_method 'backtrace' do
80
+ ["Model failure \##{i}", 'This is a test backtrace', "#{__FILE__}:#{__LINE__}"]
81
+ end
82
+ end.new
83
+ end
84
+ Minitest::Result.from test
85
+ end
31
86
 
32
- def create_reporter
33
- io = StringIO.new
34
- reporter = Minitest::Junit::Reporter.new io, {}
87
+ def create_reporter(options = {})
88
+ io = StringIO.new ''
89
+ reporter = Minitest::Junit::Reporter.new io, options
35
90
  def reporter.output
36
91
  @io.string
37
92
  end
38
- def reporter.format(result)
39
- result
40
- end
41
93
  reporter.start
42
94
  reporter
43
95
  end
@@ -17,7 +17,10 @@ class TestCaseFormatter < Minitest::Test
17
17
  test = create_test_result
18
18
  reporter = create_reporter
19
19
 
20
- assert_match test.name, reporter.format(test)
20
+ assert_match(
21
+ test.name,
22
+ reporter.format(test).attributes['name']
23
+ )
21
24
  end
22
25
 
23
26
  def test_skipped_tests_generates_skipped_tag
@@ -28,7 +31,7 @@ class TestCaseFormatter < Minitest::Test
28
31
 
29
32
  reporter.report
30
33
 
31
- assert_match(/<skipped message="[^<>]+"\/><\/testcase>\n<\/testsuite>\n/, reporter.output)
34
+ assert_match(/<skipped message="[^<>]+"\><\/skipped>\n\s+<\/testcase>\n\s*<\/testsuite>\n/, reporter.output)
32
35
  end
33
36
 
34
37
  def test_failing_tests_creates_failure_tag
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minitest-junit
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Allan Espinosa
@@ -25,19 +25,25 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '5.11'
27
27
  - !ruby/object:Gem::Dependency
28
- name: builder
28
+ name: ox
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '3.2'
33
+ version: '2'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 2.14.2
34
37
  type: :runtime
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
41
  - - "~>"
39
42
  - !ruby/object:Gem::Version
40
- version: '3.2'
43
+ version: '2'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 2.14.2
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: bundler
43
49
  requirement: !ruby/object:Gem::Requirement
@@ -52,34 +58,62 @@ dependencies:
52
58
  - - ">="
53
59
  - !ruby/object:Gem::Version
54
60
  version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: nokogiri
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: pry-byebug
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
55
89
  - !ruby/object:Gem::Dependency
56
90
  name: rake
57
91
  requirement: !ruby/object:Gem::Requirement
58
92
  requirements:
59
93
  - - "~>"
60
94
  - !ruby/object:Gem::Version
61
- version: 10.3.2
95
+ version: '13'
62
96
  type: :development
63
97
  prerelease: false
64
98
  version_requirements: !ruby/object:Gem::Requirement
65
99
  requirements:
66
100
  - - "~>"
67
101
  - !ruby/object:Gem::Version
68
- version: 10.3.2
102
+ version: '13'
69
103
  - !ruby/object:Gem::Dependency
70
104
  name: rubocop
71
105
  requirement: !ruby/object:Gem::Requirement
72
106
  requirements:
73
107
  - - "~>"
74
108
  - !ruby/object:Gem::Version
75
- version: 0.24.1
109
+ version: '1'
76
110
  type: :development
77
111
  prerelease: false
78
112
  version_requirements: !ruby/object:Gem::Requirement
79
113
  requirements:
80
114
  - - "~>"
81
115
  - !ruby/object:Gem::Version
82
- version: 0.24.1
116
+ version: '1'
83
117
  description: Junit reporter for Minitest ~> 5.0
84
118
  email:
85
119
  - allan.espinosa@outlook.com
@@ -87,6 +121,7 @@ executables: []
87
121
  extensions: []
88
122
  extra_rdoc_files: []
89
123
  files:
124
+ - ".github/workflows/main.yml"
90
125
  - ".gitignore"
91
126
  - Gemfile
92
127
  - LICENSE.txt
@@ -119,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
154
  - !ruby/object:Gem::Version
120
155
  version: '0'
121
156
  requirements: []
122
- rubygems_version: 3.2.26
157
+ rubygems_version: 3.4.13
123
158
  signing_key:
124
159
  specification_version: 4
125
160
  summary: Junit reporter for Minitest ~> 5.0