From 0de1984425609eccdae7795ade03dead204b2eb0 Mon Sep 17 00:00:00 2001 From: Tobias Pfeiffer Date: Thu, 30 Jan 2020 09:59:51 +0100 Subject: [PATCH] Fix crashes with uneven number of nocov instructions Fixes #846 We just assume them to go until the end. Test against a full nocov for the file as well as a small mixture. --- lib/simplecov/source_file.rb | 5 +- spec/fixtures/coverer.rb | 4 +- spec/fixtures/single_nocov.rb | 14 ++++++ spec/fixtures/uneven_nocovs.rb | 16 ++++++ spec/source_file_spec.rb | 89 ++++++++++++++++++++++++++++++++++ 5 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 spec/fixtures/single_nocov.rb create mode 100644 spec/fixtures/uneven_nocovs.rb diff --git a/lib/simplecov/source_file.rb b/lib/simplecov/source_file.rb index f7dcda3b..f17b01b4 100644 --- a/lib/simplecov/source_file.rb +++ b/lib/simplecov/source_file.rb @@ -164,9 +164,10 @@ def no_cov_chunks def build_no_cov_chunks no_cov_lines = src.map.with_index(1).select { |line, _index| LinesClassifier.no_cov_line?(line) } - warn "uneven number of nocov comments detected" if no_cov_lines.size.odd? - no_cov_lines.each_slice(2).map do |(_line_start, index_start), (_line_end, index_end)| + # if we have an uneven number of nocovs we assume they go to the + # end of the file + index_end ||= src.size index_start..index_end end end diff --git a/spec/fixtures/coverer.rb b/spec/fixtures/coverer.rb index f011be16..b6d9e53b 100644 --- a/spec/fixtures/coverer.rb +++ b/spec/fixtures/coverer.rb @@ -2,6 +2,8 @@ require "coverage" Coverage.start(:all) -require_relative "branch_tester_script" +require_relative "uneven_nocovs" + +UnevenNocov.call(42) p Coverage.result diff --git a/spec/fixtures/single_nocov.rb b/spec/fixtures/single_nocov.rb new file mode 100644 index 00000000..d435a1cb --- /dev/null +++ b/spec/fixtures/single_nocov.rb @@ -0,0 +1,14 @@ +# :nocov: +module SingleNocov + def self.call(arg) + if arg.odd? + :odd + elsif arg == 30 + :mop + elsif arg == 42 + :yay + else + :nay + end + end +end diff --git a/spec/fixtures/uneven_nocovs.rb b/spec/fixtures/uneven_nocovs.rb new file mode 100644 index 00000000..a4392912 --- /dev/null +++ b/spec/fixtures/uneven_nocovs.rb @@ -0,0 +1,16 @@ +module UnevenNocov + def self.call(arg) + # :nocov: + if arg.odd? + :odd + elsif arg == 30 + :mop + # :nocov: + elsif arg == 42 + :yay + # :nocov: + else + :nay + end + end +end diff --git a/spec/source_file_spec.rb b/spec/source_file_spec.rb index e3aae94c..bcd5f1e8 100644 --- a/spec/source_file_spec.rb +++ b/spec/source_file_spec.rb @@ -606,4 +606,93 @@ end end end + + context "a file entirely ignored with a single # :nocov:" do + COVERAGE_FOR_SINGLE_NOCOV_RB = { + "lines" => [nil, 1, 1, 1, 0, 1, 0, 1, 1, nil, 0, nil, nil, nil], + "branches" => { + [:if, 0, 8, 4, 11, 10] => + {[:then, 1, 9, 6, 9, 10] => 1, [:else, 2, 11, 6, 11, 10] => 0}, + [:if, 3, 6, 4, 11, 10] => + {[:then, 4, 7, 6, 7, 10] => 0, [:else, 5, 8, 4, 11, 10] => 1}, + [:if, 6, 4, 4, 12, 7] => + {[:then, 7, 5, 6, 5, 10] => 0, [:else, 8, 6, 4, 11, 10] => 1} + } + }.freeze + + subject do + SimpleCov::SourceFile.new(source_fixture("single_nocov.rb"), COVERAGE_FOR_SINGLE_NOCOV_RB) + end + + describe "line coverage" do + it "has all lines skipped" do + expect(subject.skipped_lines.size).to eq(subject.lines.size) + expect(subject.skipped_lines.size).to eq(14) + end + + it "reports 100% coverage on 0/0" do + expect(subject.covered_percent).to eq 100.0 + expect(subject.relevant_lines).to eq 0 + expect(subject.covered_lines.size).to eq 0 + end + end + + describe "branch coverage" do + it "has 100% branch coverage on 0/0" do + branch_coverage = subject.coverage_statistics.fetch(:branch) + + expect(branch_coverage.percent).to eq 100.0 + expect(branch_coverage.total).to eq 0 + expect(branch_coverage.covered).to eq 0 + end + + it "has all branches marked as skipped" do + expect(subject.branches.all?(&:skipped?)).to eq true + end + end + end + + context "a file with an uneven usage of # :nocov:s" do + COVERAGE_FOR_UNEVEN_NOCOV_RB = { + "lines" => [1, 1, nil, 1, 0, 1, 0, nil, 1, 1, nil, nil, 0, nil, nil, nil], + "branches" => { + [:if, 0, 9, 4, 13, 10] => + {[:then, 1, 10, 6, 10, 10] => 1, [:else, 2, 13, 6, 13, 10] => 0}, + [:if, 3, 6, 4, 13, 10] => + {[:then, 4, 7, 6, 7, 10] => 0, [:else, 5, 9, 4, 13, 10] => 1}, + [:if, 6, 4, 4, 14, 7] => + {[:then, 7, 5, 6, 5, 10] => 0, [:else, 8, 6, 4, 13, 10] => 1} + } + }.freeze + + subject do + SimpleCov::SourceFile.new(source_fixture("uneven_nocovs.rb"), COVERAGE_FOR_UNEVEN_NOCOV_RB) + end + + describe "line coverage" do + it "has 12 lines skipped" do + expect(subject.skipped_lines.size).to eq(12) + end + + it "reports 100% coverage on 4/4" do + expect(subject.covered_percent).to eq 100.0 + expect(subject.relevant_lines).to eq 4 + expect(subject.covered_lines.size).to eq 4 + end + end + + describe "branch coverage" do + it "has 100% branch coverage on 1/1" do + branch_coverage = subject.coverage_statistics.fetch(:branch) + + expect(branch_coverage.percent).to eq 100.0 + expect(branch_coverage.total).to eq 1 + expect(branch_coverage.covered).to eq 1 + end + + it "has 5 branches marked as skipped" do + expect(subject.branches.select(&:skipped?).size).to eq 5 + end + end + end end