simplecov-cobertura 2.1.0 → 4.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: 7c2d0c9eebf10fae25ce491aa5b33fd744cb72c8bd3b9645706e8b6f35495e88
4
- data.tar.gz: 8890ee7ca2a87b49a4f37ee049bbb6d9375f5ead377bc2e3e32ee793883f56a4
3
+ metadata.gz: af6021ce1207169b5c8d5bbb7aba68a6a02df4c88a248b7fca763f817cfe0600
4
+ data.tar.gz: e9ded405dcfbb983a77153fd13a376addcdbb77d8e34a44b68c2ecb61f6af9c5
5
5
  SHA512:
6
- metadata.gz: ce64fbbd3eb2986a45d90800573739d5f558162a8a66223007926a799e0ba082c4393a7eae1974fe8f40c7b1a22b1f3bebe3adb696805a29a2206c7c5a0b6a21
7
- data.tar.gz: ed1e556b151833e2db0eeb4a2e8a0539946f80af3a3a85429e708a119065def438032eb660437367f1bd34c91eb1d75d7636ca3958844ca83249ef433080eb6d
6
+ metadata.gz: e6678dab612071560ecde49409ed10285778dc6c73445766e80283828548c5a142631dc44ee7be5a1da637f8d3fa7ee8d077e226528574b1978b9742f21c1571
7
+ data.tar.gz: af788e30f13b615b2016359a49b6d1ab34931ac74732ca25beefb4c0cac0ddff8f5bb378a3b92ed4ed699a0c404d5590982f50f32084186b861c2bde528f7e26
@@ -7,7 +7,7 @@
7
7
 
8
8
  name: Build
9
9
 
10
- on: [push, pull_request]
10
+ on: [ push, pull_request ]
11
11
 
12
12
  jobs:
13
13
  test:
@@ -15,14 +15,14 @@ jobs:
15
15
  runs-on: ubuntu-latest
16
16
  strategy:
17
17
  matrix:
18
- ruby-version: [2.5, 2.6, 2.7, 3.0]
18
+ ruby-version: [ 3.2, 3.3, 3.4, 4.0 ]
19
19
 
20
20
  steps:
21
- - uses: actions/checkout@v2
21
+ - uses: actions/checkout@v6
22
22
  - name: Set up Ruby
23
23
  uses: ruby/setup-ruby@v1
24
24
  with:
25
25
  ruby-version: ${{ matrix.ruby-version }}
26
26
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
27
27
  - name: Run tests
28
- run: bundle exec rake
28
+ run: bundle exec rake
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ mkmf.log
15
15
 
16
16
  *.iml
17
17
  .idea
18
+ .ruby-*
data/README.md CHANGED
@@ -1,10 +1,12 @@
1
- # simplecov-cobertura
2
- [![Build](https://github.com/dashingrocket/simplecov-cobertura/actions/workflows/build.yml/badge.svg)](https://github.com/dashingrocket/simplecov-cobertura/actions/workflows/build.yml) [![Gem Version](https://badge.fury.io/rb/simplecov-cobertura.svg)](http://badge.fury.io/rb/simplecov-cobertura) [![Downloads](http://ruby-gem-downloads-badge.herokuapp.com/simplecov-cobertura?type=total)](https://rubygems.org/gems/simplecov-cobertura)
1
+ # simplecov-cobertura
3
2
 
3
+ [![Build](https://github.com/jessebs/simplecov-cobertura/actions/workflows/build.yml/badge.svg)](https://github.com/jessebs/simplecov-cobertura/actions/workflows/build.yml) [![Gem Version](https://badge.fury.io/rb/simplecov-cobertura.svg)](http://badge.fury.io/rb/simplecov-cobertura)
4
4
 
5
- Produces [Cobertura](http://cobertura.sourceforge.net/) formatted XML from [SimpleCov](https://github.com/colszowka/simplecov).
5
+ Produces [Cobertura](http://cobertura.sourceforge.net/) formatted XML
6
+ from [SimpleCov](https://github.com/colszowka/simplecov).
6
7
 
7
- Output can be consumed by the [Jenkins Cobertura Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Cobertura+Plugin) for easy
8
+ Output can be consumed by the [Jenkins Cobertura Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Cobertura+Plugin)
9
+ for easy
8
10
  coverage visualization.
9
11
 
10
12
  ## Installation
@@ -32,22 +34,22 @@ SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
32
34
  ```
33
35
 
34
36
  ## Continuous Integration
37
+
35
38
  Tested in a CI environment against the following Ruby versions:
36
- * 3.0
37
- * 2.7
38
- * 2.6
39
- * 2.5
39
+
40
+ * 3.2 - 4.0
40
41
 
41
42
  ## Contributing
42
43
 
43
- 1. Fork it ( https://github.com/dashingrocket/simplecov-cobertura/fork )
44
+ 1. Fork it ( https://github.com/jessebs/simplecov-cobertura/fork )
44
45
  2. Create your feature branch (`git checkout -b my-new-feature`)
45
46
  3. Commit your changes (`git commit -am 'Add some feature'`)
46
47
  4. Push to the branch (`git push origin my-new-feature`)
47
48
  5. Create a new Pull Request
48
49
 
49
50
  ## License
50
- Copyright 2021 Dashing Rocket, Ltd.
51
+
52
+ Copyright 2014-2026 Jesse Bowes
51
53
 
52
54
  Licensed under the Apache License, Version 2.0 (the "License");
53
55
  you may not use this file except in compliance with the License.
@@ -1,7 +1,7 @@
1
1
  module SimpleCov
2
2
  module Formatter
3
3
  class CoberturaFormatter
4
- VERSION = '2.1.0'
4
+ VERSION = '4.0.0'
5
5
  end
6
6
  end
7
7
  end
@@ -1,8 +1,8 @@
1
- require 'simplecov'
2
-
1
+ require 'stringio'
3
2
  require 'rexml/document'
4
3
  require 'rexml/element'
5
4
  require 'pathname'
5
+ require 'simplecov'
6
6
 
7
7
  require_relative 'simplecov-cobertura/version'
8
8
 
@@ -27,149 +27,172 @@ module SimpleCov
27
27
 
28
28
  xml_str = string_io.string
29
29
  File.write(result_path, xml_str)
30
- puts "Coverage report generated for #{result.command_name} to #{result_path}. #{coverage_output(result)}"
30
+ puts output_message(result, result_path)
31
+
31
32
  xml_str
32
33
  end
33
34
 
34
35
  private
35
36
 
36
- def result_to_xml(result)
37
- doc = REXML::Document.new set_xml_head
38
- doc.context[:attribute_quote] = :quote
39
- doc.add_element REXML::Element.new('coverage')
40
- coverage = doc.root
37
+ def result_to_xml(result)
38
+ doc = REXML::Document.new
39
+ doc.context[:attribute_quote] = :quote
40
+ doc << REXML::XMLDecl.new('1.0')
41
+ doc << REXML::DocType.new('coverage', "SYSTEM \"#{DTD_URL}\"")
42
+ doc << REXML::Comment.new("Generated by simplecov-cobertura version #{VERSION} (https://github.com/jessebs/simplecov-cobertura)")
43
+ doc.add_element REXML::Element.new('coverage')
44
+ coverage = doc.root
41
45
 
42
- set_coverage_attributes(coverage, result)
46
+ set_coverage_attributes(coverage, result)
43
47
 
44
- coverage.add_element(sources = REXML::Element.new('sources'))
45
- sources.add_element(source = REXML::Element.new('source'))
46
- source.text = SimpleCov.root
48
+ coverage.add_element(sources = REXML::Element.new('sources'))
49
+ sources.add_element(source = REXML::Element.new('source'))
50
+ source.text = SimpleCov.root
47
51
 
48
- coverage.add_element(packages = REXML::Element.new('packages'))
52
+ coverage.add_element(packages = REXML::Element.new('packages'))
49
53
 
50
- if result.groups.empty?
51
- groups = {File.basename(SimpleCov.root) => result.files}
52
- else
53
- groups = result.groups
54
- end
54
+ if result.groups.empty?
55
+ groups = { File.basename(SimpleCov.root) => result.files }
56
+ else
57
+ groups = result.groups
58
+ end
55
59
 
56
- groups.each do |name, files|
57
- next if files.empty?
58
- packages.add_element(package = REXML::Element.new('package'))
59
- set_package_attributes(package, name, files)
60
+ groups.each do |name, files|
61
+ next if files.empty?
62
+ packages.add_element(package = REXML::Element.new('package'))
63
+ set_package_attributes(package, name, files)
60
64
 
61
- package.add_element(classes = REXML::Element.new('classes'))
65
+ package.add_element(classes = REXML::Element.new('classes'))
62
66
 
63
- files.each do |file|
64
- classes.add_element(class_ = REXML::Element.new('class'))
65
- set_class_attributes(class_, file)
67
+ files.each do |file|
68
+ classes.add_element(class_ = REXML::Element.new('class'))
69
+ set_class_attributes(class_, file)
66
70
 
67
- class_.add_element(REXML::Element.new('methods'))
68
- class_.add_element(lines = REXML::Element.new('lines'))
71
+ class_.add_element(REXML::Element.new('methods'))
72
+ class_.add_element(lines = REXML::Element.new('lines'))
69
73
 
70
- branched_lines = file.branches.map(&:start_line)
71
- branched_lines_covered = file.covered_branches.map(&:start_line)
74
+ branches_by_line = {}
75
+ if SimpleCov.branch_coverage?
76
+ build_branches_by_line(file, branches_by_line)
77
+ end
72
78
 
73
- file.lines.each do |file_line|
74
- if file_line.covered? || file_line.missed?
75
- lines.add_element(line = REXML::Element.new('line'))
76
- set_line_attributes(line, file_line)
77
- set_branch_attributes(line, file_line, branched_lines, branched_lines_covered) if SimpleCov.branch_coverage?
78
- end
79
+ file.lines.each do |file_line|
80
+ if file_line.covered? || file_line.missed?
81
+ lines.add_element(line = REXML::Element.new('line'))
82
+ set_line_attributes(line, file_line)
83
+ set_branch_attributes(line, file_line, branches_by_line) if SimpleCov.branch_coverage?
79
84
  end
80
85
  end
81
86
  end
82
-
83
- doc
84
87
  end
85
88
 
86
- def set_coverage_attributes(coverage, result)
87
- ls = result.coverage_statistics[:line]
88
- bs = result.coverage_statistics[:branch]
89
-
90
- coverage.attributes['line-rate'] = extract_rate(ls.percent)
91
- coverage.attributes['lines-covered'] = ls.covered.to_s.to_s
92
- coverage.attributes['lines-valid'] = ls.total.to_s.to_s
93
- if SimpleCov.branch_coverage?
94
- coverage.attributes['branches-covered'] = bs.covered.to_s
95
- coverage.attributes['branches-valid'] = bs.total.to_s
96
- coverage.attributes['branch-rate'] = extract_rate(bs.percent)
97
- end
98
- coverage.attributes['complexity'] = '0'
99
- coverage.attributes['version'] = '0'
100
- coverage.attributes['timestamp'] = Time.now.to_i.to_s
89
+ doc
90
+ end
91
+
92
+ def set_coverage_attributes(coverage, result)
93
+ ls = result.coverage_statistics[:line]
94
+ bs = result.coverage_statistics[:branch]
95
+
96
+ coverage.attributes['line-rate'] = extract_rate(ls.percent)
97
+ coverage.attributes['lines-covered'] = ls.covered.to_s.to_s
98
+ coverage.attributes['lines-valid'] = ls.total.to_s.to_s
99
+ if SimpleCov.branch_coverage?
100
+ coverage.attributes['branches-covered'] = bs.covered.to_s
101
+ coverage.attributes['branches-valid'] = bs.total.to_s
102
+ coverage.attributes['branch-rate'] = extract_rate(bs.percent)
101
103
  end
104
+ coverage.attributes['complexity'] = '0'
105
+ coverage.attributes['version'] = '0'
106
+ coverage.attributes['timestamp'] = Time.now.to_i.to_s
107
+ end
102
108
 
103
- def set_package_attributes(package, name, result)
104
- ls = result.coverage_statistics[:line]
105
- bs = result.coverage_statistics[:branch]
109
+ def set_package_attributes(package, name, result)
110
+ ls = result.coverage_statistics[:line]
111
+ bs = result.coverage_statistics[:branch]
106
112
 
107
- package.attributes['name'] = name
108
- package.attributes['line-rate'] = extract_rate(ls.percent)
109
- if SimpleCov.branch_coverage?
110
- package.attributes['branch-rate'] = extract_rate(bs.percent)
111
- end
112
- package.attributes['complexity'] = '0'
113
+ package.attributes['name'] = name
114
+ package.attributes['line-rate'] = extract_rate(ls.percent)
115
+ if SimpleCov.branch_coverage?
116
+ package.attributes['branch-rate'] = extract_rate(bs.percent)
113
117
  end
118
+ package.attributes['complexity'] = '0'
119
+ end
114
120
 
115
- def set_class_attributes(class_, file)
116
- ls = file.coverage_statistics[:line]
117
- bs = file.coverage_statistics[:branch]
121
+ def set_class_attributes(class_, file)
122
+ ls = file.coverage_statistics[:line]
123
+ bs = file.coverage_statistics[:branch]
118
124
 
119
- filename = file.filename
120
- class_.attributes['name'] = File.basename(filename, '.*')
121
- class_.attributes['filename'] = resolve_filename(filename)
122
- class_.attributes['line-rate'] = extract_rate(ls.percent)
123
- if SimpleCov.branch_coverage?
124
- class_.attributes['branch-rate'] = extract_rate(bs.percent)
125
- end
126
- class_.attributes['complexity'] = '0'
125
+ filename = file.filename
126
+ class_.attributes['name'] = resolve_filename(filename)
127
+ class_.attributes['filename'] = resolve_filename(filename)
128
+ class_.attributes['line-rate'] = extract_rate(ls.percent)
129
+ if SimpleCov.branch_coverage?
130
+ class_.attributes['branch-rate'] = extract_rate(bs.percent)
127
131
  end
132
+ class_.attributes['complexity'] = '0'
133
+ end
128
134
 
129
- def set_line_attributes(line, file_line)
130
- line.attributes['number'] = file_line.line_number.to_s
131
- line.attributes['hits'] = file_line.coverage.to_s
135
+ def set_line_attributes(line, file_line)
136
+ line.attributes['number'] = file_line.line_number.to_s
137
+ line.attributes['hits'] = file_line.coverage.to_s
138
+ end
139
+
140
+ def set_branch_attributes(line, file_line, branches_by_line)
141
+ branch_info = branches_by_line[file_line.line_number]
142
+ if branch_info
143
+ total = branch_info[:total]
144
+ covered = branch_info[:covered]
145
+ pct_coverage = total > 0 ? (covered * 100 / total) : 0
146
+ line.attributes['branch'] = 'true'
147
+ line.attributes['condition-coverage'] = "#{pct_coverage}% (#{covered}/#{total})"
148
+ else
149
+ line.attributes['branch'] = 'false'
132
150
  end
151
+ end
152
+
153
+ def build_branches_by_line(file, branches_by_line)
154
+ file.coverage_data.fetch("branches", {}).each do |condition, branches|
155
+ line = condition_start_line(condition)
156
+ next unless line
133
157
 
134
- def set_branch_attributes(line, file_line, branched_lines, branched_lines_covered)
135
- if branched_lines.include? file_line.number
136
- pct_coverage, branches_covered = branched_lines_covered.include?(file_line.number) ? [100, '1/1'] : [0, '0/1']
137
- line.attributes['branch'] = 'true'
138
- line.attributes['condition-coverage'] = "#{pct_coverage}% (#{branches_covered})"
139
- else
140
- line.attributes['branch'] = 'false'
158
+ info = branches_by_line[line] ||= { total: 0, covered: 0 }
159
+ branches.each_value do |hit_count|
160
+ info[:total] += 1
161
+ info[:covered] += 1 if hit_count.to_i > 0
141
162
  end
142
163
  end
164
+ rescue StandardError => e
165
+ warn "simplecov-cobertura: couldn't extract per-line branch detail " \
166
+ "(#{e.class}: #{e.message}); lines will report branch=\"false\""
167
+ branches_by_line.clear
168
+ end
143
169
 
144
- def set_xml_head(lines=[])
145
- lines << "<?xml version=\"1.0\"?>"
146
- lines << "<!DOCTYPE coverage SYSTEM \"#{DTD_URL}\">"
147
- lines << "<!-- Generated by simplecov-cobertura version #{VERSION} (https://github.com/dashingrocket/simplecov-cobertura) -->"
148
- lines.join("\n")
149
- end
170
+ def condition_start_line(condition)
171
+ return condition[2] if condition.is_a?(Array)
172
+ return nil unless condition.is_a?(String)
150
173
 
151
- def coverage_output(result)
152
- ls = result.coverage_statistics[:line]
153
- bs = result.coverage_statistics[:branch]
174
+ condition.scan(/-?\d+/)[1]&.to_i # [id, start_line, ...]
175
+ end
154
176
 
155
- if SimpleCov.branch_coverage?
156
- "%d / %d LOC (%.2f%%) covered; %d / %d BC (%.2f%%) covered" % [ls.covered, ls.total, ls.percent, bs.covered, bs.total, bs.percent]
157
- else
158
- "%d / %d LOC (%.2f%%) covered" % [ls.covered, ls.total, ls.percent]
159
- end
160
- end
177
+ # Roughly mirrors private method SimpleCov::Formatter::HTMLFormatter#output_coverage
178
+ def output_message(result, output_path)
179
+ output = "Coverage report generated for #{result.command_name} to #{output_path}."
180
+ output += "\nLine Coverage: #{result.covered_percent.round(2)}% (#{result.covered_lines} / #{result.total_lines})"
181
+ output += "\nBranch Coverage: #{result.coverage_statistics[:branch].percent.round(2)}% (#{result.covered_branches} / #{result.total_branches})" if SimpleCov.branch_coverage?
182
+ output
183
+ end
161
184
 
162
- def resolve_filename(filename)
163
- Pathname.new(filename).relative_path_from(project_root).to_s
164
- end
185
+ def resolve_filename(filename)
186
+ Pathname.new(filename).relative_path_from(project_root).to_s
187
+ end
165
188
 
166
- def extract_rate(percent)
167
- (percent / 100).round(2).to_s
168
- end
189
+ def extract_rate(percent)
190
+ (percent / 100).round(4).to_s
191
+ end
169
192
 
170
- def project_root
171
- @project_root ||= Pathname.new(SimpleCov.root)
172
- end
193
+ def project_root
194
+ @project_root ||= Pathname.new(SimpleCov.root)
195
+ end
173
196
  end
174
197
  end
175
198
  end
@@ -5,25 +5,25 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require 'simplecov-cobertura/version'
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.name = 'simplecov-cobertura'
9
- spec.version = SimpleCov::Formatter::CoberturaFormatter::VERSION
10
- spec.authors = ['Jesse Bowes']
11
- spec.email = ['jbowes@dashingrocket.com']
12
- spec.summary = 'SimpleCov Cobertura Formatter'
13
- spec.description = 'Produces Cobertura XML formatted output from SimpleCov'
14
- spec.homepage = 'https://github.com/dashingrocket/simplecov-cobertura'
15
- spec.license = 'Apache-2.0'
16
- spec.required_ruby_version = '>= 2.5.0'
8
+ spec.name = 'simplecov-cobertura'
9
+ spec.version = SimpleCov::Formatter::CoberturaFormatter::VERSION
10
+ spec.authors = ['Jesse Bowes']
11
+ spec.email = ['jessebowes@acm.org']
12
+ spec.summary = 'SimpleCov Cobertura Formatter'
13
+ spec.description = 'Produces Cobertura XML formatted output from SimpleCov'
14
+ spec.homepage = 'https://github.com/jessebs/simplecov-cobertura'
15
+ spec.license = 'Apache-2.0'
16
+ spec.required_ruby_version = '>= 3.2'
17
17
 
18
- spec.files = `git ls-files -z`.split("\x0")
19
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.files = `git ls-files -z`.split("\x0")
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
21
  spec.require_paths = ['lib']
22
22
 
23
23
  spec.add_development_dependency 'test-unit', '~> 3.2'
24
24
  spec.add_development_dependency 'nokogiri', '~> 1.0'
25
25
  spec.add_development_dependency 'rake', '~> 13.0'
26
26
 
27
- spec.add_dependency 'simplecov', '~> 0.19'
27
+ spec.add_dependency 'simplecov', '~> 1.0'
28
28
  spec.add_dependency 'rexml'
29
29
  end
@@ -0,0 +1,28 @@
1
+ class Sample
2
+ def greet(name)
3
+ if name.nil?
4
+ "Hello, stranger!"
5
+ else
6
+ "Hello, #{name}!"
7
+ end
8
+ end
9
+
10
+ def absolute(n)
11
+ if n < 0
12
+ -n
13
+ else
14
+ n
15
+ end
16
+ end
17
+
18
+ def unused_method
19
+ x = 1
20
+ y = 2
21
+ z = x + y
22
+ if z > 0
23
+ "positive"
24
+ else
25
+ "non-positive"
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ $LOAD_PATH.unshift(File.join(ENV.fetch('GEM_ROOT'), 'lib'))
2
+
3
+ require 'simplecov'
4
+ require 'simplecov-cobertura'
5
+
6
+ SimpleCov.command_name ENV.fetch('COMMAND_NAME', 'Unit Tests')
7
+ SimpleCov.start do
8
+ enable_coverage :branch
9
+ use_merging true
10
+ merge_timeout 3600 # generous so slow CI can't expire run A's result
11
+ root ENV.fetch('PROJECT_ROOT')
12
+ coverage_dir 'coverage'
13
+ formatter SimpleCov::Formatter::CoberturaFormatter
14
+ end
15
+
16
+ require File.join(ENV.fetch('PROJECT_ROOT'), 'lib', 'sample')
17
+ require 'test/unit'
@@ -0,0 +1,11 @@
1
+ require_relative 'simplecov_setup'
2
+
3
+ class MergedATest < Test::Unit::TestCase
4
+ def test_greet_with_name
5
+ assert_equal 'Hello, World!', Sample.new.greet('World') # greet: else branch
6
+ end
7
+
8
+ def test_absolute_positive
9
+ assert_equal 5, Sample.new.absolute(5) # absolute: else branch
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ require_relative 'simplecov_setup'
2
+
3
+ class MergedBTest < Test::Unit::TestCase
4
+ def test_greet_without_name
5
+ assert_equal 'Hello, stranger!', Sample.new.greet(nil) # greet: then branch
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ require_relative 'simplecov_setup'
2
+
3
+ class SampleTest < Test::Unit::TestCase
4
+ def test_greet_with_name
5
+ assert_equal "Hello, World!", Sample.new.greet("World")
6
+ end
7
+
8
+ def test_absolute_positive
9
+ # Only exercises the else branch (n >= 0), never the then branch (n < 0)
10
+ assert_equal 5, Sample.new.absolute(5)
11
+ end
12
+ end
@@ -0,0 +1,175 @@
1
+ require 'test/unit'
2
+ require 'tmpdir'
3
+ require 'open3'
4
+ require 'nokogiri'
5
+ require 'fileutils'
6
+
7
+ class IntegrationTest < Test::Unit::TestCase
8
+ FIXTURES_DIR = File.join(__dir__, 'fixtures')
9
+ GEM_ROOT = File.expand_path('..', __dir__)
10
+
11
+ def setup
12
+ @tmpdir = Dir.mktmpdir('simplecov-cobertura-integration')
13
+ end
14
+
15
+ def teardown
16
+ FileUtils.remove_entry(@tmpdir) if @tmpdir && Dir.exist?(@tmpdir)
17
+ end
18
+
19
+ def test_clean_load_require_and_assign_formatter
20
+ # In a fresh subprocess, require simplecov-cobertura and assign the formatter.
21
+ # This catches missing requires (e.g. simplecov, stringio).
22
+ code = <<~RUBY
23
+ require 'simplecov-cobertura'
24
+ SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
25
+ RUBY
26
+ stdout, stderr, status = Open3.capture3('ruby', '-e', code)
27
+ assert status.success?, "Clean-load subprocess failed.\nstdout: #{stdout}\nstderr: #{stderr}"
28
+ end
29
+
30
+ def test_real_coverage_run_produces_valid_cobertura_xml
31
+ install_fixture('sample')
32
+
33
+ # Run the sample test in a subprocess.
34
+ stdout, stderr, status = run_fixture_test('test/test_sample.rb')
35
+ assert status.success?, "Sample test subprocess failed.\nstdout: #{stdout}\nstderr: #{stderr}"
36
+
37
+ # --- Assert on the generated coverage.xml ---
38
+ coverage_xml_path = File.join(@tmpdir, 'coverage', 'coverage.xml')
39
+ assert File.exist?(coverage_xml_path), "coverage.xml was not generated"
40
+ xml_content = File.read(coverage_xml_path)
41
+ assert !xml_content.empty?, "coverage.xml is empty"
42
+
43
+ doc = Nokogiri::XML(xml_content) { |config| config.strict }
44
+ assert doc.errors.empty?, "XML parse errors: #{doc.errors.join(', ')}"
45
+
46
+ # Root element
47
+ coverage = doc.at_xpath('/coverage')
48
+ assert_not_nil coverage, "Missing /coverage root element"
49
+
50
+ # Line coverage attributes — partial, not 100% and not 0%
51
+ line_rate = coverage['line-rate'].to_f
52
+ assert line_rate > 0.0, "line-rate should be > 0, got #{line_rate}"
53
+ assert line_rate < 1.0, "line-rate should be < 1.0 (partial coverage), got #{line_rate}"
54
+
55
+ lines_covered = coverage['lines-covered'].to_i
56
+ lines_valid = coverage['lines-valid'].to_i
57
+ assert lines_covered > 0, "lines-covered should be > 0"
58
+ assert lines_valid > lines_covered, "lines-valid (#{lines_valid}) should be > lines-covered (#{lines_covered})"
59
+
60
+ # Branch coverage attributes — partial
61
+ branch_rate = coverage['branch-rate'].to_f
62
+ assert branch_rate > 0.0, "branch-rate should be > 0, got #{branch_rate}"
63
+ assert branch_rate < 1.0, "branch-rate should be < 1.0 (partial coverage), got #{branch_rate}"
64
+
65
+ branches_covered = coverage['branches-covered'].to_i
66
+ branches_valid = coverage['branches-valid'].to_i
67
+ assert branches_covered > 0, "branches-covered should be > 0"
68
+ assert branches_valid > branches_covered, "branches-valid (#{branches_valid}) should be > branches-covered (#{branches_covered})"
69
+
70
+ # The sample library file appears as a class with the expected relative filename
71
+ classes = doc.xpath('//class')
72
+ filenames = classes.map { |c| c['filename'] }
73
+ assert filenames.any? { |f| f.include?('lib/sample.rb') },
74
+ "Expected a class with filename containing 'lib/sample.rb', got: #{filenames}"
75
+
76
+ # Line-level <line> elements exist with hits and branch attributes
77
+ lines = doc.xpath('//line')
78
+ assert lines.length > 0, "Expected <line> elements in the output"
79
+ lines.each do |line|
80
+ assert_not_nil line['number'], "Line element missing 'number' attribute"
81
+ assert_not_nil line['hits'], "Line element missing 'hits' attribute"
82
+ assert_not_nil line['branch'], "Line element missing 'branch' attribute"
83
+ end
84
+
85
+ # At least one line should have branch='true' (from the if/else)
86
+ branch_lines = lines.select { |l| l['branch'] == 'true' }
87
+ assert branch_lines.length > 0, "Expected at least one line with branch='true'"
88
+
89
+ # Validate condition-coverage on branch lines
90
+ branch_lines.each do |bl|
91
+ cc = bl['condition-coverage']
92
+ assert_not_nil cc, "Branch line missing 'condition-coverage' attribute"
93
+ assert_match(/\d+% \(\d+\/\d+\)/, cc, "condition-coverage format unexpected: #{cc}")
94
+ end
95
+ end
96
+
97
+ def test_condition_coverage_values_are_accurate
98
+ install_fixture('sample')
99
+
100
+ stdout, stderr, status = run_fixture_test('test/test_sample.rb')
101
+ assert status.success?, "Sample test subprocess failed.\nstdout: #{stdout}\nstderr: #{stderr}"
102
+
103
+ coverage_xml_path = File.join(@tmpdir, 'coverage', 'coverage.xml')
104
+ assert File.exist?(coverage_xml_path), "coverage.xml was not generated"
105
+ doc = Nokogiri::XML(File.read(coverage_xml_path)) { |config| config.strict }
106
+
107
+ # Find the branch line for the if statement in sample.rb's absolute method
108
+ sample_class = doc.xpath('//class').find { |c| c['filename'].include?('sample.rb') }
109
+ assert_not_nil sample_class, "Expected sample.rb class in output"
110
+
111
+ branch_lines = sample_class.xpath('.//line[@branch="true"]')
112
+ assert branch_lines.length > 0, "Expected branch lines in sample.rb"
113
+
114
+ # Each if/else has 2 total branches. greet and absolute each have 1/2 covered,
115
+ # unused_method has 0/2 covered. Verify exact values by line number.
116
+ condition_coverages = branch_lines.map { |bl| [bl['number'].to_i, bl['condition-coverage']] }.to_h
117
+
118
+ # greet: line 3 — only else branch taken => 50% (1/2)
119
+ assert_equal '50% (1/2)', condition_coverages[3], "greet condition-coverage mismatch"
120
+ # absolute: line 11 — only else branch taken => 50% (1/2)
121
+ assert_equal '50% (1/2)', condition_coverages[11], "absolute condition-coverage mismatch"
122
+ # unused_method: line 22 — neither branch taken => 0% (0/2)
123
+ assert_equal '0% (0/2)', condition_coverages[22], "unused_method condition-coverage mismatch"
124
+ end
125
+
126
+ def test_merged_results_exercise_string_condition_keys
127
+ install_fixture('sample')
128
+
129
+ stdout, stderr, status = run_fixture_test('test/test_merged_a.rb',
130
+ 'COMMAND_NAME' => 'Run A')
131
+ assert status.success?, "Run A failed.\nstdout: #{stdout}\nstderr: #{stderr}"
132
+
133
+ # Tripwire: confirm the stored resultset actually contains stringified
134
+ # condition keys. If a future simplecov changes its serialization, this
135
+ # assertion fails and tells you this test no longer covers the string path.
136
+ resultset = File.read(File.join(@tmpdir, 'coverage', '.resultset.json'))
137
+ assert_match(/\[:if, \d+, \d+/, resultset,
138
+ 'Expected stringified branch condition keys in .resultset.json')
139
+
140
+ stdout, stderr, status = run_fixture_test('test/test_merged_b.rb',
141
+ 'COMMAND_NAME' => 'Run B')
142
+ assert status.success?, "Run B failed.\nstdout: #{stdout}\nstderr: #{stderr}"
143
+
144
+ doc = Nokogiri::XML(File.read(File.join(@tmpdir, 'coverage', 'coverage.xml'))) { |c| c.strict }
145
+ sample_class = doc.xpath('//class').find { |c| c['filename'].include?('sample.rb') }
146
+ assert_not_nil sample_class
147
+
148
+ cc = sample_class.xpath('.//line[@branch="true"]')
149
+ .map { |l| [l['number'].to_i, l['condition-coverage']] }
150
+ .to_h
151
+
152
+ # greet (line 3): else in Run A + then in Run B => merged 2/2.
153
+ # Proves string keys were parsed AND hit counts summed across runs.
154
+ assert_equal '100% (2/2)', cc[3], 'greet should be fully covered after merge'
155
+ # absolute (line 11): only Run A touched it => still 1/2.
156
+ assert_equal '50% (1/2)', cc[11]
157
+ # unused_method (line 22): never called in either run => 0/2.
158
+ assert_equal '0% (0/2)', cc[22]
159
+ end
160
+
161
+ private
162
+
163
+ def install_fixture(name)
164
+ FileUtils.cp_r(File.join(FIXTURES_DIR, name, '.'), @tmpdir)
165
+ end
166
+
167
+ def run_fixture_test(test_path, extra_env = {})
168
+ Open3.capture3(
169
+ { 'GEM_ROOT' => GEM_ROOT, 'PROJECT_ROOT' => @tmpdir }.merge(extra_env),
170
+ 'ruby', File.join(@tmpdir, test_path),
171
+ chdir: @tmpdir
172
+ )
173
+ end
174
+
175
+ end
@@ -1,4 +1,6 @@
1
1
  require 'test/unit'
2
+ require 'fileutils'
3
+ require 'tmpdir'
2
4
  require 'nokogiri'
3
5
  require 'open-uri'
4
6
  require 'simplecov'
@@ -6,26 +8,35 @@ require 'simplecov-cobertura'
6
8
 
7
9
  class CoberturaFormatterTest < Test::Unit::TestCase
8
10
  def setup
11
+ @tmpdir = Dir.mktmpdir('simplecov-cobertura-test')
9
12
  SimpleCov.enable_coverage :branch
10
- SimpleCov.coverage_dir "tmp"
13
+ SimpleCov.coverage_dir @tmpdir
14
+ @no_filter = SimpleCov::Result::FilterConfig.new(filters: [], cover_filters: [], groups: {})
11
15
  @result = SimpleCov::Result.new({
12
- "#{__FILE__}" => {
13
- "lines" => [1, 1, 1, nil, 1, nil, 1, 0, nil, 1, nil, nil, nil],
14
- "branches" => {
15
- [:if, 0, 3, 4, 3, 21] =>
16
- {[:then, 1, 3, 4, 3, 10] => 0, [:else, 2, 3, 4, 3, 21] => 1},
17
- [:if, 3, 5, 4, 5, 26] =>
18
- {[:then, 4, 5, 16, 5, 20] => 1, [:else, 5, 5, 23, 5, 26] => 0},
19
- [:if, 6, 7, 4, 11, 7] =>
20
- {[:then, 7, 8, 6, 8, 10] => 0, [:else, 8, 10, 6, 10, 9] => 1}
21
- }
22
- }
23
- })
16
+ "#{__FILE__}" => {
17
+ "lines" => [1, 1, 1, nil, 1, nil, 1, 0, nil, 1, nil, nil, nil],
18
+ "branches" => {
19
+ [:if, 0, 3, 4, 3, 21] =>
20
+ { [:then, 1, 3, 4, 3, 10] => 0, [:else, 2, 3, 4, 3, 21] => 1 },
21
+ [:if, 3, 5, 4, 5, 26] =>
22
+ { [:then, 4, 5, 16, 5, 20] => 1, [:else, 5, 5, 23, 5, 26] => 0 },
23
+ [:if, 6, 7, 4, 11, 7] =>
24
+ { [:then, 7, 8, 6, 8, 10] => 0, [:else, 8, 10, 6, 10, 9] => 1 },
25
+ [:if, 9, 12, 4, 12, 15] =>
26
+ { [:then, 10, 12, 6, 12, 10] => 1, [:else, 11, 12, 13, 12, 15] => 0 },
27
+ [:if, 12, 13, 4, 13, 20] =>
28
+ { [:then, 13, 13, 6, 13, 15] => 1, [:else, 14, 13, 18, 13, 20] => 0 },
29
+ [:if, 15, 15, 4, 15, 25] =>
30
+ { [:then, 16, 15, 6, 15, 20] => 0, [:else, 17, 15, 23, 15, 25] => 0 }
31
+ }
32
+ }
33
+ }, filter_config: @no_filter)
24
34
  @formatter = SimpleCov::Formatter::CoberturaFormatter.new
25
35
  end
26
36
 
27
37
  def teardown
28
38
  SimpleCov.groups.clear
39
+ FileUtils.remove_entry(@tmpdir) if @tmpdir && Dir.exist?(@tmpdir)
29
40
  end
30
41
 
31
42
  def test_format_save_file
@@ -45,28 +56,32 @@ class CoberturaFormatterTest < Test::Unit::TestCase
45
56
  def test_terminal_output
46
57
  output, _ = capture_output { @formatter.format(@result) }
47
58
  result_path = File.join(SimpleCov.coverage_path, SimpleCov::Formatter::CoberturaFormatter::RESULT_FILE_NAME)
48
- output_regex = /Coverage report generated for #{@result.command_name} to #{result_path}. (.*) covered./
59
+ output_regex = /Coverage report generated for #{@result.command_name} to #{result_path}.\nLine Coverage: (.*)\nBranch Coverage: (.*)/
49
60
  assert_match(output_regex, output)
50
61
  end
51
62
 
52
- def test_format_dtd_validates
53
- xml = @formatter.format(@result)
54
- options = Nokogiri::XML::ParseOptions::DTDLOAD
55
- doc = Nokogiri::XML::Document.parse(xml, nil, nil, options)
56
- assert_empty doc.external_subset.validate(doc)
57
- end
63
+ # Rather than support HTTPS the HTTP client was removed from libxml2 / xmllint:
64
+ # https://gitlab.gnome.org/GNOME/libxml2/-/issues/160
65
+ # I am not sure what this means for Nokogiri or this issue, but it certainly means something will change soon.
66
+ # Disable this test until it becomes clear what the new behavior should be.
67
+ # def test_format_dtd_validates
68
+ # xml = @formatter.format(@result)
69
+ # options = Nokogiri::XML::ParseOptions::DTDLOAD
70
+ # doc = Nokogiri::XML::Document.parse(xml, nil, nil, options)
71
+ # assert_empty doc.external_subset.validate(doc)
72
+ # end
58
73
 
59
74
  def test_no_groups
60
75
  xml = @formatter.format(@result)
61
76
  doc = Nokogiri::XML::Document.parse(xml)
62
77
 
63
78
  coverage = doc.xpath '/coverage'
64
- assert_equal '0.86', coverage.attribute('line-rate').value
65
- assert_equal '0.5', coverage.attribute('branch-rate').value
79
+ assert_equal '0.8571', coverage.attribute('line-rate').value
80
+ assert_equal '0.4167', coverage.attribute('branch-rate').value
66
81
  assert_equal '6', coverage.attribute('lines-covered').value
67
82
  assert_equal '7', coverage.attribute('lines-valid').value
68
- assert_equal '3', coverage.attribute('branches-covered').value
69
- assert_equal '6', coverage.attribute('branches-valid').value
83
+ assert_equal '5', coverage.attribute('branches-covered').value
84
+ assert_equal '12', coverage.attribute('branches-valid').value
70
85
  assert_equal '0', coverage.attribute('complexity').value
71
86
  assert_equal '0', coverage.attribute('version').value
72
87
  assert_not_empty coverage.attribute('timestamp').value
@@ -79,17 +94,17 @@ class CoberturaFormatterTest < Test::Unit::TestCase
79
94
  assert_equal 1, packages.length
80
95
  package = packages.first
81
96
  assert_equal 'simplecov-cobertura', package.attribute('name').value
82
- assert_equal '0.86', package.attribute('line-rate').value
83
- assert_equal '0.5', package.attribute('branch-rate').value
97
+ assert_equal '0.8571', package.attribute('line-rate').value
98
+ assert_equal '0.4167', package.attribute('branch-rate').value
84
99
  assert_equal '0', package.attribute('complexity').value
85
100
 
86
101
  classes = doc.xpath '/coverage/packages/package/classes/class'
87
102
  assert_equal 1, classes.length
88
103
  clazz = classes.first
89
- assert_equal 'simplecov-cobertura_test', clazz.attribute('name').value
104
+ assert_equal 'test/simplecov-cobertura_test.rb', clazz.attribute('name').value
90
105
  assert_equal 'test/simplecov-cobertura_test.rb', clazz.attribute('filename').value
91
- assert_equal '0.86', clazz.attribute('line-rate').value
92
- assert_equal '0.5', clazz.attribute('branch-rate').value
106
+ assert_equal '0.8571', clazz.attribute('line-rate').value
107
+ assert_equal '0.4167', clazz.attribute('branch-rate').value
93
108
  assert_equal '0', clazz.attribute('complexity').value
94
109
 
95
110
  lines = doc.xpath '/coverage/packages/package/classes/class/lines/line'
@@ -100,23 +115,38 @@ class CoberturaFormatterTest < Test::Unit::TestCase
100
115
  assert_equal '1', first_line.attribute('hits').value
101
116
  last_line = lines.last
102
117
  assert_equal '10', last_line.attribute('number').value
103
- assert_equal 'true', last_line.attribute('branch').value
118
+ assert_equal 'false', last_line.attribute('branch').value
104
119
  assert_equal '1', last_line.attribute('hits').value
120
+
121
+ # Verify condition-coverage accurately reflects branch counts per condition line
122
+ branched_lines = lines.select { |l| l.attribute('branch').value == 'true' }
123
+ condition_coverages = branched_lines.map { |l| [l.attribute('number').value, l.attribute('condition-coverage').value] }
124
+ # Line 3: condition [:if, 0, 3, ...] with 2 branches (then=>0, else=>1) => 50% (1/2)
125
+ assert_include condition_coverages, ['3', '50% (1/2)']
126
+ # Line 5: condition [:if, 3, 5, ...] with 2 branches (then=>1, else=>0) => 50% (1/2)
127
+ assert_include condition_coverages, ['5', '50% (1/2)']
128
+ # Line 7: condition [:if, 6, 7, ...] with 2 branches (then=>0, else=>1) => 50% (1/2)
129
+ assert_include condition_coverages, ['7', '50% (1/2)']
130
+ # Lines 12, 13, 15 have nil line coverage so they don't get <line> elements,
131
+ # but their conditions are still correctly grouped by condition start line.
132
+ assert_equal 3, branched_lines.length
105
133
  end
106
134
 
107
135
  def test_groups
108
- SimpleCov.add_group('test_group', 'test/')
136
+ SimpleCov.group('test_group', 'test/')
137
+ group_filter = SimpleCov::Result::FilterConfig.new(filters: [], cover_filters: [], groups: SimpleCov.groups)
138
+ result = SimpleCov::Result.new(@result.original_result, filter_config: group_filter)
109
139
 
110
- xml = @formatter.format(@result)
140
+ xml = @formatter.format(result)
111
141
  doc = Nokogiri::XML::Document.parse(xml)
112
142
 
113
143
  coverage = doc.xpath '/coverage'
114
- assert_equal '0.86', coverage.attribute('line-rate').value
115
- assert_equal '0.5', coverage.attribute('branch-rate').value
144
+ assert_equal '0.8571', coverage.attribute('line-rate').value
145
+ assert_equal '0.4167', coverage.attribute('branch-rate').value
116
146
  assert_equal '6', coverage.attribute('lines-covered').value
117
147
  assert_equal '7', coverage.attribute('lines-valid').value
118
- assert_equal '3', coverage.attribute('branches-covered').value
119
- assert_equal '6', coverage.attribute('branches-valid').value
148
+ assert_equal '5', coverage.attribute('branches-covered').value
149
+ assert_equal '12', coverage.attribute('branches-valid').value
120
150
  assert_equal '0', coverage.attribute('complexity').value
121
151
  assert_equal '0', coverage.attribute('version').value
122
152
  assert_not_empty coverage.attribute('timestamp').value
@@ -129,17 +159,17 @@ class CoberturaFormatterTest < Test::Unit::TestCase
129
159
  assert_equal 1, packages.length
130
160
  package = packages.first
131
161
  assert_equal 'test_group', package.attribute('name').value
132
- assert_equal '0.86', package.attribute('line-rate').value
133
- assert_equal '0.5', package.attribute('branch-rate').value
162
+ assert_equal '0.8571', package.attribute('line-rate').value
163
+ assert_equal '0.4167', package.attribute('branch-rate').value
134
164
  assert_equal '0', package.attribute('complexity').value
135
165
 
136
166
  classes = doc.xpath '/coverage/packages/package/classes/class'
137
167
  assert_equal 1, classes.length
138
168
  clazz = classes.first
139
- assert_equal 'simplecov-cobertura_test', clazz.attribute('name').value
169
+ assert_equal 'test/simplecov-cobertura_test.rb', clazz.attribute('name').value
140
170
  assert_equal 'test/simplecov-cobertura_test.rb', clazz.attribute('filename').value
141
- assert_equal '0.86', clazz.attribute('line-rate').value
142
- assert_equal '0.5', clazz.attribute('branch-rate').value
171
+ assert_equal '0.8571', clazz.attribute('line-rate').value
172
+ assert_equal '0.4167', clazz.attribute('branch-rate').value
143
173
  assert_equal '0', clazz.attribute('complexity').value
144
174
 
145
175
  lines = doc.xpath '/coverage/packages/package/classes/class/lines/line'
@@ -150,24 +180,34 @@ class CoberturaFormatterTest < Test::Unit::TestCase
150
180
  assert_equal '1', first_line.attribute('hits').value
151
181
  last_line = lines.last
152
182
  assert_equal '10', last_line.attribute('number').value
153
- assert_equal 'true', last_line.attribute('branch').value
183
+ assert_equal 'false', last_line.attribute('branch').value
154
184
  assert_equal '1', last_line.attribute('hits').value
155
185
  end
156
186
 
157
187
  def test_supports_root_project_path
158
188
  old_root = SimpleCov.root
159
- SimpleCov.root("/tmp")
160
- expected_base = old_root[1..-1] # Remove leading "/"
161
-
162
- xml = @formatter.format(@result)
189
+ @alt_root = Dir.mktmpdir('simplecov-cobertura-root')
190
+ SimpleCov.root(@alt_root)
191
+ expected_prefix = Pathname.new(old_root).relative_path_from(Pathname.new(@alt_root)).to_s
192
+ result = SimpleCov::Result.new(@result.original_result, filter_config: @no_filter)
193
+ xml = @formatter.format(result)
163
194
  doc = Nokogiri::XML::Document.parse(xml)
164
195
 
165
196
  classes = doc.xpath '/coverage/packages/package/classes/class'
166
197
  assert_equal 1, classes.length
167
198
  clazz = classes.first
168
- assert_equal 'simplecov-cobertura_test', clazz.attribute('name').value
169
- assert_equal "../#{expected_base}/test/simplecov-cobertura_test.rb", clazz.attribute('filename').value
199
+ assert_equal "#{expected_prefix}/test/simplecov-cobertura_test.rb", clazz.attribute('name').value
200
+ assert_equal "#{expected_prefix}/test/simplecov-cobertura_test.rb", clazz.attribute('filename').value
170
201
  ensure
171
202
  SimpleCov.root(old_root)
203
+ FileUtils.remove_entry(@alt_root) if @alt_root && Dir.exist?(@alt_root)
204
+ end
205
+
206
+ def test_condition_start_line_handles_both_key_forms
207
+ formatter = SimpleCov::Formatter::CoberturaFormatter.new
208
+ assert_equal 3, formatter.send(:condition_start_line, [:if, 0, 3, 4, 5, 10])
209
+ assert_equal 3, formatter.send(:condition_start_line, '[:if, 0, 3, 4, 5, 10]')
210
+ assert_equal 7, formatter.send(:condition_start_line, '[:case, 12, 7, 0, 9, 3]')
211
+ assert_nil formatter.send(:condition_start_line, 42)
172
212
  end
173
213
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simplecov-cobertura
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jesse Bowes
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2021-12-14 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: test-unit
@@ -58,14 +57,14 @@ dependencies:
58
57
  requirements:
59
58
  - - "~>"
60
59
  - !ruby/object:Gem::Version
61
- version: '0.19'
60
+ version: '1.0'
62
61
  type: :runtime
63
62
  prerelease: false
64
63
  version_requirements: !ruby/object:Gem::Requirement
65
64
  requirements:
66
65
  - - "~>"
67
66
  - !ruby/object:Gem::Version
68
- version: '0.19'
67
+ version: '1.0'
69
68
  - !ruby/object:Gem::Dependency
70
69
  name: rexml
71
70
  requirement: !ruby/object:Gem::Requirement
@@ -82,7 +81,7 @@ dependencies:
82
81
  version: '0'
83
82
  description: Produces Cobertura XML formatted output from SimpleCov
84
83
  email:
85
- - jbowes@dashingrocket.com
84
+ - jessebowes@acm.org
86
85
  executables: []
87
86
  extensions: []
88
87
  extra_rdoc_files: []
@@ -96,13 +95,17 @@ files:
96
95
  - lib/simplecov-cobertura.rb
97
96
  - lib/simplecov-cobertura/version.rb
98
97
  - simplecov-cobertura.gemspec
99
- - test/coverage/coverage.xml
98
+ - test/fixtures/sample/lib/sample.rb
99
+ - test/fixtures/sample/test/simplecov_setup.rb
100
+ - test/fixtures/sample/test/test_merged_a.rb
101
+ - test/fixtures/sample/test/test_merged_b.rb
102
+ - test/fixtures/sample/test/test_sample.rb
103
+ - test/integration_test.rb
100
104
  - test/simplecov-cobertura_test.rb
101
- homepage: https://github.com/dashingrocket/simplecov-cobertura
105
+ homepage: https://github.com/jessebs/simplecov-cobertura
102
106
  licenses:
103
107
  - Apache-2.0
104
108
  metadata: {}
105
- post_install_message:
106
109
  rdoc_options: []
107
110
  require_paths:
108
111
  - lib
@@ -110,17 +113,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
110
113
  requirements:
111
114
  - - ">="
112
115
  - !ruby/object:Gem::Version
113
- version: 2.5.0
116
+ version: '3.2'
114
117
  required_rubygems_version: !ruby/object:Gem::Requirement
115
118
  requirements:
116
119
  - - ">="
117
120
  - !ruby/object:Gem::Version
118
121
  version: '0'
119
122
  requirements: []
120
- rubygems_version: 3.2.22
121
- signing_key:
123
+ rubygems_version: 3.6.9
122
124
  specification_version: 4
123
125
  summary: SimpleCov Cobertura Formatter
124
126
  test_files:
125
- - test/coverage/coverage.xml
127
+ - test/fixtures/sample/lib/sample.rb
128
+ - test/fixtures/sample/test/simplecov_setup.rb
129
+ - test/fixtures/sample/test/test_merged_a.rb
130
+ - test/fixtures/sample/test/test_merged_b.rb
131
+ - test/fixtures/sample/test/test_sample.rb
132
+ - test/integration_test.rb
126
133
  - test/simplecov-cobertura_test.rb
@@ -1,21 +0,0 @@
1
- <?xml version='1.0'?>
2
- <!DOCTYPE coverage SYSTEM "http://cobertura.sourceforge.net/xml/coverage-04.dtd">
3
- <!-- Generated by simplecov-cobertura version 1.4.3-dev (https://github.com/dashingrocket/simplecov-cobertura) -->
4
- <coverage line-rate="1.0" branch-rate="0" lines-covered="2" lines-valid="2" branches-covered="0" branches-valid="0" complexity="0" version="0" timestamp="1636204971">
5
- <sources>
6
- <source>/Users/st0012/projects/simplecov-cobertura/test</source>
7
- </sources>
8
- <packages>
9
- <package name="test" line-rate="1.0" branch-rate="0" complexity="0">
10
- <classes>
11
- <class name="simplecov-cobertura_test" filename="simplecov-cobertura_test.rb" line-rate="1.0" branch-rate="0" complexity="0">
12
- <methods/>
13
- <lines>
14
- <line number="1" branch="false" hits="1"/>
15
- <line number="2" branch="false" hits="2"/>
16
- </lines>
17
- </class>
18
- </classes>
19
- </package>
20
- </packages>
21
- </coverage>