Skip to content

Commit

Permalink
[Fix rubocop#9780] Support summary report for JUnitFormatter
Browse files Browse the repository at this point in the history
Fixes rubocop#9780.

This PR supports summary report for `JUnitFormatter`.

It adds the following attributes to the `<testsuite>` element.

- `tests` attribute ... Inspected file count.
- `failures` attribute ... Total offense count.

This is a JUnit format example:

```xml
% rubocop -f junit --display-only-failed lib/rubocop/formatter/junit_formatter.rb
<?xml version='1.0'?>
<testsuites>
  <testsuite name='rubocop' tests='1' failures='2'>
    <testcase classname='lib.rubocop.formatter.junit_formatter' name='Layout/LineLength'>
      <failure type='Layout/LineLength' message='Layout/LineLength: Line is too long. [110/100]'>
        /Users/koic/src/github.com/rubocop/rubocop/lib/rubocop/formatter/junit_formatter.rb:65:101
      </failure>
    </testcase>
    <testcase classname='lib.rubocop.formatter.junit_formatter' name='Metrics/AbcSize'>
      <failure type='Metrics/AbcSize' message='Metrics/AbcSize:
Assignment Branch Condition size for file_finished is too high. [&lt;8, 16, 2&gt; 18/17]'>
        /Users/koic/src/github.com/rubocop/rubocop/lib/rubocop/formatter/junit_formatter.rb:29:7
      </failure>
    </testcase>
  </testsuite>
</testsuites>
```

These mean the values of `1 file inspected` and `2 offenses detected` below.

```console
% rubocop lib/rubocop/formatter/junit_formatter.rb
Inspecting 1 file
(snip)

1 file inspected, 2 offenses detected, 2 offenses auto-correctable
```
  • Loading branch information
koic committed May 6, 2021
1 parent 4a4ad98 commit 5922b24
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 8 deletions.
@@ -0,0 +1 @@
* [#9780](https://github.com/rubocop/rubocop/issues/9780): Support summary report for `JUnitFormatter`. ([@koic][])
2 changes: 1 addition & 1 deletion docs/modules/ROOT/pages/formatters.adoc
Expand Up @@ -260,7 +260,7 @@ This formatter is based on the https://github.com/mikian/rubocop-junit-formatter
$ rubocop --format junit
<?xml version='1.0'?>
<testsuites>
<testsuite name='rubocop'>
<testsuite name='rubocop' tests='2' failures='2'>
<testcase classname='example' name='Style/FrozenStringLiteralComment'>
<failure type='Style/FrozenStringLiteralComment' message='Style/FrozenStringLiteralComment: Missing frozen string literal comment.'>
/tmp/src/example.rb:1:1
Expand Down
27 changes: 21 additions & 6 deletions lib/rubocop/formatter/junit_formatter.rb
Expand Up @@ -22,25 +22,25 @@ def initialize(output, options = {})
testsuites = REXML::Element.new('testsuites', @document)
testsuite = REXML::Element.new('testsuite', testsuites)
@testsuite = testsuite.tap { |element| element.add_attributes('name' => 'rubocop') }

reset_count
end

def file_finished(file, offenses)
@inspected_file_count += 1

# TODO: Returns all cops with the same behavior as
# the original rubocop-junit-formatter.
# https://github.com/mikian/rubocop-junit-formatter/blob/v0.1.4/lib/rubocop/formatter/junit_formatter.rb#L9
#
# In the future, it would be preferable to return only enabled cops.
Cop::Registry.all.each do |cop|
target_offenses = offenses_for_cop(offenses, cop)
@offense_count += target_offenses.count

next unless relevant_for_output?(options, target_offenses)

REXML::Element.new('testcase', @testsuite).tap do |testcase|
testcase.attributes['classname'] = classname_attribute_value(file)
testcase.attributes['name'] = cop.cop_name

add_failure_to(testcase, target_offenses, cop.cop_name)
end
add_testcase_element_to_testsuite_element(file, target_offenses, cop)
end
end

Expand All @@ -52,16 +52,31 @@ def offenses_for_cop(all_offenses, cop)
all_offenses.select { |offense| offense.cop_name == cop.cop_name }
end

def add_testcase_element_to_testsuite_element(file, target_offenses, cop)
REXML::Element.new('testcase', @testsuite).tap do |testcase|
testcase.attributes['classname'] = classname_attribute_value(file)
testcase.attributes['name'] = cop.cop_name

add_failure_to(testcase, target_offenses, cop.cop_name)
end
end

def classname_attribute_value(file)
file.gsub(/\.rb\Z/, '').gsub("#{Dir.pwd}/", '').tr('/', '.')
end

def finished(_inspected_files)
@testsuite.add_attributes('tests' => @inspected_file_count, 'failures' => @offense_count)
@document.write(output, 2)
end

private

def reset_count
@inspected_file_count = 0
@offense_count = 0
end

def add_failure_to(testcase, offenses, cop_name)
# One failure per offense. Zero failures is a passing test case,
# for most surefire/nUnit parsers.
Expand Down
2 changes: 1 addition & 1 deletion spec/rubocop/formatter/junit_formatter_spec.rb
Expand Up @@ -27,7 +27,7 @@
expect(output.string).to start_with(<<~XML)
<?xml version='1.0'?>
<testsuites>
<testsuite name='rubocop'>
<testsuite name='rubocop' tests='2' failures='4'>
XML
end

Expand Down

0 comments on commit 5922b24

Please sign in to comment.