-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
217 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ PATH | |
remote: . | ||
specs: | ||
simplecov-inline (0.1.0) | ||
rainbow (~> 3.1) | ||
simplecov (~> 0.22) | ||
|
||
GEM | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
require_relative 'inline/version' | ||
require_relative 'inline/formatter' | ||
|
||
module SimpleCov | ||
module Inline | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
require 'rainbow' | ||
|
||
module Simplecov | ||
module Inline | ||
class Formatter | ||
Result = Struct.new(:file, :start_line, :end_line, :type) do | ||
def to_s | ||
lines = [start_line, end_line].uniq.join('-') | ||
"#{file}:#{lines} (#{type})" | ||
end | ||
end | ||
|
||
Config = Struct.new(:files) do | ||
def no_output!(reason:) | ||
@no_output = reason | ||
end | ||
|
||
attr_reader :no_output | ||
end | ||
|
||
def self.reset_config = @config = Config.new | ||
reset_config | ||
|
||
def self.config(&block) | ||
return @config if block.nil? | ||
|
||
block.call(@config) | ||
|
||
return if @config.files.nil? | ||
|
||
@config.files = @config.files.to_set.freeze | ||
end | ||
|
||
def format(result, putter: Kernel) | ||
missing_coverage = process_files(filtered_files(result:).reject { |file| fully_covered?(file) }) | ||
success_message = build_success_message(missing_coverage:) | ||
|
||
if success_message | ||
putter.puts success_message | ||
return | ||
end | ||
|
||
putter.puts | ||
putter.puts Rainbow('Missing coverage:').yellow | ||
putter.puts Rainbow(missing_coverage).yellow | ||
putter.puts | ||
end | ||
|
||
private | ||
|
||
def build_success_message(missing_coverage:) | ||
if self.class.config.no_output | ||
return Rainbow("Coverage output skipped. Reason: #{self.class.config.no_output}.").yellow | ||
end | ||
|
||
return Rainbow("All branches covered (#{human_filter} files) ✔ ").green if missing_coverage.empty? | ||
|
||
nil | ||
end | ||
|
||
def fully_covered?(file) | ||
[file.covered_percent, file.branches_coverage_percent].all? { |coverage| coverage == 100 } | ||
end | ||
|
||
def human_filter | ||
self.class.config.files&.length || 'all' | ||
end | ||
|
||
def filtered_files(result:) | ||
filter = self.class.config.files | ||
|
||
return result.files if filter.nil? | ||
|
||
result.files.filter { |file| filter.include?(file.filename) } | ||
end | ||
|
||
def process_files(files) | ||
files.map do |file| | ||
[ | ||
build_line_coverage(file), | ||
build_branch_coverage(file), | ||
] | ||
end.flatten.compact.join("\n") | ||
end | ||
|
||
def build_line_coverage(file) | ||
file.missed_lines.map do |uncovered| | ||
# uncovered is a SimpleCov::SourceFile::Line | ||
Result.new(file.project_filename, uncovered.line_number, uncovered.line_number, 'line') | ||
end | ||
end | ||
|
||
def build_branch_coverage(file) | ||
file.missed_branches.map do |uncovered| | ||
# uncovered is a SimpleCov::SourceFile::Branch | ||
Result.new(file.project_filename, uncovered.report_line, uncovered.report_line, "branch:#{uncovered.type}") | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
class File1 | ||
def method(arg) | ||
arg ? 1 : 2 | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
class File2 | ||
def method(arg) | ||
arg ? 1 : 2 | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
RSpec.describe Simplecov::Inline::Formatter do | ||
after { described_class.reset_config } | ||
|
||
describe '#format' do | ||
subject { described_class.new.format(result, putter:) } | ||
|
||
let(:putter) { class_double(Kernel) } | ||
|
||
before { allow(putter).to receive(:puts) } | ||
|
||
context 'missing coverage' do | ||
let(:result) do | ||
SimpleCov::Result.new({ | ||
File.join(fixture_directory, 'file1.rb') => { | ||
# 0 means line 3 is uncovered | ||
'lines' => [1, 1, 0, 1, 1], | ||
# => 0 means the else branch is uncovered. | ||
# 2 is an idenditifier, 3 is the start line, 12 is the start col, 3 is the end line and 14 is the end col. | ||
'branches' => {[:if, 0, 3, 4, 3, 8] => {[:then, 1, 3, 8, 3, 10] => 1, [:else, 2, 3, 12, 3, 14] => 0}}, | ||
}, | ||
}) | ||
end | ||
|
||
it 'prints a yellow message saying coverage is missing' do | ||
subject | ||
|
||
expect(putter).to have_received(:puts).with(Rainbow('Missing coverage:').yellow) | ||
end | ||
|
||
it 'prints the missing lines and branches in yellow' do | ||
subject | ||
|
||
expect(putter).to have_received(:puts).with(Rainbow([ | ||
'/spec/fixtures/file1.rb:3 (line)', | ||
'/spec/fixtures/file1.rb:3 (branch:else)', | ||
].join("\n")).yellow) | ||
end | ||
end | ||
|
||
context 'fully covered' do | ||
let(:result) do | ||
SimpleCov::Result.new({ | ||
File.join(fixture_directory, 'file1.rb') => { | ||
'lines' => [1, 1, 1, 1, 1], | ||
'branches' => {[:if, 0, 3, 4, 3, 8] => {[:then, 1, 3, 8, 3, 10] => 1, [:else, 2, 3, 12, 3, 14] => 1}}, | ||
}, | ||
}) | ||
end | ||
|
||
it 'prints a green message saying fully covered' do | ||
subject | ||
expect(putter).to have_received(:puts).with(Rainbow('All branches covered (all files) ✔ ').green) | ||
end | ||
end | ||
|
||
context 'output disabled' do | ||
let(:result) { SimpleCov::Result.new({}) } | ||
|
||
before do | ||
described_class.config { |config| config.no_output!(reason: 'no output thanks') } | ||
end | ||
|
||
it 'prints a yellow message saying output is disabled' do | ||
subject | ||
expect(putter).to have_received(:puts).with(Rainbow('Coverage output skipped. Reason: no output thanks.').yellow) | ||
end | ||
end | ||
|
||
context 'filtering out of uncovered files' do | ||
let(:result) do | ||
SimpleCov::Result.new({ | ||
File.join(fixture_directory, 'file1.rb') => {'lines' => [1, 1, 1, 1, 1]}, | ||
File.join(fixture_directory, 'file2.rb') => {'lines' => [1, 1, 0, 1, 1]}, | ||
}) | ||
end | ||
|
||
before do | ||
described_class.config { |config| config.files = [File.join(fixture_directory, 'file1.rb')]} | ||
end | ||
|
||
it 'prints a green message saying fully covered, but notes only 1 file was considered' do | ||
subject | ||
expect(putter).to have_received(:puts).with(Rainbow('All branches covered (1 files) ✔ ').green) | ||
end | ||
end | ||
end | ||
|
||
describe '.config' do | ||
subject { described_class.config } | ||
|
||
it { is_expected.to have_attributes files: nil } | ||
it { is_expected.to respond_to :no_output! } | ||
|
||
it 'can change the files' do | ||
expect { described_class.config { |config| config.files = ['test.txt'] } } | ||
.to change { described_class.config.files } | ||
.from(nil) | ||
.to(['test.txt']) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters