Skip to content

Merge in simplecov_json_formatter. #1130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ PATH
simplecov (0.22.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)

GEM
remote: https://rubygems.org/
Expand Down Expand Up @@ -142,7 +141,6 @@ GEM
parser (>= 3.3.1.0)
ruby-progressbar (1.13.0)
simplecov-html (0.13.1)
simplecov_json_formatter (0.1.4)
spoon (0.0.6)
ffi
sys-uname (1.3.1)
Expand Down Expand Up @@ -192,4 +190,4 @@ DEPENDENCIES
webrick

BUNDLED WITH
2.7.0.dev
2.6.9
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -869,18 +869,17 @@ SimpleCov.formatters = [

## JSON formatter

SimpleCov is packaged with a separate gem called [simplecov_json_formatter](https://github.com/codeclimate-community/simplecov_json_formatter) that provides you with a JSON formatter, this formatter could be useful for different use cases, such as for CI consumption or for reporting to external services.

In order to use it you will need to manually load the installed gem like so:
SimpleCov is packaged with a `SimpleCov::Formatter::JSONFormatter` that provides you with a JSON formatter, this formatter could be useful for different use cases, such as for CI consumption or for reporting to external services.

```ruby
require "simplecov_json_formatter"
SimpleCov.formatter = SimpleCov::Formatter::JSONFormatter
```

> _Note:_ In case you plan to report your coverage results to CodeClimate services, know that SimpleCov will automatically use the
> JSON formatter along with the HTML formatter when the `CC_TEST_REPORTER_ID` variable is present in the environment.

> This exporter was originally separate [simplecov_json_formatter](https://github.com/codeclimate-community/simplecov_json_formatter) gem and it was needed to require manually using `require 'simplecov_json_formatter'`. Currently it is loaded by default.

## Available formatters, editor integrations and hosted services

* [Open Source formatter and integration plugins for SimpleCov](doc/alternate-formatters.md)
Expand Down
1 change: 0 additions & 1 deletion features/config_json_formatter.feature
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ Feature:
Given SimpleCov for Test/Unit is configured with:
"""
require 'simplecov'
require 'simplecov_json_formatter'
SimpleCov.formatter = SimpleCov::Formatter::JSONFormatter
SimpleCov.at_exit do
puts SimpleCov.result.format!
Expand Down
5 changes: 1 addition & 4 deletions lib/simplecov/default_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ def from_env(env)
formatters = [SimpleCov::Formatter::HTMLFormatter]

# When running under a CI that uses CodeClimate, JSON output is expected
if env.fetch("CC_TEST_REPORTER_ID", nil)
require "simplecov_json_formatter"
formatters.push(SimpleCov::Formatter::JSONFormatter)
end
formatters.push(SimpleCov::Formatter::JSONFormatter) if env.fetch("CC_TEST_REPORTER_ID", nil)

formatters
end
Expand Down
1 change: 1 addition & 0 deletions lib/simplecov/formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ module Formatter

require_relative "formatter/simple_formatter"
require_relative "formatter/multi_formatter"
require_relative "formatter/json_formatter"
36 changes: 36 additions & 0 deletions lib/simplecov/formatter/json_formatter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true

require_relative "json_formatter/result_hash_formatter"
require_relative "json_formatter/result_exporter"
require "json"

module SimpleCov
module Formatter
class JSONFormatter
def format(result, verbose: true)
result_hash = format_result(result)

export_formatted_result(result_hash)

puts output_message(result) if verbose
end

private

def format_result(result)
result_hash_formater = ResultHashFormatter.new(result)
result_hash_formater.format
end

def export_formatted_result(result_hash)
result_exporter = ResultExporter.new(result_hash)
result_exporter.export
end

def output_message(result)
"JSON Coverage report generated for #{result.command_name} to #{SimpleCov.coverage_path}. " \
"#{result.covered_lines} / #{result.total_lines} LOC (#{result.covered_percent.round(2)}%) covered."
end
end
end
end
31 changes: 31 additions & 0 deletions lib/simplecov/formatter/json_formatter/result_exporter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

module SimpleCov
module Formatter
class JSONFormatter
class ResultExporter
FILENAME = "coverage.json"

def initialize(result_hash)
@result = result_hash
end

def export
File.open(export_path, "w") do |file|
file << json_result
end
end

private

def json_result
JSON.pretty_generate(@result)
end

def export_path
File.join(SimpleCov.coverage_path, FILENAME)
end
end
end
end
end
56 changes: 56 additions & 0 deletions lib/simplecov/formatter/json_formatter/result_hash_formatter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# frozen_string_literal: true

require_relative "source_file_formatter"

module SimpleCov
module Formatter
class JSONFormatter
class ResultHashFormatter
def initialize(result)
@result = result
end

def format
format_files
format_groups

formatted_result
end

private

def format_files
@result.files.each do |source_file|
formatted_result[:coverage][source_file.filename] =
format_source_file(source_file)
end
end

def format_groups
@result.groups.each do |name, file_list|
formatted_result[:groups][name] = {
lines: {
covered_percent: file_list.covered_percent
}
}
end
end

def formatted_result
@formatted_result ||= {
meta: {
simplecov_version: SimpleCov::VERSION
},
coverage: {},
groups: {}
}
end

def format_source_file(source_file)
source_file_formatter = SourceFileFormatter.new(source_file)
source_file_formatter.format
end
end
end
end
end
63 changes: 63 additions & 0 deletions lib/simplecov/formatter/json_formatter/source_file_formatter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# frozen_string_literal: true

module SimpleCov
module Formatter
class JSONFormatter
class SourceFileFormatter
def initialize(source_file)
@source_file = source_file
@line_coverage = nil
end

def format
if SimpleCov.branch_coverage?
line_coverage.merge(branch_coverage)
else
line_coverage
end
end

private

def line_coverage
@line_coverage ||= {
lines: lines
}
end

def branch_coverage
{
branches: branches
}
end

def lines
@source_file.lines.collect do |line|
parse_line(line)
end
end

def branches
@source_file.branches.collect do |branch|
parse_branch(branch)
end
end

def parse_line(line)
return line.coverage unless line.skipped?

"ignored"
end

def parse_branch(branch)
{
type: branch.type,
start_line: branch.start_line,
end_line: branch.end_line,
coverage: parse_line(branch)
}
end
end
end
end
end
1 change: 0 additions & 1 deletion simplecov.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ Gem::Specification.new do |gem|

gem.add_dependency "docile", "~> 1.1"
gem.add_dependency "simplecov-html", "~> 0.11"
gem.add_dependency "simplecov_json_formatter", "~> 0.1"

gem.files = Dir["{lib}/**/*.*", "bin/*", "LICENSE", "CHANGELOG.md", "README.md", "doc/*"]
gem.require_paths = ["lib"]
Expand Down
1 change: 0 additions & 1 deletion spec/default_formatter_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# frozen_string_literal: true

require "helper"
require "simplecov_json_formatter"

describe SimpleCov::Formatter do
describe ".from_env" do
Expand Down
37 changes: 37 additions & 0 deletions spec/fixtures/json/sample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"meta": {
"simplecov_version": "0.22.0"
},
"coverage": {
"/STUB_WORKING_DIRECTORY/spec/fixtures/json/sample.rb": {
"lines": [
null,
1,
1,
1,
1,
null,
null,
1,
1,
null,
null,
1,
1,
0,
null,
1,
null,
null,
null,
"ignored",
"ignored",
"ignored",
"ignored",
"ignored",
null
]
}
},
"groups": {}
}
25 changes: 25 additions & 0 deletions spec/fixtures/json/sample.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Foo class
class Foo
def initialize
@foo = "bar"
@bar = "foo"
end

def bar
@foo
end

def foo(param)
if param
@bar
else
@foo
end
end

# :nocov:
def skipped
@foo * 2
end
# :nocov:
end
43 changes: 43 additions & 0 deletions spec/fixtures/json/sample_groups.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"meta": {
"simplecov_version": "0.22.0"
},
"coverage": {
"/STUB_WORKING_DIRECTORY/spec/fixtures/json/sample.rb": {
"lines": [
null,
1,
1,
1,
1,
null,
null,
1,
1,
null,
null,
1,
1,
0,
null,
1,
null,
null,
null,
"ignored",
"ignored",
"ignored",
"ignored",
"ignored",
null
]
}
},
"groups": {
"My Group": {
"lines": {
"covered_percent": 80.0
}
}
}
}
Loading