From 7e4a7410eee4947ff1f083f719fd08f196d62ad2 Mon Sep 17 00:00:00 2001 From: Dana Sherson Date: Tue, 3 Nov 2020 17:25:18 +1100 Subject: [PATCH] Add branch coverage output This will only show if simlpecov is recording branch coverage, otherwise the output is unchanged The output does look kinda awkward and busy, but all i care about is actually being able to see output from CI without having to set up some kind of artifact hosting for the coverage/index.html fixes: #18 example output: Passing: ``` COVERAGE: 100.00% -- 1743/1743 lines in 108 files BRANCH COVERAGE: 100.00% -- 434/434 branches in 108 branches ``` Failing (block format): ``` COVERAGE: 100.00% -- 1743/1743 lines in 108 files BRANCH COVERAGE: 99.77% -- 434/435 branches in 108 branches file: lib/leftovers/config_validator/error_processor.rb coverage: 100.00% (96/96 lines) missed: branches: 96.97% (32/33 branches) missed: 112[else] ``` Failing (table format): ``` COVERAGE: 100.00% -- 1743/1743 lines in 108 files BRANCH COVERAGE: 99.77% -- 434/435 branches in 108 branches +----------+---------------------------------------------------+-------+--------+---------+-----------------+----------+-----------------+------------------+ | coverage | file | lines | missed | missing | branch coverage | branches | branches missed | branches missing | +----------+---------------------------------------------------+-------+--------+---------+-----------------+----------+-----------------+------------------+ | 100.00% | lib/leftovers/config_validator/error_processor.rb | 96 | 0 | | 96.97% | 33 | 1 | 112[else] | +----------+---------------------------------------------------+-------+--------+---------+-----------------+----------+-----------------+------------------+ ``` --- lib/simplecov-console.rb | 35 ++++++++++++++---- lib/simplecov-console/output/block.rb | 8 ++++- lib/simplecov-console/output/table.rb | 26 +++++++++++--- test/test_simplecov-console.rb | 52 +++++++++++++++++++++++++-- 4 files changed, 107 insertions(+), 14 deletions(-) diff --git a/lib/simplecov-console.rb b/lib/simplecov-console.rb index 14a1664..1e4b890 100644 --- a/lib/simplecov-console.rb +++ b/lib/simplecov-console.rb @@ -36,6 +36,11 @@ def include_output_style end end + def show_branch_coverage?(result) + Gem::Version.new(SimpleCov::VERSION) >= Gem::Version.new('0.18.5') && + result.coverage_statistics[:branch] + end + def format(result) include_output_style @@ -51,7 +56,11 @@ def format(result) end puts - puts "COVERAGE: #{colorize(pct(result))} -- #{result.covered_lines}/#{result.total_lines} lines in #{result.files.size} files" + puts "COVERAGE: #{colorize(pct(result.covered_percent))} -- #{result.covered_lines}/#{result.total_lines} lines in #{result.files.size} files" + show_branch_coverage = show_branch_coverage?(result) + if show_branch_coverage + puts "BRANCH COVERAGE: #{colorize(pct(result.coverage_statistics[:branch].percent))} -- #{result.covered_branches}/#{result.total_branches} branches in #{result.files.size} branches" + end puts if root.nil? then @@ -59,7 +68,14 @@ def format(result) end if SimpleCov::Formatter::Console.sort == 'coverage' - files = result.files.sort{ |a,b| a.covered_percent <=> b.covered_percent } + if show_branch_coverage + files = result.files.sort do |a,b| + (a.covered_percent <=> b.covered_percent).nonzero? || + (a.coverage_statistics[:branch].percent <=> b.coverage_statistics[:branch].percent) + end + else + files = result.files.sort_by(&:covered_percent) + end else files = result.files end @@ -68,7 +84,7 @@ def format(result) unless SimpleCov::Formatter::Console.show_covered files.select!{ |file| - if file.covered_percent == 100 then + if file.covered_percent == 100 && file.coverage_statistics[:branch].percent == 100 then covered_files += 1 false else @@ -87,7 +103,7 @@ def format(result) files = files.slice(0, max_rows) end - puts output(files,root) + puts output(files, root, show_branch_coverage) if covered_files > 0 then puts "#{covered_files} file(s) with 100% coverage not shown" @@ -95,6 +111,12 @@ def format(result) end + def branches_missed(missed_branches) + missed_branches.group_by(&:start_line).map do |line_number, branches| + "#{line_number}[#{branches.map(&:type).join(',')}]" + end + end + def missed(missed_lines) groups = {} base = nil @@ -123,8 +145,8 @@ def missed(missed_lines) group_str end - def pct(obj) - sprintf("%6.2f%%", obj.covered_percent) + def pct(number) + sprintf("%6.2f%%", number) end def use_colors? @@ -144,5 +166,4 @@ def colorize(s) ANSI.red { s } end end - end diff --git a/lib/simplecov-console/output/block.rb b/lib/simplecov-console/output/block.rb index 8fff894..66dd306 100644 --- a/lib/simplecov-console/output/block.rb +++ b/lib/simplecov-console/output/block.rb @@ -3,7 +3,7 @@ class SimpleCov::Formatter::Console module BlockOutput # format per-file results output as plain text blocks - def output(files, root) + def output(files, root, show_branch) blocks = [] files.each do |f| block = [] @@ -12,6 +12,12 @@ def output(files, root) colorize(sprintf("%.2f%%", f.covered_percent)), f.covered_lines.count, f.lines_of_code) block << sprintf("%8.8s: %s", 'missed', missed(f.missed_lines).join(", ")) + if show_branch + block << sprintf("%8.8s: %s (%d/%d branches)", 'branches', + colorize(sprintf("%.2f%%", f.coverage_statistics[:branch].percent)), + (f.total_branches.count - f.missed_branches.count), f.total_branches.count) + block << sprintf("%8.8s: %s", 'missed', branches_missed(f.missed_branches).join(", ")) + end blocks << block.join("\n") end diff --git a/lib/simplecov-console/output/table.rb b/lib/simplecov-console/output/table.rb index 19d9ccf..deb40de 100644 --- a/lib/simplecov-console/output/table.rb +++ b/lib/simplecov-console/output/table.rb @@ -4,15 +4,25 @@ class SimpleCov::Formatter::Console module TableOutput # format per-file results output using Terminal::Table - def output(files, root) + def output(files, root,show_branch) table = files.map do |f| - [ - colorize(pct(f)), + row = [ + colorize(pct(f.covered_percent)), f.filename.gsub(root + "/", ''), f.lines_of_code, f.missed_lines.count, - missed(f.missed_lines).join(", ") + missed(f.missed_lines).join(", "), ] + if show_branch + row += [ + colorize(pct(f.coverage_statistics[:branch].percent)), + f.total_branches.count, + f.missed_branches.count, + branches_missed(f.missed_branches).join(", ") + ] + end + + row end table_options = SimpleCov::Formatter::Console.table_options || {} @@ -21,6 +31,14 @@ def output(files, root) end headings = %w{ coverage file lines missed missing } + if show_branch + headings += [ + 'branch coverage', + 'branches', + 'branches missed', + 'branches missing' + ] + end opts = table_options.merge({:headings => headings, :rows => table}) Terminal::Table.new(opts) diff --git a/test/test_simplecov-console.rb b/test/test_simplecov-console.rb index ddc5054..8aad0c1 100644 --- a/test/test_simplecov-console.rb +++ b/test/test_simplecov-console.rb @@ -14,6 +14,24 @@ class TestSimplecovConsole < MiniTest::Test :covered_percent ) + CoverageStatistics = Struct.new( + :percent + ) + Branch = Struct.new( + :start_line, + :type + ) + SourceFileWithBranches = Struct.new( + :filename, + :lines_of_code, + :covered_lines, + :missed_lines, + :covered_percent, + :coverage_statistics, + :total_branches, + :missed_branches + ) + def setup @console = SimpleCov::Formatter::Console.new end @@ -40,7 +58,22 @@ def test_table_output files = [ SourceFile.new('foo.rb',5,[2,3],[Line.new(1), Line.new(4), Line.new(5)],40.0) ] - actual = @console.output(files,'/') + actual = @console.output(files,'/',false) + assert actual.is_a? Terminal::Table + assert_equal 1, actual.rows.count + end + + def test_table_output_with_branches + SimpleCov::Formatter::Console.output_style = 'table' + @console.include_output_style + files = [ + SourceFileWithBranches.new( + 'foo.rb',5,[2,3],[Line.new(1), Line.new(4), Line.new(5)],40.0, + {branch: CoverageStatistics.new(50.0)}, [1,2], + [Branch.new(2, :then)] + ) + ] + actual = @console.output(files,'/',true) assert actual.is_a? Terminal::Table assert_equal 1, actual.rows.count end @@ -54,6 +87,21 @@ def test_block_output SourceFile.new('foo.rb',5,[2,3],[Line.new(1), Line.new(4), Line.new(5)],40.0) ] expected = "\n file: foo.rb\ncoverage: 40.00% (2/5 lines)\n missed: 1, 4-5\n\n" - assert_equal expected, @console.output(files,'/') + assert_equal expected, @console.output(files,'/',false) + end + + def test_block_output_with_branches + SimpleCov::Formatter::Console.use_colors = false + SimpleCov::Formatter::Console.output_style = 'block' + @console.include_output_style + files = [ + SourceFileWithBranches.new( + 'foo.rb',5,[2,3],[Line.new(1), Line.new(4), Line.new(5)],40.0, + {branch: CoverageStatistics.new(50.0)}, [1,2], + [Branch.new(2, :then)] + ) + ] + expected = "\n file: foo.rb\ncoverage: 40.00% (2/5 lines)\n missed: 1, 4-5\nbranches: 50% (1/2 branches)\n missed: 2[then]\n\n" + assert_equal expected, @console.output(files,'/',true) end end