From 693af604ff118c94f9fdbad55870229e6d07c516 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Sat, 22 Aug 2020 13:08:23 +0300 Subject: [PATCH 01/33] add some todos --- lib/simplecov.rb | 5 ++++- lib/simplecov/combine/results_combiner.rb | 1 + lib/simplecov/configuration.rb | 1 + lib/simplecov/file_list.rb | 1 + lib/simplecov/result.rb | 4 +++- lib/simplecov/simulate_coverage.rb | 1 + lib/simplecov/source_file.rb | 1 + spec/combine/results_combiner_spec.rb | 1 + spec/configuration_spec.rb | 1 + spec/file_list_spec.rb | 1 + spec/simplecov_spec.rb | 1 + spec/source_file/branch_spec.rb | 1 + spec/source_file_spec.rb | 1 + spec/useless_results_remover_spec.rb | 1 + 14 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/simplecov.rb b/lib/simplecov.rb index fe68b6fe..b061845e 100644 --- a/lib/simplecov.rb +++ b/lib/simplecov.rb @@ -355,7 +355,8 @@ def start_coverage_with_criteria CRITERION_TO_RUBY_COVERAGE = { branch: :branches, - line: :lines + line: :lines, + method: :methods }.freeze def lookup_corresponding_ruby_coverage_name(criterion) CRITERION_TO_RUBY_COVERAGE.fetch(criterion) @@ -444,6 +445,7 @@ def probably_running_parallel_tests? require_relative "simplecov/profiles" require_relative "simplecov/source_file/line" require_relative "simplecov/source_file/branch" +# require_relative "simplecov/source_file/method" require_relative "simplecov/source_file" require_relative "simplecov/file_list" require_relative "simplecov/result" @@ -457,6 +459,7 @@ def probably_running_parallel_tests? require_relative "simplecov/result_adapter" require_relative "simplecov/combine" require_relative "simplecov/combine/branches_combiner" +# require_relative "simplecov/combine/methods_combiner" require_relative "simplecov/combine/files_combiner" require_relative "simplecov/combine/lines_combiner" require_relative "simplecov/combine/results_combiner" diff --git a/lib/simplecov/combine/results_combiner.rb b/lib/simplecov/combine/results_combiner.rb index dd359302..9f3896e6 100644 --- a/lib/simplecov/combine/results_combiner.rb +++ b/lib/simplecov/combine/results_combiner.rb @@ -16,6 +16,7 @@ module ResultsCombiner # ==> FileCombiner: collect result of next combine levels lines and branches. # ===> LinesCombiner: combine lines results. # ===> BranchesCombiner: combine branches results. + # TODO: add method cov # # @return [Hash] # diff --git a/lib/simplecov/configuration.rb b/lib/simplecov/configuration.rb index 94f662c9..4f3078e9 100644 --- a/lib/simplecov/configuration.rb +++ b/lib/simplecov/configuration.rb @@ -360,6 +360,7 @@ def add_group(group_name, filter_argument = nil, &filter_proc) groups[group_name] = parse_filter(filter_argument, &filter_proc) end + # TODO: add method cov SUPPORTED_COVERAGE_CRITERIA = %i[line branch].freeze DEFAULT_COVERAGE_CRITERION = :line # diff --git a/lib/simplecov/file_list.rb b/lib/simplecov/file_list.rb index d4c9bba9..c8872ae9 100644 --- a/lib/simplecov/file_list.rb +++ b/lib/simplecov/file_list.rb @@ -100,6 +100,7 @@ def branch_covered_percent private + # TODO: add method cov def compute_coverage_statistics total_coverage_statistics = @files.each_with_object(line: [], branch: []) do |file, together| together[:line] << file.coverage_statistics[:line] diff --git a/lib/simplecov/result.rb b/lib/simplecov/result.rb index 36eb1f9f..d153bb01 100644 --- a/lib/simplecov/result.rb +++ b/lib/simplecov/result.rb @@ -20,7 +20,9 @@ class Result # Explicitly set the command name that was used for this coverage result. Defaults to SimpleCov.command_name attr_writer :command_name - def_delegators :files, :covered_percent, :covered_percentages, :least_covered_file, :covered_strength, :covered_lines, :missed_lines, :total_branches, :covered_branches, :missed_branches, :coverage_statistics + def_delegators :files, :covered_percent, :covered_percentages, :least_covered_file, :covered_strength, + :covered_lines, :missed_lines, :total_branches, :covered_branches, :missed_branches, + :coverage_statistics def_delegator :files, :lines_of_code, :total_lines # Initialize a new SimpleCov::Result from given Coverage.result (a Hash of filenames each containing an array of diff --git a/lib/simplecov/simulate_coverage.rb b/lib/simplecov/simulate_coverage.rb index 04443865..387cfcd4 100644 --- a/lib/simplecov/simulate_coverage.rb +++ b/lib/simplecov/simulate_coverage.rb @@ -23,6 +23,7 @@ def call(absolute_path) # we don't want to parse branches ourselves... # requiring files can have side effects and we don't want to trigger that "branches" => {} + # TODO: add method cov? } end end diff --git a/lib/simplecov/source_file.rb b/lib/simplecov/source_file.rb index 4cb9f632..c3c394e6 100644 --- a/lib/simplecov/source_file.rb +++ b/lib/simplecov/source_file.rb @@ -34,6 +34,7 @@ def coverage_statistics { **line_coverage_statistics, **branch_coverage_statistics + # TODO: add method cov } end diff --git a/spec/combine/results_combiner_spec.rb b/spec/combine/results_combiner_spec.rb index 05e1b55e..a0af4081 100644 --- a/spec/combine/results_combiner_spec.rb +++ b/spec/combine/results_combiner_spec.rb @@ -9,6 +9,7 @@ source_fixture("sample.rb") => { "lines" => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], "branches" => {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 47, [:else, 5, 8, 6, 8, 36] => 24}} + # TODO: add method cov? }, source_fixture("app/models/user.rb") => { "lines" => [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil], diff --git a/spec/configuration_spec.rb b/spec/configuration_spec.rb index ca2e8ccb..44d8c3f1 100644 --- a/spec/configuration_spec.rb +++ b/spec/configuration_spec.rb @@ -74,6 +74,7 @@ expect(config.minimum_coverage).to eq line: 85.0 end + # TODO: add method cov it "sets the right coverage when called with a hash of just branch" do config.enable_coverage :branch config.minimum_coverage branch: 85.0 diff --git a/spec/file_list_spec.rb b/spec/file_list_spec.rb index f0d33629..7de0eac6 100644 --- a/spec/file_list_spec.rb +++ b/spec/file_list_spec.rb @@ -8,6 +8,7 @@ source_fixture("sample.rb") => { "lines" => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], "branches" => {} + # TODO: add method cov }, source_fixture("app/models/user.rb") => { "lines" => [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil], diff --git a/spec/simplecov_spec.rb b/spec/simplecov_spec.rb index 1ab1aaed..74fe7de6 100644 --- a/spec/simplecov_spec.rb +++ b/spec/simplecov_spec.rb @@ -172,6 +172,7 @@ end end + # TODO: add method cov context "branch coverage" do before do allow(SimpleCov).to receive(:minimum_coverage).and_return(branch: 90) diff --git a/spec/source_file/branch_spec.rb b/spec/source_file/branch_spec.rb index 048cc12b..99016c7e 100644 --- a/spec/source_file/branch_spec.rb +++ b/spec/source_file/branch_spec.rb @@ -2,6 +2,7 @@ require "helper" +# TODO: add method cov describe SimpleCov::SourceFile::Branch do let(:if_branch) do described_class.new(start_line: 1, end_line: 3, coverage: 0, inline: false, type: :then) diff --git a/spec/source_file_spec.rb b/spec/source_file_spec.rb index 86f62b3a..bb35d2b9 100644 --- a/spec/source_file_spec.rb +++ b/spec/source_file_spec.rb @@ -69,6 +69,7 @@ end end + # TODO: add method cov describe "branch coverage" do it "has total branches count 0" do expect(subject.total_branches.size).to eq(0) diff --git a/spec/useless_results_remover_spec.rb b/spec/useless_results_remover_spec.rb index 223b8f55..cafa56b5 100644 --- a/spec/useless_results_remover_spec.rb +++ b/spec/useless_results_remover_spec.rb @@ -11,6 +11,7 @@ gem_file_path => { "lines" => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], "branches" => {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 47, [:else, 5, 8, 6, 8, 36] => 24}} + # TODO: add method cov? }, source_path => { "lines" => [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil], From 2521b5c547cef5b72a473dc4bb58467732426aec Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Sat, 22 Aug 2020 14:22:10 +0300 Subject: [PATCH 02/33] add method coverage criterion --- lib/simplecov.rb | 2 +- lib/simplecov/configuration.rb | 10 +++++++--- spec/configuration_spec.rb | 31 +++++++++++++++++++++++++++++-- spec/simplecov_spec.rb | 10 +++++++++- spec/source_file_spec.rb | 16 ++++++++-------- 5 files changed, 54 insertions(+), 15 deletions(-) diff --git a/lib/simplecov.rb b/lib/simplecov.rb index b061845e..83263b2e 100644 --- a/lib/simplecov.rb +++ b/lib/simplecov.rb @@ -356,7 +356,7 @@ def start_coverage_with_criteria CRITERION_TO_RUBY_COVERAGE = { branch: :branches, line: :lines, - method: :methods + method: :methods, }.freeze def lookup_corresponding_ruby_coverage_name(criterion) CRITERION_TO_RUBY_COVERAGE.fetch(criterion) diff --git a/lib/simplecov/configuration.rb b/lib/simplecov/configuration.rb index 4f3078e9..2ba53b33 100644 --- a/lib/simplecov/configuration.rb +++ b/lib/simplecov/configuration.rb @@ -360,8 +360,7 @@ def add_group(group_name, filter_argument = nil, &filter_proc) groups[group_name] = parse_filter(filter_argument, &filter_proc) end - # TODO: add method cov - SUPPORTED_COVERAGE_CRITERIA = %i[line branch].freeze + SUPPORTED_COVERAGE_CRITERIA = %i[line branch method].freeze DEFAULT_COVERAGE_CRITERION = :line # # Define which coverage criterion should be evaluated. @@ -404,6 +403,10 @@ def branch_coverage? branch_coverage_supported? && coverage_criterion_enabled?(:branch) end + def method_coverage? + method_coverage_supported? && coverage_criterion_enabled?(:method) + end + def coverage_start_arguments_supported? # safe to cache as within one process this value should never # change @@ -416,6 +419,7 @@ def coverage_start_arguments_supported? end alias branch_coverage_supported? coverage_start_arguments_supported? + alias method_coverage_supported? coverage_start_arguments_supported? private @@ -423,7 +427,7 @@ def raise_if_criterion_disabled(criterion) raise_if_criterion_unsupported(criterion) # rubocop:disable Style/IfUnlessModifier unless coverage_criterion_enabled?(criterion) - raise "Coverage criterion #{criterion}, is disabled! Please enable it first through enable_coverage #{criterion} (if supported)" + raise "Coverage criterion #{criterion} is disabled! Please enable it first through enable_coverage #{criterion} (if supported)" end # rubocop:enable Style/IfUnlessModifier end diff --git a/spec/configuration_spec.rb b/spec/configuration_spec.rb index 44d8c3f1..1bbfec78 100644 --- a/spec/configuration_spec.rb +++ b/spec/configuration_spec.rb @@ -74,7 +74,6 @@ expect(config.minimum_coverage).to eq line: 85.0 end - # TODO: add method cov it "sets the right coverage when called with a hash of just branch" do config.enable_coverage :branch config.minimum_coverage branch: 85.0 @@ -82,13 +81,21 @@ expect(config.minimum_coverage).to eq branch: 85.0 end - it "sets the right coverage when called withboth line and branch" do + it "sets the right coverage when called with both line and branch" do config.enable_coverage :branch config.minimum_coverage branch: 85.0, line: 95.4 expect(config.minimum_coverage).to eq branch: 85.0, line: 95.4 end + it "sets the right coverage when called with line, branch and method" do + config.enable_coverage :branch + config.enable_coverage :method + config.minimum_coverage branch: 85.0, line: 95.4, method: 91.5 + + expect(config.minimum_coverage).to eq branch: 85.0, line: 95.4, method: 91.5 + end + it "raises when trying to set branch coverage but not enabled" do expect do config.minimum_coverage branch: 42 @@ -131,6 +138,12 @@ expect(config.coverage_criterion).to eq :branch end + it "works fine with :method" do + config.coverage_criterion :method + + expect(config.coverage_criterion).to eq :method + end + it "works fine setting it back and forth" do config.coverage_criterion :branch config.coverage_criterion :line @@ -184,5 +197,19 @@ expect(config).not_to be_branch_coverage end end + + describe "#method_coverage?", if: SimpleCov.method_coverage_supported? do + it "returns true of method coverage is being measured" do + config.enable_coverage :method + + expect(config).to be_method_coverage + end + + it "returns false for line coverage" do + config.coverage_criterion :line + + expect(config).not_to be_method_coverage + end + end end end diff --git a/spec/simplecov_spec.rb b/spec/simplecov_spec.rb index 74fe7de6..17962702 100644 --- a/spec/simplecov_spec.rb +++ b/spec/simplecov_spec.rb @@ -291,12 +291,20 @@ def clear_mergeable_reports(*names) SimpleCov.send :start_coverage_measurement end - it "starts coverage with lines and branches if branches is activated" do + it "starts coverage with lines and branches if branch coverage is activated" do expect(Coverage).to receive(:start).with(lines: true, branches: true) SimpleCov.enable_coverage :branch SimpleCov.send :start_coverage_measurement end + + it "starts coverage with lines and methods if method coverage is activated" do + expect(Coverage).to receive(:start).with(lines: true, methods: true) + + SimpleCov.enable_coverage :method + + SimpleCov.send :start_coverage_measurement + end end end diff --git a/spec/source_file_spec.rb b/spec/source_file_spec.rb index bb35d2b9..c9a518cb 100644 --- a/spec/source_file_spec.rb +++ b/spec/source_file_spec.rb @@ -4,7 +4,7 @@ describe SimpleCov::SourceFile do COVERAGE_FOR_SAMPLE_RB = { - "lines" => [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil, nil, 1, 0, nil, nil, nil], + "lines" => [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil, nil, 1, 0, nil, nil, nil], "branches" => {} }.freeze @@ -95,7 +95,7 @@ context "file with branches" do COVERAGE_FOR_BRANCHES_RB = { - "lines" => [1, 1, 1, nil, 1, nil, 1, 0, nil, 1, nil, nil, nil], + "lines" => [1, 1, 1, nil, 1, nil, 1, 0, nil, 1, nil, nil, nil], "branches" => { [:if, 0, 3, 4, 3, 21] => {[:then, 1, 3, 4, 3, 10] => 0, [:else, 2, 3, 4, 3, 21] => 1}, @@ -185,7 +185,7 @@ context "A file that has inline branches" do COVERAGE_FOR_INLINE = { - "lines" => [1, 1, 1, nil, 1, 1, 0, nil, 1, nil, nil, nil, nil], + "lines" => [1, 1, 1, nil, 1, 1, 0, nil, 1, nil, nil, nil, nil], "branches" => { [:if, 0, 3, 11, 3, 33] => {[:then, 1, 3, 23, 3, 27] => 1, [:else, 2, 3, 30, 3, 33] => 0}, @@ -331,7 +331,7 @@ context "a file with more complex skipping" do COVERAGE_FOR_NOCOV_COMPLEX_RB = { - "lines" => [nil, nil, 1, 1, nil, 1, nil, nil, nil, 1, nil, nil, 1, nil, nil, 0, nil, 1, nil, 0, nil, nil, 1, nil, nil, nil, nil], + "lines" => [nil, nil, 1, 1, nil, 1, nil, nil, nil, 1, nil, nil, 1, nil, nil, 0, nil, 1, nil, 0, nil, nil, 1, nil, nil, nil, nil], "branches" => { [:if, 0, 6, 4, 11, 7] => {[:then, 1, 7, 6, 7, 7] => 0, [:else, 2, 10, 6, 10, 7] => 1}, @@ -392,7 +392,7 @@ context "a file with nested branches" do COVERAGE_FOR_NESTED_BRANCHES_RB = { - "lines" => [nil, nil, 1, 1, 1, 1, 1, 1, nil, nil, 0, nil, nil, nil, nil], + "lines" => [nil, nil, 1, 1, 1, 1, 1, 1, nil, nil, 0, nil, nil, nil, nil], "branches" => { [:while, 0, 7, 8, 7, 31] => {[:body, 1, 7, 8, 7, 16] => 2}, @@ -428,7 +428,7 @@ context "a file with case" do COVERAGE_FOR_CASE_STATEMENT_RB = { - "lines" => [1, 1, 1, nil, 0, nil, 1, nil, 0, nil, 0, nil, nil, nil], + "lines" => [1, 1, 1, nil, 0, nil, 1, nil, 0, nil, 0, nil, nil, nil], "branches" => { [:case, 0, 3, 4, 12, 7] => { [:when, 1, 5, 6, 5, 10] => 0, @@ -471,7 +471,7 @@ context "a file with case without else" do COVERAGE_FOR_CASE_WITHOUT_ELSE_STATEMENT_RB = { - "lines" => [1, 1, 1, nil, 0, nil, 1, nil, 0, nil, nil, nil], + "lines" => [1, 1, 1, nil, 0, nil, 1, nil, 0, nil, nil, nil], "branches" => { [:case, 0, 3, 4, 10, 7] => { [:when, 1, 5, 6, 5, 10] => 0, @@ -556,7 +556,7 @@ context "the branch tester script" do COVERAGE_FOR_BRANCH_TESTER_RB = { - "lines" => [nil, nil, 1, 1, nil, 1, nil, 1, 1, nil, nil, 1, 0, nil, nil, 1, 0, nil, 1, nil, nil, 1, 1, 1, nil, nil, 1, 0, nil, nil, 1, 1, nil, 0, nil, 1, 1, 0, 0, 1, 5, 0, 0, nil, 0, nil, 0, nil, nil, nil], + "lines" => [nil, nil, 1, 1, nil, 1, nil, 1, 1, nil, nil, 1, 0, nil, nil, 1, 0, nil, 1, nil, nil, 1, 1, 1, nil, nil, 1, 0, nil, nil, 1, 1, nil, 0, nil, 1, 1, 0, 0, 1, 5, 0, 0, nil, 0, nil, 0, nil, nil, nil], "branches" => { [:if, 0, 4, 0, 4, 19] => {[:then, 1, 4, 12, 4, 15] => 0, [:else, 2, 4, 18, 4, 19] => 1}, From d68a977a049f313f28cd887983bb7f22a5bca3fb Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Sat, 22 Aug 2020 14:22:24 +0300 Subject: [PATCH 03/33] add some temp stuff --- Gemfile | 2 +- Gemfile.lock | 7 +++++- features/method_coverage.feature | 37 +++++++++++++++++++++++++++++ lib/simplecov/source_file/method.rb | 33 +++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 features/method_coverage.feature create mode 100644 lib/simplecov/source_file/method.rb diff --git a/Gemfile b/Gemfile index 9688762b..4422fd79 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ source "https://rubygems.org" # Uncomment this to use local copy of simplecov-html in development when checked out -# gem "simplecov-html", path: File.dirname(__FILE__) + "/../simplecov-html" +gem "simplecov-html", path: File.dirname(__FILE__) + "/../simplecov-html" # Uncomment this to use development version of html formatter from github # gem "simplecov-html", github: "colszowka/simplecov-html" diff --git a/Gemfile.lock b/Gemfile.lock index 5ceb1e75..4b581c5c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,6 +5,11 @@ PATH docile (~> 1.1) simplecov-html (~> 0.11) +PATH + remote: ../simplecov-html + specs: + simplecov-html (0.12.2) + GEM remote: https://rubygems.org/ specs: @@ -136,7 +141,6 @@ GEM rubocop-ast (0.3.0) parser (>= 2.7.1.4) ruby-progressbar (1.10.1) - simplecov-html (0.12.2) spoon (0.0.6) ffi sys-uname (1.2.1) @@ -174,6 +178,7 @@ DEPENDENCIES rspec (~> 3.2) rubocop simplecov! + simplecov-html! test-unit BUNDLED WITH diff --git a/features/method_coverage.feature b/features/method_coverage.feature new file mode 100644 index 00000000..9d10b4a3 --- /dev/null +++ b/features/method_coverage.feature @@ -0,0 +1,37 @@ +@rspec @method_coverage +Feature: + + Simply executing method coverage gives ok results. + + Background: + Given I'm working on the project "faked_project" + + Scenario: + Given SimpleCov for RSpec is configured with: + """ + require 'simplecov' + SimpleCov.start do + enable_coverage :method + end + """ + When I open the coverage report generated with `bundle exec rspec spec` + Then I should see the groups: + | name | coverage | files | + | All Files | 91.8% | 7 | + # And I should see a line coverage summary of 56/61 + # And I should see a branch coverage summary of 2/4 + # And I should see the source files: + # | name | coverage | branch coverage | + # | lib/faked_project.rb | 100.00 % | 100.00 % | + # | lib/faked_project/some_class.rb | 80.00 % | 50.00 % | + # | lib/faked_project/framework_specific.rb | 75.00 % | 100.00 % | + # | lib/faked_project/meta_magic.rb | 100.00 % | 100.00 % | + # | spec/forking_spec.rb | 100.00 % | 50.00 % | + # | spec/meta_magic_spec.rb | 100.00 % | 100.00 % | + # | spec/some_class_spec.rb | 100.00 % | 100.00 % | + + # When I open the detailed view for "lib/faked_project/some_class.rb" + # Then I should see a line coverage summary of 12/15 for the file + # And I should see a branch coverage summary of 1/2 for the file + # And I should see coverage branch data like "then: 1" + # And I should see coverage branch data like "else: 0" diff --git a/lib/simplecov/source_file/method.rb b/lib/simplecov/source_file/method.rb new file mode 100644 index 00000000..0daf983a --- /dev/null +++ b/lib/simplecov/source_file/method.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module SimpleCov + class SourceFile + class Method + attr_reader :source_file, :coverage + attr_reader :klass, :method, :start_line, :start_col, :end_line, :end_col + + def initialize(source_file, info, coverage) + @source_file = source_file + @klass, @method, @start_line, @start_col, @end_line, @end_col = info + @coverage = coverage + end + + def covered? + !skipped? && coverage.positive? + end + + def skipped? + return @skipped if defined?(@skipped) + @skipped = lines.all?(&:skipped?) + end + + def lines + @lines ||= source_file.lines[(start_line - 1)..(end_line - 1)] + end + + def to_s + "#{klass}##{method}" + end + end + end +end From 1f40180ac5902cb7c27e28ab57848edf5f4fdb8c Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Sat, 22 Aug 2020 15:31:03 +0300 Subject: [PATCH 04/33] add basic method coverage support --- lib/simplecov.rb | 3 +- lib/simplecov/file_list.rb | 7 +- lib/simplecov/result.rb | 22 ++--- lib/simplecov/result_serialization.rb | 112 ++++++++++++++++++++++++++ lib/simplecov/source_file.rb | 38 +++++++-- lib/simplecov/source_file/method.rb | 4 + 6 files changed, 167 insertions(+), 19 deletions(-) create mode 100644 lib/simplecov/result_serialization.rb diff --git a/lib/simplecov.rb b/lib/simplecov.rb index 83263b2e..e7a1572c 100644 --- a/lib/simplecov.rb +++ b/lib/simplecov.rb @@ -445,7 +445,7 @@ def probably_running_parallel_tests? require_relative "simplecov/profiles" require_relative "simplecov/source_file/line" require_relative "simplecov/source_file/branch" -# require_relative "simplecov/source_file/method" +require_relative "simplecov/source_file/method" require_relative "simplecov/source_file" require_relative "simplecov/file_list" require_relative "simplecov/result" @@ -454,6 +454,7 @@ def probably_running_parallel_tests? require_relative "simplecov/last_run" require_relative "simplecov/lines_classifier" require_relative "simplecov/result_merger" +require_relative "simplecov/result_serialization" require_relative "simplecov/command_guesser" require_relative "simplecov/version" require_relative "simplecov/result_adapter" diff --git a/lib/simplecov/file_list.rb b/lib/simplecov/file_list.rb index c8872ae9..2b20fc49 100644 --- a/lib/simplecov/file_list.rb +++ b/lib/simplecov/file_list.rb @@ -98,17 +98,20 @@ def branch_covered_percent coverage_statistics[:branch]&.percent end + # TODO: add method cov methods for html report + private - # TODO: add method cov def compute_coverage_statistics - total_coverage_statistics = @files.each_with_object(line: [], branch: []) do |file, together| + total_coverage_statistics = @files.each_with_object(line: [], branch: [], method: []) do |file, together| together[:line] << file.coverage_statistics[:line] together[:branch] << file.coverage_statistics[:branch] if SimpleCov.branch_coverage? + together[:method] << file.coverage_statistics[:method] if SimpleCov.method_coverage? end coverage_statistics = {line: CoverageStatistics.from(total_coverage_statistics[:line])} coverage_statistics[:branch] = CoverageStatistics.from(total_coverage_statistics[:branch]) if SimpleCov.branch_coverage? + coverage_statistics[:method] = CoverageStatistics.from(total_coverage_statistics[:method]) if SimpleCov.method_coverage? coverage_statistics end end diff --git a/lib/simplecov/result.rb b/lib/simplecov/result.rb index d153bb01..b9c74ebe 100644 --- a/lib/simplecov/result.rb +++ b/lib/simplecov/result.rb @@ -64,12 +64,12 @@ def command_name # Returns a hash representation of this Result that can be used for marshalling it into JSON def to_hash - { - command_name => { - "coverage" => coverage, - "timestamp" => created_at.to_i - } - } + SimpleCov::ResultSerialization.serialize(self) + end + + # Loads a SimpleCov::Result#to_hash dump + def self.from_hash(hash) + SimpleCov::ResultSerialization.deserialize(hash) end # Loads a SimpleCov::Result#to_hash dump @@ -83,6 +83,11 @@ def self.from_hash(hash) result end + def coverage + keys = original_result.keys & filenames + Hash[keys.zip(original_result.values_at(*keys))] + end + private # We changed the format of the raw result data in simplecov, as people are likely @@ -110,11 +115,6 @@ def adapt_pre_simplecov_0_18_result(result) end end - def coverage - keys = original_result.keys & filenames - Hash[keys.zip(original_result.values_at(*keys))] - end - # Applies all configured SimpleCov filters on this result's source files def filter! @files = SimpleCov.filtered(files) diff --git a/lib/simplecov/result_serialization.rb b/lib/simplecov/result_serialization.rb new file mode 100644 index 00000000..baeab5c8 --- /dev/null +++ b/lib/simplecov/result_serialization.rb @@ -0,0 +1,112 @@ +# frozen_string_literal: true + +module SimpleCov + class ResultSerialization + class << self + def serialize(result) + coverage = {} + + result.coverage.each do |file_path, file_data| + serializable_file_data = {} + + file_data.each do |key, value| + serializable_file_data[key] = serialize_value(key, value) + end + + coverage[file_path] = serializable_file_data + end + + data = {"coverage" => coverage, "timestamp" => result.created_at.to_i} + {result.command_name => data} + end + + def deserialize(hash) # rubocop:disable Metrics/MethodLength + command_name, data = hash.first + + coverage = {} + + data["coverage"].each do |file_name, file_data| + parsed_file_data = {} + + file_data.each do |key, value| + key = key.to_sym + parsed_file_data[key] = deserialize_value(key, value) + end + + coverage[file_name] = parsed_file_data + end + + result = SimpleCov::Result.new(coverage) + result.command_name = command_name + result.created_at = Time.at(data["timestamp"]) + result + end + + private + + def serialize_value(key, value) # rubocop:disable Metrics/MethodLength + case key + when :branches + value.map { |k, v| [k, v.to_a] } + when :methods + value.map do |methods_data, coverage| + klass, *info = methods_data + # Replace all memory addresses with 0 since they are inconsistent between test runs + serialized_klass = klass.to_s.sub(/0x[0-9a-f]{16}/, "0x0000000000000000") + serialized_methods_data = [serialized_klass, *info] + [serialized_methods_data, coverage] + end + else + value + end + end + + def deserialize_value(key, value) + case key + when :branches + deserialize_branches(value) + when :methods + deserialize_methods(value) + else + value + end + end + + def deserialize_branches(value) + result = {} + + value.each do |serialized_root, serialized_coverage_data| + root = deserialize_branch_info(serialized_root) + coverage_data = {} + + serialized_coverage_data.each do |serialized_branch, coverage| + branch = deserialize_branch_info(serialized_branch) + coverage_data[branch] = coverage + end + + result[root] = coverage_data + end + + result + end + + def deserialize_branch_info(value) + type, *info = value + [type.to_sym, *info] + end + + def deserialize_methods(value) + result = Hash.new { |hash, key| hash[key] = 0 } + + value.each do |serialized_info, coverage| + klass, method_name, *info = serialized_info + info = [klass, method_name.to_sym, *info] + # Info keys might be non-unique since we replace memory addresses with 0 + result[info] += coverage + end + + result + end + end + end +end diff --git a/lib/simplecov/source_file.rb b/lib/simplecov/source_file.rb index c3c394e6..a99975f2 100644 --- a/lib/simplecov/source_file.rb +++ b/lib/simplecov/source_file.rb @@ -33,8 +33,8 @@ def coverage_statistics @coverage_statistics ||= { **line_coverage_statistics, - **branch_coverage_statistics - # TODO: add method cov + **branch_coverage_statistics, + **method_coverage_statistics, } end @@ -155,6 +155,18 @@ def line_with_missed_branch?(line_number) branches_for_line(line_number).select { |_type, count| count.zero? }.any? end + def methods + @methods ||= build_methods + end + + def covered_methods + methods.select(&:covered?) + end + + def missed_methods + methods.select(&:missed?) + end + private # no_cov_chunks is zero indexed to work directly with the array holding the lines @@ -293,6 +305,7 @@ def process_skipped_branches(branches) # See #801 # def restore_ruby_data_structure(structure) + return structure # TODO[@tycooon]: remove # Tests use the real data structures (except for integration tests) so no need to # put them through here. return structure if structure.is_a?(Array) @@ -328,12 +341,18 @@ def build_branch(branch_data, hit_count, condition_start_line) ) end + def build_methods + coverage_data.fetch("methods", []).map do |info, coverage| + SourceFile::Method.new(self, info, coverage) + end + end + def line_coverage_statistics { line: CoverageStatistics.new( total_strength: lines_strength, - covered: covered_lines.size, - missed: missed_lines.size + covered: covered_lines.size, + missed: missed_lines.size ) } end @@ -342,7 +361,16 @@ def branch_coverage_statistics { branch: CoverageStatistics.new( covered: covered_branches.size, - missed: missed_branches.size + missed: missed_branches.size + ) + } + end + + def method_coverage_statistics + { + method: CoverageStatistics.new( + covered: covered_methods.size, + missed: missed_methods.size ) } end diff --git a/lib/simplecov/source_file/method.rb b/lib/simplecov/source_file/method.rb index 0daf983a..f30f7d77 100644 --- a/lib/simplecov/source_file/method.rb +++ b/lib/simplecov/source_file/method.rb @@ -21,6 +21,10 @@ def skipped? @skipped = lines.all?(&:skipped?) end + def missed? + !skipped? && coverage.zero? + end + def lines @lines ||= source_file.lines[(start_line - 1)..(end_line - 1)] end From d609d16e122d5e6a4a9681173a07bc024964da9f Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Sat, 22 Aug 2020 15:53:46 +0300 Subject: [PATCH 05/33] fix serialization --- lib/simplecov/result.rb | 15 +++------------ lib/simplecov/result_merger.rb | 2 +- lib/simplecov/source_file.rb | 8 ++++---- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/lib/simplecov/result.rb b/lib/simplecov/result.rb index b9c74ebe..582d01c3 100644 --- a/lib/simplecov/result.rb +++ b/lib/simplecov/result.rb @@ -30,9 +30,11 @@ class Result def initialize(original_result) result = adapt_result(original_result) @original_result = result.freeze + @files = SimpleCov::FileList.new(result.map do |filename, coverage| - SimpleCov::SourceFile.new(filename, JSON.parse(JSON.dump(coverage))) if File.file?(filename) + SimpleCov::SourceFile.new(filename, coverage) if File.file?(filename) end.compact.sort_by(&:filename)) + filter! end @@ -72,17 +74,6 @@ def self.from_hash(hash) SimpleCov::ResultSerialization.deserialize(hash) end - # Loads a SimpleCov::Result#to_hash dump - def self.from_hash(hash) - command_name, data = hash.first - - result = SimpleCov::Result.new(data["coverage"]) - - result.command_name = command_name - result.created_at = Time.at(data["timestamp"]) - result - end - def coverage keys = original_result.keys & filenames Hash[keys.zip(original_result.values_at(*keys))] diff --git a/lib/simplecov/result_merger.rb b/lib/simplecov/result_merger.rb index f0d1338d..2f506a7b 100644 --- a/lib/simplecov/result_merger.rb +++ b/lib/simplecov/result_merger.rb @@ -72,7 +72,7 @@ def merge_and_store(*results) # coverage data and the command_name for the result consisting of a join # on all source result's names def merge_results(*results) - parsed_results = JSON.parse(JSON.dump(results.map(&:original_result))) + parsed_results = results.map(&:original_result) combined_result = SimpleCov::Combine::ResultsCombiner.combine(*parsed_results) result = SimpleCov::Result.new(combined_result) # Specify the command name diff --git a/lib/simplecov/source_file.rb b/lib/simplecov/source_file.rb index a99975f2..a112a5be 100644 --- a/lib/simplecov/source_file.rb +++ b/lib/simplecov/source_file.rb @@ -234,9 +234,9 @@ def ensure_remove_undefs(file_lines) end def build_lines - coverage_exceeding_source_warn if coverage_data["lines"].size > src.size + coverage_exceeding_source_warn if coverage_data.fetch(:lines).size > src.size lines = src.map.with_index(1) do |src, i| - SimpleCov::SourceFile::Line.new(src, i, coverage_data["lines"][i - 1]) + SimpleCov::SourceFile::Line.new(src, i, coverage_data.fetch(:lines)[i - 1]) end process_skipped_lines(lines) end @@ -278,7 +278,7 @@ def build_branches_report # @return [Array] # def build_branches - coverage_branch_data = coverage_data.fetch("branches", {}) + coverage_branch_data = coverage_data.fetch(:branches, {}) branches = coverage_branch_data.flat_map do |condition, coverage_branches| build_branches_from(condition, coverage_branches) end @@ -342,7 +342,7 @@ def build_branch(branch_data, hit_count, condition_start_line) end def build_methods - coverage_data.fetch("methods", []).map do |info, coverage| + coverage_data.fetch(:methods, []).map do |info, coverage| SourceFile::Method.new(self, info, coverage) end end From f00fdf2c0bc79732be9d23b63843396993599f43 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Wed, 2 Sep 2020 19:02:24 +0300 Subject: [PATCH 06/33] some fixes and fix all specs --- lib/simplecov/combine/files_combiner.rb | 11 +++- lib/simplecov/result.rb | 2 +- lib/simplecov/result_adapter.rb | 2 +- lib/simplecov/simulate_coverage.rb | 6 +-- lib/simplecov/source_file.rb | 32 +++-------- spec/combine/results_combiner_spec.rb | 72 +++++++++++++------------ spec/file_list_spec.rb | 12 ++--- spec/result_merger_spec.rb | 24 ++++----- spec/result_spec.rb | 8 +-- spec/simplecov_spec.rb | 4 +- spec/source_file_spec.rb | 64 +++++++++++----------- spec/useless_results_remover_spec.rb | 10 ++-- 12 files changed, 120 insertions(+), 127 deletions(-) diff --git a/lib/simplecov/combine/files_combiner.rb b/lib/simplecov/combine/files_combiner.rb index 32df1184..b70429d6 100644 --- a/lib/simplecov/combine/files_combiner.rb +++ b/lib/simplecov/combine/files_combiner.rb @@ -15,8 +15,15 @@ module FilesCombiner # @return [Hash] # def combine(coverage_a, coverage_b) - combination = {"lines" => Combine.combine(LinesCombiner, coverage_a["lines"], coverage_b["lines"])} - combination["branches"] = Combine.combine(BranchesCombiner, coverage_a["branches"], coverage_b["branches"]) if SimpleCov.branch_coverage? + combination = {} + combination[:lines] = Combine.combine(LinesCombiner, coverage_a[:lines], coverage_b[:lines]) + + if SimpleCov.branch_coverage? + combination[:branches] = Combine.combine(BranchesCombiner, coverage_a[:branches], coverage_b[:branches]) + end + + # TODO: add method cov + combination end end diff --git a/lib/simplecov/result.rb b/lib/simplecov/result.rb index 582d01c3..f9f6fcc0 100644 --- a/lib/simplecov/result.rb +++ b/lib/simplecov/result.rb @@ -102,7 +102,7 @@ def pre_simplecov_0_18_result?(result) def adapt_pre_simplecov_0_18_result(result) result.transform_values do |line_coverage_data| - {"lines" => line_coverage_data} + {lines: line_coverage_data} end end diff --git a/lib/simplecov/result_adapter.rb b/lib/simplecov/result_adapter.rb index 4b7f07f9..79cf8e6f 100644 --- a/lib/simplecov/result_adapter.rb +++ b/lib/simplecov/result_adapter.rb @@ -20,7 +20,7 @@ def adapt result.each_with_object({}) do |(file_name, cover_statistic), adapted_result| if cover_statistic.is_a?(Array) - adapted_result.merge!(file_name => {"lines" => cover_statistic}) + adapted_result.merge!(file_name => {lines: cover_statistic}) else adapted_result.merge!(file_name => cover_statistic) end diff --git a/lib/simplecov/simulate_coverage.rb b/lib/simplecov/simulate_coverage.rb index 387cfcd4..bc95bfe5 100644 --- a/lib/simplecov/simulate_coverage.rb +++ b/lib/simplecov/simulate_coverage.rb @@ -19,11 +19,11 @@ def call(absolute_path) lines = File.foreach(absolute_path) { - "lines" => LinesClassifier.new.classify(lines), + lines: LinesClassifier.new.classify(lines), # we don't want to parse branches ourselves... # requiring files can have side effects and we don't want to trigger that - "branches" => {} - # TODO: add method cov? + branches: {}, + methods: {}, } end end diff --git a/lib/simplecov/source_file.rb b/lib/simplecov/source_file.rb index a112a5be..583495db 100644 --- a/lib/simplecov/source_file.rb +++ b/lib/simplecov/source_file.rb @@ -234,9 +234,9 @@ def ensure_remove_undefs(file_lines) end def build_lines - coverage_exceeding_source_warn if coverage_data.fetch(:lines).size > src.size + coverage_exceeding_source_warn if lines_data.size > src.size lines = src.map.with_index(1) do |src, i| - SimpleCov::SourceFile::Line.new(src, i, coverage_data.fetch(:lines)[i - 1]) + SimpleCov::SourceFile::Line.new(src, i, lines_data[i - 1]) end process_skipped_lines(lines) end @@ -254,9 +254,13 @@ def lines_strength lines.map(&:coverage).compact.reduce(:+) end + def lines_data + coverage_data.fetch(:lines) + end + # Warning to identify condition from Issue #56 def coverage_exceeding_source_warn - warn "Warning: coverage data provided by Coverage [#{coverage_data['lines'].size}] exceeds number of lines in #{filename} [#{src.size}]" + warn "Warning: coverage data provided by Coverage [#{lines_data.size}] exceeds number of lines in #{filename} [#{src.size}]" end # @@ -296,35 +300,15 @@ def process_skipped_branches(branches) branches end - # Since we are dumping to and loading from JSON, and we have arrays as keys those - # don't make their way back to us intact e.g. just as a string - # - # We should probably do something different here, but as it stands these are - # our data structures that we write so eval isn't _too_ bad. - # - # See #801 - # - def restore_ruby_data_structure(structure) - return structure # TODO[@tycooon]: remove - # Tests use the real data structures (except for integration tests) so no need to - # put them through here. - return structure if structure.is_a?(Array) - - # rubocop:disable Security/Eval - eval structure - # rubocop:enable Security/Eval - end - def build_branches_from(condition, branches) # the format handed in from the coverage data is like this: # # [:then, 4, 6, 6, 6, 10] # # which is [type, id, start_line, start_col, end_line, end_col] - _condition_type, _condition_id, condition_start_line, * = restore_ruby_data_structure(condition) + _condition_type, _condition_id, condition_start_line, * = condition branches.map do |branch_data, hit_count| - branch_data = restore_ruby_data_structure(branch_data) build_branch(branch_data, hit_count, condition_start_line) end end diff --git a/spec/combine/results_combiner_spec.rb b/spec/combine/results_combiner_spec.rb index a0af4081..df32ad68 100644 --- a/spec/combine/results_combiner_spec.rb +++ b/spec/combine/results_combiner_spec.rb @@ -7,39 +7,39 @@ let(:resultset1) do { source_fixture("sample.rb") => { - "lines" => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], - "branches" => {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 47, [:else, 5, 8, 6, 8, 36] => 24}} + lines: [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], + branches: {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 47, [:else, 5, 8, 6, 8, 36] => 24}} # TODO: add method cov? }, source_fixture("app/models/user.rb") => { - "lines" => [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil], - "branches" => {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 47, [:else, 5, 8, 6, 8, 36] => 24}} + lines: [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil], + branches: {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 47, [:else, 5, 8, 6, 8, 36] => 24}} }, - source_fixture("app/controllers/sample_controller.rb") => {"lines" => [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]}, - source_fixture("resultset1.rb") => {"lines" => [1, 1, 1, 1]}, - source_fixture("parallel_tests.rb") => {"lines" => [nil, 0, nil, 0]}, - source_fixture("conditionally_loaded_1.rb") => {"lines" => [nil, 0, 1]}, # loaded only in the first resultset - source_fixture("three.rb") => {"lines" => [nil, 1, 1]} + source_fixture("app/controllers/sample_controller.rb") => {lines: [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]}, + source_fixture("resultset1.rb") => {lines: [1, 1, 1, 1]}, + source_fixture("parallel_tests.rb") => {lines: [nil, 0, nil, 0]}, + source_fixture("conditionally_loaded_1.rb") => {lines: [nil, 0, 1]}, # loaded only in the first resultset + source_fixture("three.rb") => {lines: [nil, 1, 1]} } end let(:resultset2) do { - source_fixture("sample.rb") => {"lines" => [1, nil, 1, 1, nil, nil, 1, 1, nil, nil]}, + source_fixture("sample.rb") => {lines: [1, nil, 1, 1, nil, nil, 1, 1, nil, nil]}, source_fixture("app/models/user.rb") => { - "lines" => [nil, 1, 5, 1, nil, nil, 1, 0, nil, nil], - "branches" => {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 1, [:else, 5, 8, 6, 8, 36] => 2}} + lines: [nil, 1, 5, 1, nil, nil, 1, 0, nil, nil], + branches: {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 1, [:else, 5, 8, 6, 8, 36] => 2}} }, - source_fixture("app/controllers/sample_controller.rb") => {"lines" => [nil, 3, 1, nil, nil, nil, 1, 0, nil, nil]}, - source_fixture("resultset2.rb") => {"lines" => [nil, 1, 1, nil]}, - source_fixture("parallel_tests.rb") => {"lines" => [nil, nil, 0, 0]}, - source_fixture("conditionally_loaded_2.rb") => {"lines" => [nil, 0, 1]}, # loaded only in the second resultset - source_fixture("three.rb") => {"lines" => [nil, 1, 4]} + source_fixture("app/controllers/sample_controller.rb") => {lines: [nil, 3, 1, nil, nil, nil, 1, 0, nil, nil]}, + source_fixture("resultset2.rb") => {lines: [nil, 1, 1, nil]}, + source_fixture("parallel_tests.rb") => {lines: [nil, nil, 0, 0]}, + source_fixture("conditionally_loaded_2.rb") => {lines: [nil, 0, 1]}, # loaded only in the second resultset + source_fixture("three.rb") => {lines: [nil, 1, 4]} } end let(:resultset3) do - {source_fixture("three.rb") => {"lines" => [nil, 1, 2]}} + {source_fixture("three.rb") => {lines: [nil, 1, 2]}} end after do @@ -56,70 +56,72 @@ end it "has proper results for sample.rb" do - expect(subject[source_fixture("sample.rb")]["lines"]).to eq([1, 1, 2, 2, nil, nil, 2, 2, nil, nil]) + expect(subject[source_fixture("sample.rb")][:lines]).to eq([1, 1, 2, 2, nil, nil, 2, 2, nil, nil]) + + # TODO: add method cov # gotta configure max line so it doesn't get ridiculous # rubocop:disable Style/IfUnlessModifier if SimpleCov.branch_coverage_supported? - expect(subject[source_fixture("sample.rb")]["branches"][[:if, 3, 8, 6, 8, 36]][[:then, 4, 8, 6, 8, 12]]).to eq(47) + expect(subject[source_fixture("sample.rb")][:branches][[:if, 3, 8, 6, 8, 36]][[:then, 4, 8, 6, 8, 12]]).to eq(47) end # rubocop:enable Style/IfUnlessModifier end it "has proper results for user.rb" do - expect(subject[source_fixture("app/models/user.rb")]["lines"]).to eq([nil, 2, 6, 2, nil, nil, 2, 0, nil, nil]) + expect(subject[source_fixture("app/models/user.rb")][:lines]).to eq([nil, 2, 6, 2, nil, nil, 2, 0, nil, nil]) if SimpleCov.branch_coverage_supported? - expect(subject[source_fixture("app/models/user.rb")]["branches"][[:if, 3, 8, 6, 8, 36]][[:then, 4, 8, 6, 8, 12]]).to eq(48) - expect(subject[source_fixture("app/models/user.rb")]["branches"][[:if, 3, 8, 6, 8, 36]][[:else, 5, 8, 6, 8, 36]]).to eq(26) + expect(subject[source_fixture("app/models/user.rb")][:branches][[:if, 3, 8, 6, 8, 36]][[:then, 4, 8, 6, 8, 12]]).to eq(48) + expect(subject[source_fixture("app/models/user.rb")][:branches][[:if, 3, 8, 6, 8, 36]][[:else, 5, 8, 6, 8, 36]]).to eq(26) end end it "has proper results for sample_controller.rb" do - expect(subject[source_fixture("app/controllers/sample_controller.rb")]["lines"]).to eq([nil, 4, 2, 1, nil, nil, 2, 0, nil, nil]) + expect(subject[source_fixture("app/controllers/sample_controller.rb")][:lines]).to eq([nil, 4, 2, 1, nil, nil, 2, 0, nil, nil]) end it "has proper results for resultset1.rb" do - expect(subject[source_fixture("resultset1.rb")]["lines"]).to eq([1, 1, 1, 1]) + expect(subject[source_fixture("resultset1.rb")][:lines]).to eq([1, 1, 1, 1]) end it "has proper results for resultset2.rb" do - expect(subject[source_fixture("resultset2.rb")]["lines"]).to eq([nil, 1, 1, nil]) + expect(subject[source_fixture("resultset2.rb")][:lines]).to eq([nil, 1, 1, nil]) end it "has proper results for parallel_tests.rb" do - expect(subject[source_fixture("parallel_tests.rb")]["lines"]).to eq([nil, nil, nil, 0]) + expect(subject[source_fixture("parallel_tests.rb")][:lines]).to eq([nil, nil, nil, 0]) end it "has proper results for conditionally_loaded_1.rb" do - expect(subject[source_fixture("conditionally_loaded_1.rb")]["lines"]).to eq([nil, 0, 1]) + expect(subject[source_fixture("conditionally_loaded_1.rb")][:lines]).to eq([nil, 0, 1]) end it "has proper results for conditionally_loaded_2.rb" do - expect(subject[source_fixture("conditionally_loaded_2.rb")]["lines"]).to eq([nil, 0, 1]) + expect(subject[source_fixture("conditionally_loaded_2.rb")][:lines]).to eq([nil, 0, 1]) end it "has proper results for three.rb" do - expect(subject[source_fixture("three.rb")]["lines"]).to eq([nil, 3, 7]) + expect(subject[source_fixture("three.rb")][:lines]).to eq([nil, 3, 7]) end end end it "merges frozen resultsets" do resultset1 = { - source_fixture("sample.rb").freeze => {"lines" => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil]}, - source_fixture("app/models/user.rb").freeze => {"lines" => [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]} + source_fixture("sample.rb").freeze => {lines: [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil]}, + source_fixture("app/models/user.rb").freeze => {lines: [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]} } resultset2 = { - source_fixture("sample.rb").freeze => {"lines" => [1, nil, 1, 1, nil, nil, 1, 1, nil, nil]} + source_fixture("sample.rb").freeze => {lines: [1, nil, 1, 1, nil, nil, 1, 1, nil, nil]} } merged_result = SimpleCov::Combine::ResultsCombiner.combine(resultset1, resultset2) expect(merged_result.keys).to eq(resultset1.keys) expect(merged_result.values.map(&:frozen?)).to eq([false, false]) - expect(merged_result[source_fixture("sample.rb")]["lines"]).to eq([1, 1, 2, 2, nil, nil, 2, 2, nil, nil]) - expect(merged_result[source_fixture("app/models/user.rb")]["lines"]).to eq([nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]) + expect(merged_result[source_fixture("sample.rb")][:lines]).to eq([1, 1, 2, 2, nil, nil, 2, 2, nil, nil]) + expect(merged_result[source_fixture("app/models/user.rb")][:lines]).to eq([nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]) end end diff --git a/spec/file_list_spec.rb b/spec/file_list_spec.rb index 7de0eac6..03325cbb 100644 --- a/spec/file_list_spec.rb +++ b/spec/file_list_spec.rb @@ -6,17 +6,17 @@ subject do original_result = { source_fixture("sample.rb") => { - "lines" => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], - "branches" => {} + lines: [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], + branches: {} # TODO: add method cov }, source_fixture("app/models/user.rb") => { - "lines" => [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil], - "branches" => {} + lines: [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil], + branches: {} }, source_fixture("app/controllers/sample_controller.rb") => { - "lines" => [nil, 2, 2, 0, nil, nil, 0, nil, nil, nil], - "branches" => {} + lines: [nil, 2, 2, 0, nil, nil, 0, nil, nil, nil], + branches: {} } } SimpleCov::Result.new(original_result).files diff --git a/spec/result_merger_spec.rb b/spec/result_merger_spec.rb index 42234513..5f2223a9 100644 --- a/spec/result_merger_spec.rb +++ b/spec/result_merger_spec.rb @@ -13,21 +13,21 @@ describe "with two faked coverage resultsets" do before do @resultset1 = { - source_fixture("sample.rb") => {"lines" => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil]}, - source_fixture("app/models/user.rb") => {"lines" => [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]}, - source_fixture("app/controllers/sample_controller.rb") => {"lines" => [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]}, - source_fixture("resultset1.rb") => {"lines" => [1, 1, 1, 1]}, - source_fixture("parallel_tests.rb") => {"lines" => [nil, 0, nil, 0]}, - source_fixture("conditionally_loaded_1.rb") => {"lines" => [nil, 0, 1]} # loaded only in the first resultset + source_fixture("sample.rb") => {lines: [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil]}, + source_fixture("app/models/user.rb") => {lines: [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]}, + source_fixture("app/controllers/sample_controller.rb") => {lines: [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]}, + source_fixture("resultset1.rb") => {lines: [1, 1, 1, 1]}, + source_fixture("parallel_tests.rb") => {lines: [nil, 0, nil, 0]}, + source_fixture("conditionally_loaded_1.rb") => {lines: [nil, 0, 1]} # loaded only in the first resultset } @resultset2 = { - source_fixture("sample.rb") => {"lines" => [1, nil, 1, 1, nil, nil, 1, 1, nil, nil]}, - source_fixture("app/models/user.rb") => {"lines" => [nil, 1, 5, 1, nil, nil, 1, 0, nil, nil]}, - source_fixture("app/controllers/sample_controller.rb") => {"lines" => [nil, 3, 1, nil, nil, nil, 1, 0, nil, nil]}, - source_fixture("resultset2.rb") => {"lines" => [nil, 1, 1, nil]}, - source_fixture("parallel_tests.rb") => {"lines" => [nil, nil, 0, 0]}, - source_fixture("conditionally_loaded_2.rb") => {"lines" => [nil, 0, 1]} # loaded only in the second resultset + source_fixture("sample.rb") => {lines: [1, nil, 1, 1, nil, nil, 1, 1, nil, nil]}, + source_fixture("app/models/user.rb") => {lines: [nil, 1, 5, 1, nil, nil, 1, 0, nil, nil]}, + source_fixture("app/controllers/sample_controller.rb") => {lines: [nil, 3, 1, nil, nil, nil, 1, 0, nil, nil]}, + source_fixture("resultset2.rb") => {lines: [nil, 1, 1, nil]}, + source_fixture("parallel_tests.rb") => {lines: [nil, nil, 0, 0]}, + source_fixture("conditionally_loaded_2.rb") => {lines: [nil, 0, 1]} # loaded only in the second resultset } end diff --git a/spec/result_spec.rb b/spec/result_spec.rb index 462a6787..4d367bb8 100644 --- a/spec/result_spec.rb +++ b/spec/result_spec.rb @@ -21,9 +21,9 @@ let(:original_result) do { - source_fixture("sample.rb") => {"lines" => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil]}, - source_fixture("app/models/user.rb") => {"lines" => [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]}, - source_fixture("app/controllers/sample_controller.rb") => {"lines" => [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]} + source_fixture("sample.rb") => {lines: [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil]}, + source_fixture("app/models/user.rb") => {lines: [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]}, + source_fixture("app/controllers/sample_controller.rb") => {lines: [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]} } end @@ -212,7 +212,7 @@ old_resultset = {source_fixture("three.rb") => [nil, 1, 2]} expect(described_class.new(old_resultset).original_result).to eq( - source_fixture("three.rb") => {"lines" => [nil, 1, 2]} + source_fixture("three.rb") => {lines: [nil, 1, 2]} ) end end diff --git a/spec/simplecov_spec.rb b/spec/simplecov_spec.rb index 17962702..4306b4de 100644 --- a/spec/simplecov_spec.rb +++ b/spec/simplecov_spec.rb @@ -192,11 +192,11 @@ describe ".collate" do let(:resultset1) do - {source_fixture("sample.rb") => {"lines" => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil]}} + {source_fixture("sample.rb") => {lines: [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil]}} end let(:resultset2) do - {source_fixture("sample.rb") => {"lines" => [1, nil, 1, 1, nil, nil, 1, 1, nil, nil]}} + {source_fixture("sample.rb") => {lines: [1, nil, 1, 1, nil, nil, 1, 1, nil, nil]}} end let(:resultset_path) { SimpleCov::ResultMerger.resultset_path } diff --git a/spec/source_file_spec.rb b/spec/source_file_spec.rb index c9a518cb..6ae17ac5 100644 --- a/spec/source_file_spec.rb +++ b/spec/source_file_spec.rb @@ -4,12 +4,12 @@ describe SimpleCov::SourceFile do COVERAGE_FOR_SAMPLE_RB = { - "lines" => [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil, nil, 1, 0, nil, nil, nil], - "branches" => {} + lines: [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil, nil, 1, 0, nil, nil, nil], + branches: {} }.freeze COVERAGE_FOR_SAMPLE_RB_WITH_MORE_LINES = { - "lines" => [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil, nil, nil, nil, nil, nil, nil, nil] + lines: [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil, nil, nil, nil, nil, nil, nil, nil] }.freeze context "a source file initialized with some coverage data" do @@ -95,8 +95,8 @@ context "file with branches" do COVERAGE_FOR_BRANCHES_RB = { - "lines" => [1, 1, 1, nil, 1, nil, 1, 0, nil, 1, nil, nil, nil], - "branches" => { + lines: [1, 1, 1, nil, 1, nil, 1, 0, nil, 1, nil, nil, nil], + branches: { [:if, 0, 3, 4, 3, 21] => {[:then, 1, 3, 4, 3, 10] => 0, [:else, 2, 3, 4, 3, 21] => 1}, [:if, 3, 5, 4, 5, 26] => @@ -185,8 +185,8 @@ context "A file that has inline branches" do COVERAGE_FOR_INLINE = { - "lines" => [1, 1, 1, nil, 1, 1, 0, nil, 1, nil, nil, nil, nil], - "branches" => { + lines: [1, 1, 1, nil, 1, 1, 0, nil, 1, nil, nil, nil, nil], + branches: { [:if, 0, 3, 11, 3, 33] => {[:then, 1, 3, 23, 3, 27] => 1, [:else, 2, 3, 30, 3, 33] => 0}, [:if, 3, 6, 6, 10, 9] => @@ -217,7 +217,7 @@ end context "a file that is never relevant" do - COVERAGE_FOR_NEVER_RB = {"lines" => [nil, nil], "branches" => {}}.freeze + COVERAGE_FOR_NEVER_RB = {lines: [nil, nil], branches: {}}.freeze subject do SimpleCov::SourceFile.new(source_fixture("never.rb"), COVERAGE_FOR_NEVER_RB) @@ -237,7 +237,7 @@ end context "a file where nothing is ever executed mixed with skipping #563" do - COVERAGE_FOR_SKIPPED_RB = {"lines" => [nil, nil, nil, nil]}.freeze + COVERAGE_FOR_SKIPPED_RB = {lines: [nil, nil, nil, nil]}.freeze subject do SimpleCov::SourceFile.new(source_fixture("skipped.rb"), COVERAGE_FOR_SKIPPED_RB) @@ -253,7 +253,7 @@ end context "a file where everything is skipped and missed #563" do - COVERAGE_FOR_SKIPPED_RB_2 = {"lines" => [nil, nil, 0, nil]}.freeze + COVERAGE_FOR_SKIPPED_RB_2 = {lines: [nil, nil, 0, nil]}.freeze subject do SimpleCov::SourceFile.new(source_fixture("skipped.rb"), COVERAGE_FOR_SKIPPED_RB_2) @@ -275,8 +275,8 @@ context "a file where everything is skipped/irrelevant but executed #563" do COVERAGE_FOR_SKIPPED_AND_EXECUTED_RB = { - "lines" => [nil, nil, 1, 1, 0, 0, nil, 0, nil, nil, nil, nil], - "branches" => { + lines: [nil, nil, 1, 1, 0, 0, nil, 0, nil, nil, nil, nil], + branches: { [:if, 0, 5, 4, 9, 7] => {[:then, 1, 6, 6, 6, 7] => 1, [:else, 2, 8, 6, 8, 7] => 0} } @@ -331,8 +331,8 @@ context "a file with more complex skipping" do COVERAGE_FOR_NOCOV_COMPLEX_RB = { - "lines" => [nil, nil, 1, 1, nil, 1, nil, nil, nil, 1, nil, nil, 1, nil, nil, 0, nil, 1, nil, 0, nil, nil, 1, nil, nil, nil, nil], - "branches" => { + lines: [nil, nil, 1, 1, nil, 1, nil, nil, nil, 1, nil, nil, 1, nil, nil, 0, nil, 1, nil, 0, nil, nil, 1, nil, nil, nil, nil], + branches: { [:if, 0, 6, 4, 11, 7] => {[:then, 1, 7, 6, 7, 7] => 0, [:else, 2, 10, 6, 10, 7] => 1}, [:if, 3, 13, 4, 13, 24] => @@ -392,8 +392,8 @@ context "a file with nested branches" do COVERAGE_FOR_NESTED_BRANCHES_RB = { - "lines" => [nil, nil, 1, 1, 1, 1, 1, 1, nil, nil, 0, nil, nil, nil, nil], - "branches" => { + lines: [nil, nil, 1, 1, 1, 1, 1, 1, nil, nil, 0, nil, nil, nil, nil], + branches: { [:while, 0, 7, 8, 7, 31] => {[:body, 1, 7, 8, 7, 16] => 2}, [:if, 2, 6, 6, 9, 9] => @@ -428,8 +428,8 @@ context "a file with case" do COVERAGE_FOR_CASE_STATEMENT_RB = { - "lines" => [1, 1, 1, nil, 0, nil, 1, nil, 0, nil, 0, nil, nil, nil], - "branches" => { + lines: [1, 1, 1, nil, 0, nil, 1, nil, 0, nil, 0, nil, nil, nil], + branches: { [:case, 0, 3, 4, 12, 7] => { [:when, 1, 5, 6, 5, 10] => 0, [:when, 2, 7, 6, 7, 10] => 1, @@ -471,8 +471,8 @@ context "a file with case without else" do COVERAGE_FOR_CASE_WITHOUT_ELSE_STATEMENT_RB = { - "lines" => [1, 1, 1, nil, 0, nil, 1, nil, 0, nil, nil, nil], - "branches" => { + lines: [1, 1, 1, nil, 0, nil, 1, nil, 0, nil, nil, nil], + branches: { [:case, 0, 3, 4, 10, 7] => { [:when, 1, 5, 6, 5, 10] => 0, [:when, 2, 7, 6, 7, 10] => 1, @@ -518,8 +518,8 @@ context "a file with if/elsif" do COVERAGE_FOR_ELSIF_RB = { - "lines" => [1, 1, 1, 0, 1, 0, 1, 1, nil, 0, nil, nil, nil], - "branches" => { + lines: [1, 1, 1, 0, 1, 0, 1, 1, nil, 0, nil, nil, nil], + branches: { [:if, 0, 7, 4, 10, 10] => {[:then, 1, 8, 6, 8, 10] => 1, [:else, 2, 10, 6, 10, 10] => 0}, [:if, 3, 5, 4, 10, 10] => @@ -556,8 +556,8 @@ context "the branch tester script" do COVERAGE_FOR_BRANCH_TESTER_RB = { - "lines" => [nil, nil, 1, 1, nil, 1, nil, 1, 1, nil, nil, 1, 0, nil, nil, 1, 0, nil, 1, nil, nil, 1, 1, 1, nil, nil, 1, 0, nil, nil, 1, 1, nil, 0, nil, 1, 1, 0, 0, 1, 5, 0, 0, nil, 0, nil, 0, nil, nil, nil], - "branches" => { + lines: [nil, nil, 1, 1, nil, 1, nil, 1, 1, nil, nil, 1, 0, nil, nil, 1, 0, nil, 1, nil, nil, 1, 1, 1, nil, nil, 1, 0, nil, nil, 1, 1, nil, 0, nil, 1, 1, 0, 0, 1, 5, 0, 0, nil, 0, nil, 0, nil, nil, nil], + branches: { [:if, 0, 4, 0, 4, 19] => {[:then, 1, 4, 12, 4, 15] => 0, [:else, 2, 4, 18, 4, 19] => 1}, [:unless, 3, 6, 0, 6, 23] => @@ -610,8 +610,8 @@ 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" => { + 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] => @@ -655,8 +655,8 @@ 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" => { + 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] => @@ -698,9 +698,9 @@ end context "a file contains non-ASCII characters" do - COVERAGE_FOR_SINGLE_LINE = {"lines" => [nil]}.freeze - COVERAGE_FOR_DOUBLE_LINES = {"lines" => [nil, 1]}.freeze - COVERAGE_FOR_TRIPLE_LINES = {"lines" => [nil, nil, 1]}.freeze + COVERAGE_FOR_SINGLE_LINE = {lines: [nil]}.freeze + COVERAGE_FOR_DOUBLE_LINES = {lines: [nil, 1]}.freeze + COVERAGE_FOR_TRIPLE_LINES = {lines: [nil, nil, 1]}.freeze DEGREE_135_LINE = "puts \"135°C\"\n" shared_examples_for "converting to UTF-8" do @@ -766,7 +766,7 @@ describe "empty euc-jp file" do subject do - SimpleCov::SourceFile.new(source_fixture("empty_euc-jp.rb"), "lines" => []) + SimpleCov::SourceFile.new(source_fixture("empty_euc-jp.rb"), lines: []) end it "has empty lines" do diff --git a/spec/useless_results_remover_spec.rb b/spec/useless_results_remover_spec.rb index cafa56b5..f4b107cd 100644 --- a/spec/useless_results_remover_spec.rb +++ b/spec/useless_results_remover_spec.rb @@ -9,13 +9,13 @@ let(:result_set) do { gem_file_path => { - "lines" => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], - "branches" => {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 47, [:else, 5, 8, 6, 8, 36] => 24}} + lines: [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], + branches: {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 47, [:else, 5, 8, 6, 8, 36] => 24}} # TODO: add method cov? }, source_path => { - "lines" => [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil], - "branches" => {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 47, [:else, 5, 8, 6, 8, 36] => 24}} + lines: [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil], + branches: {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 47, [:else, 5, 8, 6, 8, 36] => 24}} } } end @@ -31,6 +31,6 @@ it "still retains the app path" do expect(subject).to have_key(source_path) - expect(subject[source_path]["lines"]).to be_kind_of(Array) + expect(subject[source_path][:lines]).to be_kind_of(Array) end end From 31b95e7536d585500f6ee336ca35a918cf4c5dd7 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Wed, 2 Sep 2020 19:14:12 +0300 Subject: [PATCH 07/33] add methods combiner --- Gemfile | 2 +- Gemfile.lock | 7 +---- lib/simplecov.rb | 4 +-- lib/simplecov/combine/files_combiner.rb | 3 +-- lib/simplecov/combine/methods_combiner.rb | 31 +++++++++++++++++++++++ lib/simplecov/combine/results_combiner.rb | 2 +- lib/simplecov/file_list.rb | 17 ++++++++----- lib/simplecov/simulate_coverage.rb | 2 +- lib/simplecov/source_file.rb | 2 +- lib/simplecov/source_file/method.rb | 4 +-- spec/combine/results_combiner_spec.rb | 16 +++++++----- 11 files changed, 60 insertions(+), 30 deletions(-) create mode 100644 lib/simplecov/combine/methods_combiner.rb diff --git a/Gemfile b/Gemfile index 4422fd79..9688762b 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ source "https://rubygems.org" # Uncomment this to use local copy of simplecov-html in development when checked out -gem "simplecov-html", path: File.dirname(__FILE__) + "/../simplecov-html" +# gem "simplecov-html", path: File.dirname(__FILE__) + "/../simplecov-html" # Uncomment this to use development version of html formatter from github # gem "simplecov-html", github: "colszowka/simplecov-html" diff --git a/Gemfile.lock b/Gemfile.lock index 4b581c5c..5ceb1e75 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,11 +5,6 @@ PATH docile (~> 1.1) simplecov-html (~> 0.11) -PATH - remote: ../simplecov-html - specs: - simplecov-html (0.12.2) - GEM remote: https://rubygems.org/ specs: @@ -141,6 +136,7 @@ GEM rubocop-ast (0.3.0) parser (>= 2.7.1.4) ruby-progressbar (1.10.1) + simplecov-html (0.12.2) spoon (0.0.6) ffi sys-uname (1.2.1) @@ -178,7 +174,6 @@ DEPENDENCIES rspec (~> 3.2) rubocop simplecov! - simplecov-html! test-unit BUNDLED WITH diff --git a/lib/simplecov.rb b/lib/simplecov.rb index e7a1572c..aa96c809 100644 --- a/lib/simplecov.rb +++ b/lib/simplecov.rb @@ -356,7 +356,7 @@ def start_coverage_with_criteria CRITERION_TO_RUBY_COVERAGE = { branch: :branches, line: :lines, - method: :methods, + method: :methods }.freeze def lookup_corresponding_ruby_coverage_name(criterion) CRITERION_TO_RUBY_COVERAGE.fetch(criterion) @@ -460,7 +460,7 @@ def probably_running_parallel_tests? require_relative "simplecov/result_adapter" require_relative "simplecov/combine" require_relative "simplecov/combine/branches_combiner" -# require_relative "simplecov/combine/methods_combiner" +require_relative "simplecov/combine/methods_combiner" require_relative "simplecov/combine/files_combiner" require_relative "simplecov/combine/lines_combiner" require_relative "simplecov/combine/results_combiner" diff --git a/lib/simplecov/combine/files_combiner.rb b/lib/simplecov/combine/files_combiner.rb index b70429d6..f4a5725f 100644 --- a/lib/simplecov/combine/files_combiner.rb +++ b/lib/simplecov/combine/files_combiner.rb @@ -20,10 +20,9 @@ def combine(coverage_a, coverage_b) if SimpleCov.branch_coverage? combination[:branches] = Combine.combine(BranchesCombiner, coverage_a[:branches], coverage_b[:branches]) + combination[:methods] = Combine.combine(MethodsCombiner, coverage_a[:methods], coverage_b[:methods]) end - # TODO: add method cov - combination end end diff --git a/lib/simplecov/combine/methods_combiner.rb b/lib/simplecov/combine/methods_combiner.rb new file mode 100644 index 00000000..b842c423 --- /dev/null +++ b/lib/simplecov/combine/methods_combiner.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module SimpleCov + module Combine + # + # Combine different method coverage results on single file. + # + # Should be called through `SimpleCov.combine`. + module MethodsCombiner + module_function + + # + # TODO[@tycooon]: add description + # + # @return [Hash] + # + def combine(coverage_a, coverage_b) + result_coverage = {} + + keys = (coverage_a.keys + coverage_b.keys).uniq + + keys.each do |method_name| + result_coverage[method_name] = + coverage_a.fetch(method_name, 0) + coverage_b.fetch(method_name, 0) + end + + result_coverage + end + end + end +end diff --git a/lib/simplecov/combine/results_combiner.rb b/lib/simplecov/combine/results_combiner.rb index 9f3896e6..2ebf8edc 100644 --- a/lib/simplecov/combine/results_combiner.rb +++ b/lib/simplecov/combine/results_combiner.rb @@ -16,7 +16,7 @@ module ResultsCombiner # ==> FileCombiner: collect result of next combine levels lines and branches. # ===> LinesCombiner: combine lines results. # ===> BranchesCombiner: combine branches results. - # TODO: add method cov + # ===> MethodsCombiner: combine methods results. # # @return [Hash] # diff --git a/lib/simplecov/file_list.rb b/lib/simplecov/file_list.rb index 2b20fc49..d48e7202 100644 --- a/lib/simplecov/file_list.rb +++ b/lib/simplecov/file_list.rb @@ -98,21 +98,24 @@ def branch_covered_percent coverage_statistics[:branch]&.percent end - # TODO: add method cov methods for html report + # TODO: add method cov methods for html report private def compute_coverage_statistics - total_coverage_statistics = @files.each_with_object(line: [], branch: [], method: []) do |file, together| - together[:line] << file.coverage_statistics[:line] - together[:branch] << file.coverage_statistics[:branch] if SimpleCov.branch_coverage? - together[:method] << file.coverage_statistics[:method] if SimpleCov.method_coverage? - end - + total_coverage_statistics = compute_total_coverage_statistics coverage_statistics = {line: CoverageStatistics.from(total_coverage_statistics[:line])} coverage_statistics[:branch] = CoverageStatistics.from(total_coverage_statistics[:branch]) if SimpleCov.branch_coverage? coverage_statistics[:method] = CoverageStatistics.from(total_coverage_statistics[:method]) if SimpleCov.method_coverage? coverage_statistics end + + def compute_total_coverage_statistics + @files.each_with_object(line: [], branch: [], method: []) do |file, together| + together[:line] << file.coverage_statistics[:line] + together[:branch] << file.coverage_statistics[:branch] if SimpleCov.branch_coverage? + together[:method] << file.coverage_statistics[:method] if SimpleCov.method_coverage? + end + end end end diff --git a/lib/simplecov/simulate_coverage.rb b/lib/simplecov/simulate_coverage.rb index bc95bfe5..f75122db 100644 --- a/lib/simplecov/simulate_coverage.rb +++ b/lib/simplecov/simulate_coverage.rb @@ -23,7 +23,7 @@ def call(absolute_path) # we don't want to parse branches ourselves... # requiring files can have side effects and we don't want to trigger that branches: {}, - methods: {}, + methods: {} } end end diff --git a/lib/simplecov/source_file.rb b/lib/simplecov/source_file.rb index 583495db..3adb7f3d 100644 --- a/lib/simplecov/source_file.rb +++ b/lib/simplecov/source_file.rb @@ -34,7 +34,7 @@ def coverage_statistics { **line_coverage_statistics, **branch_coverage_statistics, - **method_coverage_statistics, + **method_coverage_statistics } end diff --git a/lib/simplecov/source_file/method.rb b/lib/simplecov/source_file/method.rb index f30f7d77..3096dad4 100644 --- a/lib/simplecov/source_file/method.rb +++ b/lib/simplecov/source_file/method.rb @@ -3,8 +3,7 @@ module SimpleCov class SourceFile class Method - attr_reader :source_file, :coverage - attr_reader :klass, :method, :start_line, :start_col, :end_line, :end_col + attr_reader :source_file, :coverage, :klass, :method, :start_line, :start_col, :end_line, :end_col def initialize(source_file, info, coverage) @source_file = source_file @@ -18,6 +17,7 @@ def covered? def skipped? return @skipped if defined?(@skipped) + @skipped = lines.all?(&:skipped?) end diff --git a/spec/combine/results_combiner_spec.rb b/spec/combine/results_combiner_spec.rb index df32ad68..abc605cc 100644 --- a/spec/combine/results_combiner_spec.rb +++ b/spec/combine/results_combiner_spec.rb @@ -9,11 +9,11 @@ source_fixture("sample.rb") => { lines: [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], branches: {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 47, [:else, 5, 8, 6, 8, 36] => 24}} - # TODO: add method cov? }, source_fixture("app/models/user.rb") => { lines: [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil], - branches: {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 47, [:else, 5, 8, 6, 8, 36] => 24}} + branches: {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 47, [:else, 5, 8, 6, 8, 36] => 24}}, + methods: {["#", "foo", 4, 2, 6, 5] => 1} }, source_fixture("app/controllers/sample_controller.rb") => {lines: [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil]}, source_fixture("resultset1.rb") => {lines: [1, 1, 1, 1]}, @@ -28,7 +28,8 @@ source_fixture("sample.rb") => {lines: [1, nil, 1, 1, nil, nil, 1, 1, nil, nil]}, source_fixture("app/models/user.rb") => { lines: [nil, 1, 5, 1, nil, nil, 1, 0, nil, nil], - branches: {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 1, [:else, 5, 8, 6, 8, 36] => 2}} + branches: {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 1, [:else, 5, 8, 6, 8, 36] => 2}}, + methods: {["#", "foo", 4, 2, 6, 5] => 5, ["#", "bar", 1, 2, 3, 4] => 3} }, source_fixture("app/controllers/sample_controller.rb") => {lines: [nil, 3, 1, nil, nil, nil, 1, 0, nil, nil]}, source_fixture("resultset2.rb") => {lines: [nil, 1, 1, nil]}, @@ -58,14 +59,11 @@ it "has proper results for sample.rb" do expect(subject[source_fixture("sample.rb")][:lines]).to eq([1, 1, 2, 2, nil, nil, 2, 2, nil, nil]) - # TODO: add method cov - # gotta configure max line so it doesn't get ridiculous - # rubocop:disable Style/IfUnlessModifier if SimpleCov.branch_coverage_supported? expect(subject[source_fixture("sample.rb")][:branches][[:if, 3, 8, 6, 8, 36]][[:then, 4, 8, 6, 8, 12]]).to eq(47) + expect(subject[source_fixture("sample.rb")][:methods]).to eq(nil) end - # rubocop:enable Style/IfUnlessModifier end it "has proper results for user.rb" do @@ -74,6 +72,10 @@ if SimpleCov.branch_coverage_supported? expect(subject[source_fixture("app/models/user.rb")][:branches][[:if, 3, 8, 6, 8, 36]][[:then, 4, 8, 6, 8, 12]]).to eq(48) expect(subject[source_fixture("app/models/user.rb")][:branches][[:if, 3, 8, 6, 8, 36]][[:else, 5, 8, 6, 8, 36]]).to eq(26) + expect(subject[source_fixture("app/models/user.rb")][:methods]).to eq( + ["#", "foo", 4, 2, 6, 5] => 6, + ["#", "bar", 1, 2, 3, 4] => 3 + ) end end From fa3902aa9bdf93f42cf8b0a03ceee2c820320cb0 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Wed, 2 Sep 2020 19:27:11 +0300 Subject: [PATCH 08/33] update ci config --- .github/workflows/stable.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/stable.yml b/.github/workflows/stable.yml index 6593643e..ad3f2d7e 100644 --- a/.github/workflows/stable.yml +++ b/.github/workflows/stable.yml @@ -4,8 +4,9 @@ on: pull_request: push: - branches: - - master + # TODO[@tycooon]: uncomment + # branches: + # - master jobs: test: From a78b5eda8fce24d16ca28f3308bf20b640b8dd3b Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Thu, 3 Sep 2020 13:17:05 +0300 Subject: [PATCH 09/33] add some backwards compability to result serialization --- Gemfile | 2 +- Gemfile.lock | 7 +- features/branch_coverage.feature | 2 +- features/step_definitions/html_steps.rb | 2 +- lib/simplecov/result_serialization.rb | 7 ++ spec/result_spec.rb | 137 +++++++++++++++++++++--- 6 files changed, 136 insertions(+), 21 deletions(-) diff --git a/Gemfile b/Gemfile index ccbbb9f9..49d8952f 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ source "https://rubygems.org" # Uncomment this to use local copy of simplecov-html in development when checked out -# gem "simplecov-html", path: File.dirname(__FILE__) + "/../simplecov-html" +gem "simplecov-html", path: File.dirname(__FILE__) + "/../simplecov-html" # Uncomment this to use development version of html formatter from github # gem "simplecov-html", github: "simplecov-ruby/simplecov-html" diff --git a/Gemfile.lock b/Gemfile.lock index dc1772d6..226539d3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,6 +5,11 @@ PATH docile (~> 1.1) simplecov-html (~> 0.11) +PATH + remote: ../simplecov-html + specs: + simplecov-html (0.12.2) + GEM remote: https://rubygems.org/ specs: @@ -136,7 +141,6 @@ GEM rubocop-ast (0.3.0) parser (>= 2.7.1.4) ruby-progressbar (1.10.1) - simplecov-html (0.12.2) spoon (0.0.6) ffi sys-uname (1.2.1) @@ -174,6 +178,7 @@ DEPENDENCIES rspec (~> 3.2) rubocop simplecov! + simplecov-html! test-unit BUNDLED WITH diff --git a/features/branch_coverage.feature b/features/branch_coverage.feature index 55f0d096..622cd780 100644 --- a/features/branch_coverage.feature +++ b/features/branch_coverage.feature @@ -21,7 +21,7 @@ Feature: And I should see a line coverage summary of 56/61 And I should see a branch coverage summary of 2/4 And I should see the source files: - | name | coverage | branch coverage | + | name | coverage | branch coverage | | lib/faked_project.rb | 100.00 % | 100.00 % | | lib/faked_project/some_class.rb | 80.00 % | 50.00 % | | lib/faked_project/framework_specific.rb | 75.00 % | 100.00 % | diff --git a/features/step_definitions/html_steps.rb b/features/step_definitions/html_steps.rb index a2cffa7b..3e0f993d 100644 --- a/features/step_definitions/html_steps.rb +++ b/features/step_definitions/html_steps.rb @@ -25,7 +25,7 @@ expected_files = table.hashes available_source_files = all(".t-file", visible: true) - expect(expected_files.length).to eq(available_source_files.count) + expect(available_source_files.count).to eq(expected_files.length) include_branch_coverage = table.column_names.include?("branch coverage") # Find all filenames and their coverage present in coverage report diff --git a/lib/simplecov/result_serialization.rb b/lib/simplecov/result_serialization.rb index 79b138ce..eeb4361e 100644 --- a/lib/simplecov/result_serialization.rb +++ b/lib/simplecov/result_serialization.rb @@ -27,6 +27,8 @@ def deserialize(hash) # rubocop:disable Metrics/MethodLength data["coverage"].each do |file_name, file_data| parsed_file_data = {} + file_data = {lines: file_data} if file_data.is_a?(Array) + file_data.each do |key, value| key = key.to_sym parsed_file_data[key] = deserialize_value(key, value) @@ -91,6 +93,7 @@ def deserialize_branches(value) end def deserialize_branch_info(value) + value = adapt_old_style_branch_info(value) if value.is_a?(Symbol) type, *info = value [type.to_sym, *info] end @@ -107,6 +110,10 @@ def deserialize_methods(value) result end + + def adapt_old_style_branch_info(value) + eval(value.to_s) # rubocop:disable Security/Eval + end end end end diff --git a/spec/result_spec.rb b/spec/result_spec.rb index 296eb0ed..6b540709 100644 --- a/spec/result_spec.rb +++ b/spec/result_spec.rb @@ -207,32 +207,135 @@ end describe ".from_hash" do - let(:other_result) do - { - source_fixture("sample.rb") => {lines: [nil, 1, 1, 1, nil, nil, 0, 0, nil, nil]} - } - end let(:created_at) { Time.now.to_i } - it "can consume multiple commands" do - input = { + let(:input) do + { "rspec" => { "coverage" => original_result, "timestamp" => created_at - }, - "cucumber" => { - "coverage" => other_result, - "timestamp" => created_at } } + end - result = described_class.from_hash(input) + let(:expected_branch_coverage) do + { + [:unless, 0, 8, 4, 8, 90] => { + [:else, 1, 8, 4, 8, 90] => 0, + [:then, 2, 8, 4, 8, 35] => 1 + } + } + end - expect(result.size).to eq 2 - sorted = result.sort_by(&:command_name) - expect(sorted.map(&:command_name)).to eq %w[cucumber rspec] - expect(sorted.map(&:created_at).map(&:to_i)).to eq [created_at, created_at] - expect(sorted.map(&:original_result)).to eq [other_result, original_result] + context "multiple commands" do + let(:other_result) do + { + source_fixture("sample.rb") => {lines: [nil, 1, 1, 1, nil, nil, 0, 0, nil, nil]} + } + end + + let(:input) do + { + "rspec" => { + "coverage" => original_result, + "timestamp" => created_at + }, + "cucumber" => { + "coverage" => other_result, + "timestamp" => created_at + } + } + end + + it "can consume multiple commands" do + result = described_class.from_hash(input) + + expect(result.size).to eq 2 + sorted = result.sort_by(&:command_name) + expect(sorted.map(&:command_name)).to eq %w[cucumber rspec] + expect(sorted.map(&:created_at).map(&:to_i)).to eq [created_at, created_at] + expect(sorted.map(&:original_result)).to eq [other_result, original_result] + end + end + + context "branch and method coverage present" do + let(:original_result) do + { + source_fixture("sample.rb") => { + "lines" => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], + "branches" => [ + [ + ["unless", 0, 8, 4, 8, 90], + [ + [["else", 1, 8, 4, 8, 90], 0], + [["then", 2, 8, 4, 8, 35], 1] + ] + ] + ], + "methods" => [ + [["RSpec::ExampleGroups::SomeClass::LetDefinitions", "subject", 6, 10, 6, 34], 2] + ] + } + } + end + + it "parses that properly" do + result = described_class.from_hash(input) + + expect(result.size).to eq(1) + expect(result.first.original_result.size).to eq(1) + + expect(result.first.original_result.values.last).to eq( + lines: [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], + branches: expected_branch_coverage, + methods: { + ["RSpec::ExampleGroups::SomeClass::LetDefinitions", :subject, 6, 10, 6, 34] => 2 + } + ) + end + end + + context "old style line coverage format" do + let(:original_result) do + { source_fixture("sample.rb") => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil] } + end + + it "parses that properly" do + result = described_class.from_hash(input) + + expect(result.size).to eq(1) + expect(result.first.original_result.size).to eq(1) + + expect(result.first.original_result.values.last).to eq( + lines: [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], + ) + end + end + + context "old style branch coverage format" do + let(:original_result) do + { + source_fixture("sample.rb") => { + "branches" => { + "[:unless, 0, 8, 4, 8, 90]": { + "[:else, 1, 8, 4, 8, 90]": 0, + "[:then, 2, 8, 4, 8, 35]": 1 + } + } + } + } + end + + it "parses that properly" do + result = described_class.from_hash(input) + + expect(result.size).to eq(1) + expect(result.first.original_result.size).to eq(1) + + expect(result.first.original_result.values.last).to eq( + branches: expected_branch_coverage + ) + end end end end From b16b6e527c9adaa37353456bfe113f380a5b1105 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Thu, 3 Sep 2020 18:15:21 +0300 Subject: [PATCH 10/33] add some methods for html report --- lib/simplecov/combine/branches_combiner.rb | 2 +- lib/simplecov/combine/methods_combiner.rb | 2 +- lib/simplecov/file_list.rb | 19 +++- lib/simplecov/source_file.rb | 8 ++ spec/file_list_spec.rb | 10 +- spec/result_spec.rb | 118 ++++++++++++++------- spec/simplecov_spec.rb | 1 - spec/source_file/branch_spec.rb | 1 - spec/source_file/method_spec.rb | 7 ++ spec/source_file_spec.rb | 2 +- spec/useless_results_remover_spec.rb | 7 +- 11 files changed, 127 insertions(+), 50 deletions(-) create mode 100644 spec/source_file/method_spec.rb diff --git a/lib/simplecov/combine/branches_combiner.rb b/lib/simplecov/combine/branches_combiner.rb index 320f648f..2f0f4acd 100644 --- a/lib/simplecov/combine/branches_combiner.rb +++ b/lib/simplecov/combine/branches_combiner.rb @@ -10,7 +10,7 @@ module BranchesCombiner module_function # - # Return merged branches or the existed brach if other is missing. + # Return merged branches or the existing branch if other is missing. # # Branches inside files are always same if they exist, the difference only in coverage count. # Branch coverage report for any conditional case is built from hash, it's key is a condition and diff --git a/lib/simplecov/combine/methods_combiner.rb b/lib/simplecov/combine/methods_combiner.rb index b842c423..67604285 100644 --- a/lib/simplecov/combine/methods_combiner.rb +++ b/lib/simplecov/combine/methods_combiner.rb @@ -10,7 +10,7 @@ module MethodsCombiner module_function # - # TODO[@tycooon]: add description + # Combine method coverage from 2 sources # # @return [Hash] # diff --git a/lib/simplecov/file_list.rb b/lib/simplecov/file_list.rb index d48e7202..61f81d3b 100644 --- a/lib/simplecov/file_list.rb +++ b/lib/simplecov/file_list.rb @@ -98,7 +98,24 @@ def branch_covered_percent coverage_statistics[:branch]&.percent end - # TODO: add method cov methods for html report + # Return total count of methods in all files + def total_methods + coverage_statistics[:method]&.total + end + + # Return total count of covered methods + def covered_methods + coverage_statistics[:method]&.covered + end + + # Return total count of covered methods + def missed_methods + coverage_statistics[:method]&.missed + end + + def method_covered_percent + coverage_statistics[:method]&.percent + end private diff --git a/lib/simplecov/source_file.rb b/lib/simplecov/source_file.rb index 3adb7f3d..1c5bff55 100644 --- a/lib/simplecov/source_file.rb +++ b/lib/simplecov/source_file.rb @@ -159,6 +159,10 @@ def methods @methods ||= build_methods end + def total_methods + @total_methods ||= covered_methods + missed_methods + end + def covered_methods methods.select(&:covered?) end @@ -167,6 +171,10 @@ def missed_methods methods.select(&:missed?) end + def methods_coverage_percent + coverage_statistics[:method]&.percent + end + private # no_cov_chunks is zero indexed to work directly with the array holding the lines diff --git a/spec/file_list_spec.rb b/spec/file_list_spec.rb index 03325cbb..10033216 100644 --- a/spec/file_list_spec.rb +++ b/spec/file_list_spec.rb @@ -7,16 +7,18 @@ original_result = { source_fixture("sample.rb") => { lines: [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], - branches: {} - # TODO: add method cov + branches: {}, + methods: {} }, source_fixture("app/models/user.rb") => { lines: [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil], - branches: {} + branches: {}, + methods: {} }, source_fixture("app/controllers/sample_controller.rb") => { lines: [nil, 2, 2, 0, nil, nil, 0, nil, nil, nil], - branches: {} + branches: {}, + methods: {} } } SimpleCov::Result.new(original_result).files diff --git a/spec/result_spec.rb b/spec/result_spec.rb index 6b540709..e46416de 100644 --- a/spec/result_spec.rb +++ b/spec/result_spec.rb @@ -206,13 +206,58 @@ end end + describe "#to_hash" do + subject { SimpleCov::Result.new(original_result) } + + let(:original_result) do + { + source_fixture("sample.rb") => { + lines: [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], + branches: { + [:unless, 0, 8, 4, 8, 90] => { + [:else, 1, 8, 4, 8, 90] => 0, + [:then, 2, 8, 4, 8, 35] => 1 + } + }, + methods: { + ["# 2 + } + } + } + end + + it "dumps all coverage types properly" do + expect(subject.to_hash).to match( + "RSpec" => { + "coverage" => { + source_fixture("sample.rb") => { + lines: [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], + branches: [ + [ + [:unless, 0, 8, 4, 8, 90], [ + [[:else, 1, 8, 4, 8, 90], 0], + [[:then, 2, 8, 4, 8, 35], 1] + ] + ] + ], + methods: [ + [["# be_a(Integer), + } + ) + end + end + describe ".from_hash" do let(:created_at) { Time.now.to_i } let(:input) do { "rspec" => { - "coverage" => original_result, + "coverage" => dumped_result, "timestamp" => created_at } } @@ -227,46 +272,14 @@ } end - context "multiple commands" do - let(:other_result) do - { - source_fixture("sample.rb") => {lines: [nil, 1, 1, 1, nil, nil, 0, 0, nil, nil]} - } - end - - let(:input) do - { - "rspec" => { - "coverage" => original_result, - "timestamp" => created_at - }, - "cucumber" => { - "coverage" => other_result, - "timestamp" => created_at - } - } - end - - it "can consume multiple commands" do - result = described_class.from_hash(input) - - expect(result.size).to eq 2 - sorted = result.sort_by(&:command_name) - expect(sorted.map(&:command_name)).to eq %w[cucumber rspec] - expect(sorted.map(&:created_at).map(&:to_i)).to eq [created_at, created_at] - expect(sorted.map(&:original_result)).to eq [other_result, original_result] - end - end - context "branch and method coverage present" do - let(:original_result) do + let(:dumped_result) do { source_fixture("sample.rb") => { "lines" => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], "branches" => [ [ - ["unless", 0, 8, 4, 8, 90], - [ + ["unless", 0, 8, 4, 8, 90], [ [["else", 1, 8, 4, 8, 90], 0], [["then", 2, 8, 4, 8, 35], 1] ] @@ -296,7 +309,7 @@ end context "old style line coverage format" do - let(:original_result) do + let(:dumped_result) do { source_fixture("sample.rb") => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil] } end @@ -313,7 +326,7 @@ end context "old style branch coverage format" do - let(:original_result) do + let(:dumped_result) do { source_fixture("sample.rb") => { "branches" => { @@ -337,6 +350,37 @@ ) end end + + context "multiple commands" do + let(:other_result) do + { + source_fixture("sample.rb") => {lines: [nil, 1, 1, 1, nil, nil, 0, 0, nil, nil]} + } + end + + let(:input) do + { + "rspec" => { + "coverage" => original_result, + "timestamp" => created_at + }, + "cucumber" => { + "coverage" => other_result, + "timestamp" => created_at + } + } + end + + it "can consume multiple commands" do + result = described_class.from_hash(input) + + expect(result.size).to eq 2 + sorted = result.sort_by(&:command_name) + expect(sorted.map(&:command_name)).to eq %w[cucumber rspec] + expect(sorted.map(&:created_at).map(&:to_i)).to eq [created_at, created_at] + expect(sorted.map(&:original_result)).to eq [other_result, original_result] + end + end end end diff --git a/spec/simplecov_spec.rb b/spec/simplecov_spec.rb index 4306b4de..409f5371 100644 --- a/spec/simplecov_spec.rb +++ b/spec/simplecov_spec.rb @@ -172,7 +172,6 @@ end end - # TODO: add method cov context "branch coverage" do before do allow(SimpleCov).to receive(:minimum_coverage).and_return(branch: 90) diff --git a/spec/source_file/branch_spec.rb b/spec/source_file/branch_spec.rb index 99016c7e..048cc12b 100644 --- a/spec/source_file/branch_spec.rb +++ b/spec/source_file/branch_spec.rb @@ -2,7 +2,6 @@ require "helper" -# TODO: add method cov describe SimpleCov::SourceFile::Branch do let(:if_branch) do described_class.new(start_line: 1, end_line: 3, coverage: 0, inline: false, type: :then) diff --git a/spec/source_file/method_spec.rb b/spec/source_file/method_spec.rb new file mode 100644 index 00000000..a8c4d8a1 --- /dev/null +++ b/spec/source_file/method_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require "helper" + +describe SimpleCov::SourceFile::Method do + # TODO[@tycooon]: add specs +end diff --git a/spec/source_file_spec.rb b/spec/source_file_spec.rb index 6ae17ac5..599ccee0 100644 --- a/spec/source_file_spec.rb +++ b/spec/source_file_spec.rb @@ -69,7 +69,7 @@ end end - # TODO: add method cov + # TODO[@tycooon]: add method cov describe "branch coverage" do it "has total branches count 0" do expect(subject.total_branches.size).to eq(0) diff --git a/spec/useless_results_remover_spec.rb b/spec/useless_results_remover_spec.rb index f4b107cd..b24e96ed 100644 --- a/spec/useless_results_remover_spec.rb +++ b/spec/useless_results_remover_spec.rb @@ -10,12 +10,13 @@ { gem_file_path => { lines: [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], - branches: {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 47, [:else, 5, 8, 6, 8, 36] => 24}} - # TODO: add method cov? + branches: {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 47, [:else, 5, 8, 6, 8, 36] => 24}}, + methods: {} }, source_path => { lines: [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil], - branches: {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 47, [:else, 5, 8, 6, 8, 36] => 24}} + branches: {[:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 47, [:else, 5, 8, 6, 8, 36] => 24}}, + methods: {} } } end From 66e6e0be0705b1ab7373e06c9518bc336f9ce13c Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Tue, 22 Sep 2020 13:55:25 +0300 Subject: [PATCH 11/33] revert simplecov-html version --- Gemfile | 13 ++++++++----- Gemfile.lock | 7 +------ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Gemfile b/Gemfile index 49d8952f..95a2357f 100644 --- a/Gemfile +++ b/Gemfile @@ -2,11 +2,14 @@ source "https://rubygems.org" -# Uncomment this to use local copy of simplecov-html in development when checked out -gem "simplecov-html", path: File.dirname(__FILE__) + "/../simplecov-html" - -# Uncomment this to use development version of html formatter from github -# gem "simplecov-html", github: "simplecov-ruby/simplecov-html" +case ENV["SIMPLECOV_HTML_MODE"] +when "local" + # Use local copy of simplecov-html in development when checked out + gem "simplecov-html", path: File.dirname(__FILE__) + "/../simplecov-html" +when "github" + # Use development version of html formatter from github + gem "simplecov-html", github: "simplecov-ruby/simplecov-html" +end group :development do gem "apparition", "~> 0.6.0" diff --git a/Gemfile.lock b/Gemfile.lock index 226539d3..dc1772d6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,11 +5,6 @@ PATH docile (~> 1.1) simplecov-html (~> 0.11) -PATH - remote: ../simplecov-html - specs: - simplecov-html (0.12.2) - GEM remote: https://rubygems.org/ specs: @@ -141,6 +136,7 @@ GEM rubocop-ast (0.3.0) parser (>= 2.7.1.4) ruby-progressbar (1.10.1) + simplecov-html (0.12.2) spoon (0.0.6) ffi sys-uname (1.2.1) @@ -178,7 +174,6 @@ DEPENDENCIES rspec (~> 3.2) rubocop simplecov! - simplecov-html! test-unit BUNDLED WITH From d79cb80843cf01c21efc4962d81f3d5bc26f7a22 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Tue, 22 Sep 2020 14:06:53 +0300 Subject: [PATCH 12/33] fix rubocop issues --- Gemfile | 4 +++- spec/result_spec.rb | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 95a2357f..680c54ae 100644 --- a/Gemfile +++ b/Gemfile @@ -2,14 +2,16 @@ source "https://rubygems.org" +# rubocop:disable Bundler/DuplicatedGem case ENV["SIMPLECOV_HTML_MODE"] when "local" # Use local copy of simplecov-html in development when checked out - gem "simplecov-html", path: File.dirname(__FILE__) + "/../simplecov-html" + gem "simplecov-html", path: "#{File.dirname(__FILE__)}/../simplecov-html" when "github" # Use development version of html formatter from github gem "simplecov-html", github: "simplecov-ruby/simplecov-html" end +# rubocop:enable Bundler/DuplicatedGem group :development do gem "apparition", "~> 0.6.0" diff --git a/spec/result_spec.rb b/spec/result_spec.rb index e46416de..195babf1 100644 --- a/spec/result_spec.rb +++ b/spec/result_spec.rb @@ -245,7 +245,7 @@ ] } }, - "timestamp" => be_a(Integer), + "timestamp" => be_a(Integer) } ) end @@ -310,7 +310,7 @@ context "old style line coverage format" do let(:dumped_result) do - { source_fixture("sample.rb") => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil] } + {source_fixture("sample.rb") => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil]} end it "parses that properly" do @@ -320,7 +320,7 @@ expect(result.first.original_result.size).to eq(1) expect(result.first.original_result.values.last).to eq( - lines: [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil], + lines: [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil] ) end end From 4904192d753bf5a2a95768a949b927920dce4986 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Tue, 22 Sep 2020 14:18:24 +0300 Subject: [PATCH 13/33] fix flacky specs --- spec/command_guesser_spec.rb | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/spec/command_guesser_spec.rb b/spec/command_guesser_spec.rb index 9817f3f2..4fbb1e0e 100644 --- a/spec/command_guesser_spec.rb +++ b/spec/command_guesser_spec.rb @@ -5,44 +5,44 @@ describe SimpleCov::CommandGuesser do subject { SimpleCov::CommandGuesser } it 'correctly guesses "Unit Tests" for unit tests' do - subject.original_run_command = "/some/path/test/units/foo_bar_test.rb" + allow(subject).to receive(:original_run_command) { "/some/path/test/units/foo_bar_test.rb" } expect(subject.guess).to eq("Unit Tests") - subject.original_run_command = "test/units/foo.rb" + allow(subject).to receive(:original_run_command) { "test/units/foo.rb" } expect(subject.guess).to eq("Unit Tests") - subject.original_run_command = "test/foo.rb" + allow(subject).to receive(:original_run_command) { "test/foo.rb" } expect(subject.guess).to eq("Unit Tests") - subject.original_run_command = "test/{models,helpers,unit}/**/*_test.rb" + allow(subject).to receive(:original_run_command) { "test/{models,helpers,unit}/**/*_test.rb" } expect(subject.guess).to eq("Unit Tests") end it 'correctly guesses "Functional Tests" for functional tests' do - subject.original_run_command = "/some/path/test/functional/foo_bar_controller_test.rb" + allow(subject).to receive(:original_run_command) { "/some/path/test/functional/foo_bar_controller_test.rb" } expect(subject.guess).to eq("Functional Tests") - subject.original_run_command = "test/{controllers,mailers,functional}/**/*_test.rb" + allow(subject).to receive(:original_run_command) { "test/{controllers,mailers,functional}/**/*_test.rb" } expect(subject.guess).to eq("Functional Tests") end it 'correctly guesses "Integration Tests" for integration tests' do - subject.original_run_command = "/some/path/test/integration/foo_bar_controller_test.rb" + allow(subject).to receive(:original_run_command) { "/some/path/test/integration/foo_bar_controller_test.rb" } expect(subject.guess).to eq("Integration Tests") - subject.original_run_command = "test/integration/**/*_test.rb" + allow(subject).to receive(:original_run_command) { "test/integration/**/*_test.rb" } expect(subject.guess).to eq("Integration Tests") end it 'correctly guesses "Cucumber Features" for cucumber features' do - subject.original_run_command = "features" + allow(subject).to receive(:original_run_command) { "features" } expect(subject.guess).to eq("Cucumber Features") - subject.original_run_command = "cucumber" + allow(subject).to receive(:original_run_command) { "cucumber" } expect(subject.guess).to eq("Cucumber Features") end it 'correctly guesses "RSpec" for RSpec' do - subject.original_run_command = "/some/path/spec/foo.rb" + allow(subject).to receive(:original_run_command) { "/some/path/spec/foo.rb" } expect(subject.guess).to eq("RSpec") end it "defaults to RSpec because RSpec constant is defined" do - subject.original_run_command = "some_arbitrary_command with arguments" + allow(subject).to receive(:original_run_command) { "some_arbitrary_command with arguments" } expect(subject.guess).to eq("RSpec") end end From 3eff8b79337355455b0eebe543c60d0947788c09 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Fri, 23 Apr 2021 17:24:57 +0300 Subject: [PATCH 14/33] minor refactor --- .gitignore | 1 + lib/simplecov/combine/files_combiner.rb | 13 ++++++++----- lib/simplecov/configuration.rb | 12 ++++-------- spec/combine/results_combiner_spec.rb | 1 + 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 91d75687..903961cf 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ tmp ## PROJECT::SPECIFIC .yardoc +.ruby-version spec/fixtures/coverage spec/fixtures/frameworks/coverage test_projects/**/coverage diff --git a/lib/simplecov/combine/files_combiner.rb b/lib/simplecov/combine/files_combiner.rb index f4a5725f..c19b79d2 100644 --- a/lib/simplecov/combine/files_combiner.rb +++ b/lib/simplecov/combine/files_combiner.rb @@ -14,13 +14,16 @@ module FilesCombiner # # @return [Hash] # - def combine(coverage_a, coverage_b) + def combine(cov_a, cov_b) combination = {} - combination[:lines] = Combine.combine(LinesCombiner, coverage_a[:lines], coverage_b[:lines]) + combination[:lines] = Combine.combine(LinesCombiner, cov_a[:lines], cov_b[:lines]) - if SimpleCov.branch_coverage? - combination[:branches] = Combine.combine(BranchesCombiner, coverage_a[:branches], coverage_b[:branches]) - combination[:methods] = Combine.combine(MethodsCombiner, coverage_a[:methods], coverage_b[:methods]) + if SimpleCov.branch_coverage? # rubocop:disable Style/IfUnlessModifier + combination[:branches] = Combine.combine(BranchesCombiner, cov_a[:branches], cov_b[:branches]) + end + + if SimpleCov.method_coverage? # rubocop:disable Style/IfUnlessModifier + combination[:methods] = Combine.combine(MethodsCombiner, cov_a[:methods], cov_b[:methods]) end combination diff --git a/lib/simplecov/configuration.rb b/lib/simplecov/configuration.rb index c6ed242f..719ed22d 100644 --- a/lib/simplecov/configuration.rb +++ b/lib/simplecov/configuration.rb @@ -409,8 +409,7 @@ def method_coverage? end def coverage_start_arguments_supported? - # safe to cache as within one process this value should never - # change + # safe to cache as within one process this value should never change return @coverage_start_arguments_supported if defined?(@coverage_start_arguments_supported) @coverage_start_arguments_supported = begin @@ -426,19 +425,16 @@ def coverage_start_arguments_supported? def raise_if_criterion_disabled(criterion) raise_if_criterion_unsupported(criterion) - # rubocop:disable Style/IfUnlessModifier - unless coverage_criterion_enabled?(criterion) + + unless coverage_criterion_enabled?(criterion) # rubocop:disable Style/IfUnlessModifier raise "Coverage criterion #{criterion} is disabled! Please enable it first through enable_coverage #{criterion} (if supported)" end - # rubocop:enable Style/IfUnlessModifier end def raise_if_criterion_unsupported(criterion) - # rubocop:disable Style/IfUnlessModifier - unless SUPPORTED_COVERAGE_CRITERIA.member?(criterion) + unless SUPPORTED_COVERAGE_CRITERIA.member?(criterion) # rubocop:disable Style/IfUnlessModifier raise "Unsupported coverage criterion #{criterion}, supported values are #{SUPPORTED_COVERAGE_CRITERIA}" end - # rubocop:enable Style/IfUnlessModifier end def minimum_possible_coverage_exceeded(coverage_option) diff --git a/spec/combine/results_combiner_spec.rb b/spec/combine/results_combiner_spec.rb index abc605cc..2e4e2759 100644 --- a/spec/combine/results_combiner_spec.rb +++ b/spec/combine/results_combiner_spec.rb @@ -49,6 +49,7 @@ before do SimpleCov.enable_coverage :branch + SimpleCov.enable_coverage :method end context "a merge" do From 9fafd3cb49e763dad2d6d3e24fb7b5ce42ce502b Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Fri, 23 Apr 2021 19:13:12 +0300 Subject: [PATCH 15/33] fix results collation --- Gemfile | 3 - Gemfile.lock | 2 +- features/method_coverage.feature | 37 ----------- lib/simplecov/combine/files_combiner.rb | 1 + lib/simplecov/result.rb | 12 ++-- lib/simplecov/result_merger.rb | 85 ++++++------------------- spec/result_merger_spec.rb | 2 +- spec/simplecov_spec.rb | 7 +- 8 files changed, 30 insertions(+), 119 deletions(-) delete mode 100644 features/method_coverage.feature diff --git a/Gemfile b/Gemfile index 397e9269..bf062f2f 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,6 @@ source "https://rubygems.org" -# rubocop:disable Bundler/DuplicatedGem case ENV["SIMPLECOV_HTML_MODE"] when "local" # Use local copy of simplecov-html in development when checked out @@ -11,8 +10,6 @@ when "github" # Use development version of html formatter from github gem "simplecov-html", github: "simplecov-ruby/simplecov-html" end -# rubocop:enable Bundler/DuplicatedGem - group :development do gem "apparition", "~> 0.6.0" gem "aruba", "~> 1.0" diff --git a/Gemfile.lock b/Gemfile.lock index 359c9964..b1acad64 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -179,4 +179,4 @@ DEPENDENCIES webrick BUNDLED WITH - 2.2.8 + 2.2.16 diff --git a/features/method_coverage.feature b/features/method_coverage.feature deleted file mode 100644 index 9d10b4a3..00000000 --- a/features/method_coverage.feature +++ /dev/null @@ -1,37 +0,0 @@ -@rspec @method_coverage -Feature: - - Simply executing method coverage gives ok results. - - Background: - Given I'm working on the project "faked_project" - - Scenario: - Given SimpleCov for RSpec is configured with: - """ - require 'simplecov' - SimpleCov.start do - enable_coverage :method - end - """ - When I open the coverage report generated with `bundle exec rspec spec` - Then I should see the groups: - | name | coverage | files | - | All Files | 91.8% | 7 | - # And I should see a line coverage summary of 56/61 - # And I should see a branch coverage summary of 2/4 - # And I should see the source files: - # | name | coverage | branch coverage | - # | lib/faked_project.rb | 100.00 % | 100.00 % | - # | lib/faked_project/some_class.rb | 80.00 % | 50.00 % | - # | lib/faked_project/framework_specific.rb | 75.00 % | 100.00 % | - # | lib/faked_project/meta_magic.rb | 100.00 % | 100.00 % | - # | spec/forking_spec.rb | 100.00 % | 50.00 % | - # | spec/meta_magic_spec.rb | 100.00 % | 100.00 % | - # | spec/some_class_spec.rb | 100.00 % | 100.00 % | - - # When I open the detailed view for "lib/faked_project/some_class.rb" - # Then I should see a line coverage summary of 12/15 for the file - # And I should see a branch coverage summary of 1/2 for the file - # And I should see coverage branch data like "then: 1" - # And I should see coverage branch data like "else: 0" diff --git a/lib/simplecov/combine/files_combiner.rb b/lib/simplecov/combine/files_combiner.rb index c19b79d2..390bd0d6 100644 --- a/lib/simplecov/combine/files_combiner.rb +++ b/lib/simplecov/combine/files_combiner.rb @@ -16,6 +16,7 @@ module FilesCombiner # def combine(cov_a, cov_b) combination = {} + combination[:lines] = Combine.combine(LinesCombiner, cov_a[:lines], cov_b[:lines]) if SimpleCov.branch_coverage? # rubocop:disable Style/IfUnlessModifier diff --git a/lib/simplecov/result.rb b/lib/simplecov/result.rb index 5b308c5b..89e7cf83 100644 --- a/lib/simplecov/result.rb +++ b/lib/simplecov/result.rb @@ -73,18 +73,14 @@ def to_hash # Loads a SimpleCov::Result#to_hash dump def self.from_hash(hash) SimpleCov::ResultSerialization.deserialize(hash) - # hash.map do |command_name, data| - # new(data.fetch("coverage"), command_name: command_name, created_at: Time.at(data["timestamp"])) - # end end private - # TODO[@tycooon]: remove? - # def coverage - # keys = original_result.keys & filenames - # Hash[keys.zip(original_result.values_at(*keys))] - # end + def coverage + keys = original_result.keys & filenames + Hash[keys.zip(original_result.values_at(*keys))] + end # Applies all configured SimpleCov filters on this result's source files def filter! diff --git a/lib/simplecov/result_merger.rb b/lib/simplecov/result_merger.rb index a6b2e92e..15155eb6 100644 --- a/lib/simplecov/result_merger.rb +++ b/lib/simplecov/result_merger.rb @@ -31,20 +31,14 @@ def merge_results(*file_paths, ignore_timeout: false) # In big CI setups you might deal with 100s of CI jobs and each one producing Megabytes # of data. Reading them all in easily produces Gigabytes of memory consumption which # we want to avoid. - # - # For similar reasons a SimpleCov::Result is only created in the end as that'd create - # even more data especially when it also reads in all source files. - initial_memo = valid_results(file_paths.shift, ignore_timeout: ignore_timeout) - - command_names, coverage = file_paths.reduce(initial_memo) do |memo, file_path| - merge_coverage(memo, valid_results(file_path, ignore_timeout: ignore_timeout)) - end - create_result(command_names, coverage) + results = file_paths.map { |path| valid_results(path, ignore_timeout: ignore_timeout) } + merge_coverage(results) end def valid_results(file_path, ignore_timeout: false) - results = parse_file(file_path) + raw_results = parse_file(file_path) + results = Result.from_hash(raw_results) merge_valid_results(results, ignore_timeout: ignore_timeout) end @@ -72,42 +66,25 @@ def parse_json(content) end def merge_valid_results(results, ignore_timeout: false) - results = results.select { |_command_name, data| within_merge_timeout?(data) } unless ignore_timeout - - command_plus_coverage = results.map do |command_name, data| - [[command_name], adapt_result(data.fetch("coverage"))] - end - - # one file itself _might_ include multiple test runs - merge_coverage(*command_plus_coverage) + results = results.select { |x| within_merge_timeout?(x) } unless ignore_timeout + merge_coverage(results) end - def within_merge_timeout?(data) - time_since_result_creation(data) < SimpleCov.merge_timeout + def within_merge_timeout?(result) + Time.now - result.created_at < SimpleCov.merge_timeout end - def time_since_result_creation(data) - Time.now - Time.at(data.fetch("timestamp")) - end - - def create_result(command_names, coverage) - return nil unless coverage - - command_name = command_names.reject(&:empty?).sort.join(", ") - SimpleCov::Result.new(coverage, command_name: command_name) - end + def merge_coverage(results) + results = results.compact - def merge_coverage(*results) - return [[""], nil] if results.empty? + return nil if results.size.zero? return results.first if results.size == 1 - results.reduce do |(memo_command, memo_coverage), (command, coverage)| - # timestamp is dropped here, which is intentional (we merge it, it gets a new time stamp as of now) - merged_coverage = Combine.combine(Combine::ResultsCombiner, memo_coverage, coverage) - merged_command = memo_command + command - - [merged_command, merged_coverage] - end + parsed_results = results.map(&:original_result) + combined_result = SimpleCov::Combine::ResultsCombiner.combine(*parsed_results) + result = SimpleCov::Result.new(combined_result) + result.command_name = results.map(&:command_name).reject(&:empty?).sort.join(", ") + result end # @@ -118,9 +95,8 @@ def merged_result # conceptually this is just doing `merge_results(resultset_path)` # it's more involved to make syre `synchronize_resultset` is only used around reading resultset_hash = read_resultset - command_names, coverage = merge_valid_results(resultset_hash) - - create_result(command_names, coverage) + results = Result.from_hash(resultset_hash) + merge_valid_results(results) end def read_resultset @@ -164,31 +140,6 @@ def synchronize_resultset @resultset_locked = false end end - - # We changed the format of the raw result data in simplecov, as people are likely - # to have "old" resultsets lying around (but not too old so that they're still - # considered we can adapt them). - # See https://github.com/simplecov-ruby/simplecov/pull/824#issuecomment-576049747 - def adapt_result(result) - if pre_simplecov_0_18_result?(result) - adapt_pre_simplecov_0_18_result(result) - else - result - end - end - - # pre 0.18 coverage data pointed from file directly to an array of line coverage - def pre_simplecov_0_18_result?(result) - _key, data = result.first - - data.is_a?(Array) - end - - def adapt_pre_simplecov_0_18_result(result) - result.transform_values do |line_coverage_data| - {"lines" => line_coverage_data} - end - end end end end diff --git a/spec/result_merger_spec.rb b/spec/result_merger_spec.rb index 4518d5c4..ee2320cb 100644 --- a/spec/result_merger_spec.rb +++ b/spec/result_merger_spec.rb @@ -123,7 +123,7 @@ it "has the result stored" do SimpleCov::ResultMerger.merge_and_store(resultset1_path, resultset2_path) - expect_resultset_1_and_2_merged(SimpleCov::ResultMerger.read_resultset) + expect_resultset_1_and_2_merged(SimpleCov::ResultMerger.merged_result.to_hash) end end diff --git a/spec/simplecov_spec.rb b/spec/simplecov_spec.rb index 63e6dd31..62dfa829 100644 --- a/spec/simplecov_spec.rb +++ b/spec/simplecov_spec.rb @@ -207,7 +207,7 @@ "result1, result2" => { "coverage" => { source_fixture("sample.rb") => { - "lines" => [1, 1, 2, 2, nil, nil, 2, 2, nil, nil] + lines: [1, 1, 2, 2, nil, nil, 2, 2, nil, nil] } } } @@ -215,7 +215,10 @@ end let(:collated) do - JSON.parse(File.read(resultset_path)).transform_values { |v| v.reject { |k| k == "timestamp" } } + JSON.parse(File.read(resultset_path)).transform_values do |data| + data["coverage"].values.first.transform_keys!(&:to_sym) + data.reject { |k| k == "timestamp" } + end end context "when no files to be merged" do From 64206882943ad3083689c40590278baaddf29d2a Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Fri, 23 Apr 2021 19:44:56 +0300 Subject: [PATCH 16/33] update test app gemfile --- Gemfile | 1 + test_projects/rails/rspec_rails/Gemfile.lock | 157 +++++++++---------- 2 files changed, 78 insertions(+), 80 deletions(-) diff --git a/Gemfile b/Gemfile index bf062f2f..236df0a8 100644 --- a/Gemfile +++ b/Gemfile @@ -10,6 +10,7 @@ when "github" # Use development version of html formatter from github gem "simplecov-html", github: "simplecov-ruby/simplecov-html" end + group :development do gem "apparition", "~> 0.6.0" gem "aruba", "~> 1.0" diff --git a/test_projects/rails/rspec_rails/Gemfile.lock b/test_projects/rails/rspec_rails/Gemfile.lock index b586e8ef..36274504 100644 --- a/test_projects/rails/rspec_rails/Gemfile.lock +++ b/test_projects/rails/rspec_rails/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: ../../.. specs: - simplecov (0.20.0) + simplecov (0.21.2) docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) @@ -9,65 +9,60 @@ PATH GEM remote: https://rubygems.org/ specs: - actioncable (6.1.0) - actionpack (= 6.1.0) - activesupport (= 6.1.0) + actioncable (6.1.3.1) + actionpack (= 6.1.3.1) + activesupport (= 6.1.3.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.0) - actionpack (= 6.1.0) - activejob (= 6.1.0) - activerecord (= 6.1.0) - activestorage (= 6.1.0) - activesupport (= 6.1.0) + actionmailbox (6.1.3.1) + actionpack (= 6.1.3.1) + activejob (= 6.1.3.1) + activerecord (= 6.1.3.1) + activestorage (= 6.1.3.1) + activesupport (= 6.1.3.1) mail (>= 2.7.1) - actionmailer (6.1.0) - actionpack (= 6.1.0) - actionview (= 6.1.0) - activejob (= 6.1.0) - activesupport (= 6.1.0) + actionmailer (6.1.3.1) + actionpack (= 6.1.3.1) + actionview (= 6.1.3.1) + activejob (= 6.1.3.1) + activesupport (= 6.1.3.1) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.1.0) - actionview (= 6.1.0) - activesupport (= 6.1.0) + actionpack (6.1.3.1) + actionview (= 6.1.3.1) + activesupport (= 6.1.3.1) rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.0) - actionpack (= 6.1.0) - activerecord (= 6.1.0) - activestorage (= 6.1.0) - activesupport (= 6.1.0) + actiontext (6.1.3.1) + actionpack (= 6.1.3.1) + activerecord (= 6.1.3.1) + activestorage (= 6.1.3.1) + activesupport (= 6.1.3.1) nokogiri (>= 1.8.5) - actionview (6.1.0) - activesupport (= 6.1.0) + actionview (6.1.3.1) + activesupport (= 6.1.3.1) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.1.0) - activesupport (= 6.1.0) + activejob (6.1.3.1) + activesupport (= 6.1.3.1) globalid (>= 0.3.6) - activemodel (6.1.0) - activesupport (= 6.1.0) - activerecord (6.1.0) - activemodel (= 6.1.0) - activesupport (= 6.1.0) - activerecord-jdbc-adapter (61.0-java) - activerecord (~> 6.1.0) - activerecord-jdbcsqlite3-adapter (61.0-java) - activerecord-jdbc-adapter (= 61.0) - jdbc-sqlite3 (~> 3.8, < 3.30) - activestorage (6.1.0) - actionpack (= 6.1.0) - activejob (= 6.1.0) - activerecord (= 6.1.0) - activesupport (= 6.1.0) - marcel (~> 0.3.1) - mimemagic (~> 0.3.2) - activesupport (6.1.0) + activemodel (6.1.3.1) + activesupport (= 6.1.3.1) + activerecord (6.1.3.1) + activemodel (= 6.1.3.1) + activesupport (= 6.1.3.1) + activestorage (6.1.3.1) + actionpack (= 6.1.3.1) + activejob (= 6.1.3.1) + activerecord (= 6.1.3.1) + activesupport (= 6.1.3.1) + marcel (~> 1.0.0) + mini_mime (~> 1.0.2) + activesupport (6.1.3.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -90,68 +85,69 @@ GEM rack-test (>= 0.6.3) regexp_parser (~> 1.5) xpath (~> 3.2) - concurrent-ruby (1.1.7) + concurrent-ruby (1.1.8) crass (1.0.6) diff-lcs (1.4.4) - docile (1.3.3) + docile (1.3.5) erubi (1.10.0) globalid (0.4.2) activesupport (>= 4.2.0) - i18n (1.8.5) + i18n (1.8.10) concurrent-ruby (~> 1.0) jbuilder (2.10.1) activesupport (>= 5.0.0) - jdbc-sqlite3 (3.28.0) - loofah (2.8.0) + loofah (2.9.1) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) - marcel (0.3.3) - mimemagic (~> 0.3.2) + marcel (1.0.1) method_source (1.0.0) - mimemagic (0.3.5) - mini_mime (1.0.2) - mini_portile2 (2.4.0) - minitest (5.14.2) + mini_mime (1.0.3) + mini_portile2 (2.5.0) + minitest (5.14.4) msgpack (1.3.3) msgpack (1.3.3-java) - nio4r (2.5.4) - nio4r (2.5.4-java) - nokogiri (1.10.10) - mini_portile2 (~> 2.4.0) - nokogiri (1.10.10-java) + nio4r (2.5.7) + nio4r (2.5.7-java) + nokogiri (1.11.3) + mini_portile2 (~> 2.5.0) + racc (~> 1.4) + nokogiri (1.11.3-java) + racc (~> 1.4) public_suffix (4.0.6) puma (5.1.1) nio4r (~> 2.0) puma (5.1.1-java) nio4r (~> 2.0) + racc (1.5.2) + racc (1.5.2-java) rack (2.2.3) rack-test (1.1.0) rack (>= 1.0, < 3) - rails (6.1.0) - actioncable (= 6.1.0) - actionmailbox (= 6.1.0) - actionmailer (= 6.1.0) - actionpack (= 6.1.0) - actiontext (= 6.1.0) - actionview (= 6.1.0) - activejob (= 6.1.0) - activemodel (= 6.1.0) - activerecord (= 6.1.0) - activestorage (= 6.1.0) - activesupport (= 6.1.0) + rails (6.1.3.1) + actioncable (= 6.1.3.1) + actionmailbox (= 6.1.3.1) + actionmailer (= 6.1.3.1) + actionpack (= 6.1.3.1) + actiontext (= 6.1.3.1) + actionview (= 6.1.3.1) + activejob (= 6.1.3.1) + activemodel (= 6.1.3.1) + activerecord (= 6.1.3.1) + activestorage (= 6.1.3.1) + activesupport (= 6.1.3.1) bundler (>= 1.15.0) - railties (= 6.1.0) + railties (= 6.1.3.1) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) rails-html-sanitizer (1.3.0) loofah (~> 2.3) - railties (6.1.0) - actionpack (= 6.1.0) - activesupport (= 6.1.0) + railties (6.1.3.1) + actionpack (= 6.1.3.1) + activesupport (= 6.1.3.1) method_source rake (>= 0.8.7) thor (~> 1.0) @@ -184,7 +180,8 @@ GEM actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) - thor (1.0.1) + sqlite3 (1.4.2) + thor (1.1.0) tzinfo (2.0.4) concurrent-ruby (~> 1.0) tzinfo-data (1.2020.4) @@ -209,7 +206,6 @@ PLATFORMS universal-java-1.8 DEPENDENCIES - activerecord-jdbcsqlite3-adapter (~> 61.0) bootsnap (>= 1.4.4) byebug capybara (>= 3.26) @@ -219,8 +215,9 @@ DEPENDENCIES rspec-rails simplecov! spring + sqlite3 (~> 1.4) tzinfo-data web-console (>= 4.1.0) BUNDLED WITH - 2.2.2 + 2.2.16 From ddccb3c7e52f72447f3b8f003bb7a23c401be612 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Fri, 23 Apr 2021 20:29:08 +0300 Subject: [PATCH 17/33] add specs --- spec/fixtures/coverer.rb | 5 +- spec/fixtures/methods.rb | 18 +++++ spec/source_file/method_spec.rb | 45 ++++++++++++- spec/source_file_spec.rb | 112 ++++++++++++++++++++++++++++---- 4 files changed, 163 insertions(+), 17 deletions(-) create mode 100644 spec/fixtures/methods.rb diff --git a/spec/fixtures/coverer.rb b/spec/fixtures/coverer.rb index b6d9e53b..381bdeb0 100644 --- a/spec/fixtures/coverer.rb +++ b/spec/fixtures/coverer.rb @@ -2,8 +2,5 @@ require "coverage" Coverage.start(:all) -require_relative "uneven_nocovs" - -UnevenNocov.call(42) - +require_relative "methods" p Coverage.result diff --git a/spec/fixtures/methods.rb b/spec/fixtures/methods.rb new file mode 100644 index 00000000..de753ef3 --- /dev/null +++ b/spec/fixtures/methods.rb @@ -0,0 +1,18 @@ +class A + def method1 + puts "hello from method1" + method2 + end + +private + + def method2 + puts "hello from method2" + end + + def method3 + puts "hello from method3" + end +end + +A.new.method1 diff --git a/spec/source_file/method_spec.rb b/spec/source_file/method_spec.rb index a8c4d8a1..bebee569 100644 --- a/spec/source_file/method_spec.rb +++ b/spec/source_file/method_spec.rb @@ -3,5 +3,48 @@ require "helper" describe SimpleCov::SourceFile::Method do - # TODO[@tycooon]: add specs + subject { described_class.new(source_file, info, coverage) } + + let(:source_file) do + SimpleCov::SourceFile.new(source_fixture("methods.rb"), lines: {}) + end + + let(:info) { ["A", :method1, 2, 2, 5, 5] } + let(:coverage) { 1 } + + it "is covered" do + expect(subject.covered?).to eq(true) + end + + it "is not skipped" do + expect(subject.skipped?).to eq(false) + end + + it "is not missed" do + expect(subject.missed?).to eq(false) + end + + it "has 4 lines" do + expect(subject.lines.size).to eq(4) + end + + it "converts to string properly" do + expect(subject.to_s).to eq("A#method1") + end + + context "uncovered method" do + let(:coverage) { 0 } + + it "is not covered" do + expect(subject.covered?).to eq(false) + end + + it "is not skipped" do + expect(subject.skipped?).to eq(false) + end + + it "is missed" do + expect(subject.missed?).to eq(true) + end + end end diff --git a/spec/source_file_spec.rb b/spec/source_file_spec.rb index 599ccee0..1aa30561 100644 --- a/spec/source_file_spec.rb +++ b/spec/source_file_spec.rb @@ -69,7 +69,6 @@ end end - # TODO[@tycooon]: add method cov describe "branch coverage" do it "has total branches count 0" do expect(subject.total_branches.size).to eq(0) @@ -91,23 +90,43 @@ expect(subject.branches_report).to eq({}) end end + + describe "method coverage" do + it "has total methods count 0" do + expect(subject.total_methods.size).to eq(0) + end + + it "has covered methods count 0" do + expect(subject.covered_methods.size).to eq(0) + end + + it "has missed methods count 0" do + expect(subject.missed_methods.size).to eq(0) + end + + it "is considered 100% methods covered" do + expect(subject.methods_coverage_percent).to eq(100.0) + end + end end context "file with branches" do - COVERAGE_FOR_BRANCHES_RB = { - lines: [1, 1, 1, nil, 1, nil, 1, 0, nil, 1, nil, nil, nil], - branches: { - [:if, 0, 3, 4, 3, 21] => - {[:then, 1, 3, 4, 3, 10] => 0, [:else, 2, 3, 4, 3, 21] => 1}, - [:if, 3, 5, 4, 5, 26] => - {[:then, 4, 5, 16, 5, 20] => 1, [:else, 5, 5, 23, 5, 26] => 0}, - [:if, 6, 7, 4, 11, 7] => - {[:then, 7, 8, 6, 8, 10] => 0, [:else, 8, 10, 6, 10, 9] => 1} + let(:coverage_for_branches_rb) do + { + lines: [1, 1, 1, nil, 1, nil, 1, 0, nil, 1, nil, nil, nil], + branches: { + [:if, 0, 3, 4, 3, 21] => + {[:then, 1, 3, 4, 3, 10] => 0, [:else, 2, 3, 4, 3, 21] => 1}, + [:if, 3, 5, 4, 5, 26] => + {[:then, 4, 5, 16, 5, 20] => 1, [:else, 5, 5, 23, 5, 26] => 0}, + [:if, 6, 7, 4, 11, 7] => + {[:then, 7, 8, 6, 8, 10] => 0, [:else, 8, 10, 6, 10, 9] => 1} + } } - }.freeze + end subject do - SimpleCov::SourceFile.new(source_fixture("branches.rb"), COVERAGE_FOR_BRANCHES_RB) + SimpleCov::SourceFile.new(source_fixture("branches.rb"), coverage_for_branches_rb) end describe "branch coverage" do @@ -164,6 +183,60 @@ end end + context "file with methods" do + let(:coverage_for_methods_rb) do + { + lines: [1, 1, 1, 1, nil, nil, 1, nil, 1, 1, nil, nil, 1, 0, nil, nil, nil, 1], + branches: {}, + methods: { + ["A", :method3, 13, 2, 15, 5] => 0, + ["A", :method2, 9, 2, 11, 5] => 1, + ["A", :method1, 2, 2, 5, 5] => 1 + } + } + end + + subject do + SimpleCov::SourceFile.new(source_fixture("methods.rb"), coverage_for_methods_rb) + end + + describe "method coverage" do + it "has total methods count 0" do + expect(subject.total_methods.size).to eq(3) + end + + it "has covered methods count 0" do + expect(subject.covered_methods.size).to eq(2) + end + + it "has missed methods count 0" do + expect(subject.missed_methods.size).to eq(1) + end + + it "is considered 66.(6)% methods covered" do + expect(subject.methods_coverage_percent).to eq(66.66666666666667) + end + end + + describe "line coverage" do + it "has line coverage" do + expect(subject.covered_percent).to eq 90.0 + end + + it "has 9 covered lines" do + expect(subject.covered_lines.size).to eq 9 + end + + it "has 1 missed line" do + expect(subject.missed_lines.size).to eq 1 + end + + it "has 10 relevant lines" do + expect(subject.relevant_lines).to eq 10 + end + end + end + context "simulating potential Ruby 1.9 defect -- see Issue #56" do subject do SimpleCov::SourceFile.new(source_fixture("sample.rb"), COVERAGE_FOR_SAMPLE_RB_WITH_MORE_LINES) @@ -234,6 +307,10 @@ it "has 100.0 branch coverage" do expect(subject.branches_coverage_percent).to eq(100.00) end + + it "has 100.0 method coverage" do + expect(subject.methods_coverage_percent).to eq(100.00) + end end context "a file where nothing is ever executed mixed with skipping #563" do @@ -327,6 +404,17 @@ expect(subject.covered_branches.size).to eq 0 end end + + describe "method coverage" do + it "has no methods" do + expect(subject.total_methods.size).to eq 0 + end + + it "does has neither covered nor missed methods" do + expect(subject.missed_methods.size).to eq 0 + expect(subject.covered_methods.size).to eq 0 + end + end end context "a file with more complex skipping" do From 15c03b27519b98b8070513bef88d37e7c1a93357 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Sat, 24 Apr 2021 13:51:20 +0300 Subject: [PATCH 18/33] optimize result merger --- lib/simplecov/result_merger.rb | 11 ++++++++--- lib/simplecov/result_serialization.rb | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/simplecov/result_merger.rb b/lib/simplecov/result_merger.rb index 15155eb6..78dbcc7c 100644 --- a/lib/simplecov/result_merger.rb +++ b/lib/simplecov/result_merger.rb @@ -32,11 +32,16 @@ def merge_results(*file_paths, ignore_timeout: false) # of data. Reading them all in easily produces Gigabytes of memory consumption which # we want to avoid. - results = file_paths.map { |path| valid_results(path, ignore_timeout: ignore_timeout) } - merge_coverage(results) + file_paths = file_paths.dup + initial_result = merge_file_results(file_paths.shift, ignore_timeout: ignore_timeout) + + file_paths.reduce(initial_result) do |memo, path| + file_result = merge_file_results(path, ignore_timeout: ignore_timeout) + merge_coverage([memo, file_result]) + end end - def valid_results(file_path, ignore_timeout: false) + def merge_file_results(file_path, ignore_timeout:) raw_results = parse_file(file_path) results = Result.from_hash(raw_results) merge_valid_results(results, ignore_timeout: ignore_timeout) diff --git a/lib/simplecov/result_serialization.rb b/lib/simplecov/result_serialization.rb index eeb4361e..2a5f6e71 100644 --- a/lib/simplecov/result_serialization.rb +++ b/lib/simplecov/result_serialization.rb @@ -24,7 +24,7 @@ def deserialize(hash) # rubocop:disable Metrics/MethodLength hash.map do |command_name, data| coverage = {} - data["coverage"].each do |file_name, file_data| + data.fetch("coverage").each do |file_name, file_data| parsed_file_data = {} file_data = {lines: file_data} if file_data.is_a?(Array) @@ -39,7 +39,7 @@ def deserialize(hash) # rubocop:disable Metrics/MethodLength result = SimpleCov::Result.new(coverage) result.command_name = command_name - result.created_at = Time.at(data["timestamp"]) + result.created_at = Time.at(data.fetch("timestamp")) result end end From 9a8b3246ade78691ed219c47c20a61276695d752 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Sat, 24 Apr 2021 14:24:11 +0300 Subject: [PATCH 19/33] add specs for method cov merging --- spec/result_merger_spec.rb | 67 ++++++++++++++++++++++++++++++++++++++ spec/source_file_spec.rb | 4 +-- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/spec/result_merger_spec.rb b/spec/result_merger_spec.rb index ee2320cb..21547ada 100644 --- a/spec/result_merger_spec.rb +++ b/spec/result_merger_spec.rb @@ -165,6 +165,73 @@ expect_resultset_1_and_2_merged(result_hash) end end + + describe "method coverage", if: SimpleCov.method_coverage_supported? do + before do + SimpleCov.enable_coverage :method + store_result(result3, path: resultset3_path) + end + + after do + SimpleCov.clear_coverage_criteria + end + + let(:resultset1) do + { + source_fixture("methods.rb") => { + methods: { + ["A", :method1, 2, 2, 5, 5] => 1, + ["A", :method2, 9, 2, 11, 5] => 0, + ["A", :method3, 13, 2, 15, 5] => 0 + } + } + } + end + + let(:resultset2) do + { + source_fixture("methods.rb") => { + methods: { + ["A", :method1, 2, 2, 5, 5] => 0, + ["A", :method2, 9, 2, 11, 5] => 1, + ["A", :method3, 13, 2, 15, 5] => 0 + } + } + } + end + + let(:resultset3) do + { + source_fixture("methods.rb") => { + methods: { + ["B", :method1, 2, 2, 5, 5] => 1, + ["B", :method2, 9, 2, 11, 5] => 0, + ["B", :method3, 13, 2, 15, 5] => 0 + } + } + } + end + + let(:result3) { SimpleCov::Result.new(resultset3, command_name: "result3") } + let(:resultset3_path) { "#{resultset_prefix}3.json" } + + it "correctly merges the 3 results" do + result = SimpleCov::ResultMerger.merge_and_store( + resultset1_path, resultset2_path, resultset3_path + ) + + merged_coverage = result.original_result.fetch(source_fixture("methods.rb")) + + expect(merged_coverage.fetch(:methods)).to eq( + ["A", :method1, 2, 2, 5, 5] => 1, + ["A", :method2, 9, 2, 11, 5] => 1, + ["A", :method3, 13, 2, 15, 5] => 0, + ["B", :method1, 2, 2, 5, 5] => 1, + ["B", :method2, 9, 2, 11, 5] => 0, + ["B", :method3, 13, 2, 15, 5] => 0 + ) + end + end end context "pre 0.18 result format" do diff --git a/spec/source_file_spec.rb b/spec/source_file_spec.rb index 1aa30561..43609c77 100644 --- a/spec/source_file_spec.rb +++ b/spec/source_file_spec.rb @@ -189,9 +189,9 @@ lines: [1, 1, 1, 1, nil, nil, 1, nil, 1, 1, nil, nil, 1, 0, nil, nil, nil, 1], branches: {}, methods: { - ["A", :method3, 13, 2, 15, 5] => 0, + ["A", :method1, 2, 2, 5, 5] => 1, ["A", :method2, 9, 2, 11, 5] => 1, - ["A", :method1, 2, 2, 5, 5] => 1 + ["A", :method3, 13, 2, 15, 5] => 0 } } end From dc754e45991c624a322e948fc754761093ecacfc Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Fri, 30 Apr 2021 18:58:20 +0300 Subject: [PATCH 20/33] add feature specs for method coverage --- Gemfile | 2 ++ Gemfile.lock | 15 +++++++++- features/method_coverage.feature | 39 +++++++++++++++++++++++++ features/step_definitions/html_steps.rb | 8 +++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 features/method_coverage.feature diff --git a/Gemfile b/Gemfile index 236df0a8..97673e29 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,8 @@ when "local" when "github" # Use development version of html formatter from github gem "simplecov-html", github: "simplecov-ruby/simplecov-html" +when "methods" + gem "simplecov-html", github: "umbrellio/simplecov-html", branch: "add-method-coverage-support" end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index b1acad64..e686a04b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,10 @@ +GIT + remote: https://github.com/umbrellio/simplecov-html.git + revision: fc9c7a1beaa75bad3a925d1296b94fcd0c96b126 + branch: add-method-coverage-support + specs: + simplecov-html (0.12.3) + PATH remote: . specs: @@ -101,6 +108,10 @@ GEM pry (0.13.1) coderay (~> 1.1) method_source (~> 1.0) + pry (0.13.1-java) + coderay (~> 1.1) + method_source (~> 1.0) + spoon (~> 0.0) public_suffix (4.0.6) racc (1.5.2) racc (1.5.2-java) @@ -136,8 +147,9 @@ GEM rubocop-ast (1.4.1) parser (>= 2.7.1.5) ruby-progressbar (1.11.0) - simplecov-html (0.12.3) simplecov_json_formatter (0.1.2) + spoon (0.0.6) + ffi sys-uname (1.2.2) ffi (~> 1.1) test-unit (3.3.6) @@ -175,6 +187,7 @@ DEPENDENCIES rspec (~> 3.2) rubocop simplecov! + simplecov-html! test-unit webrick diff --git a/features/method_coverage.feature b/features/method_coverage.feature new file mode 100644 index 00000000..aa52ba0d --- /dev/null +++ b/features/method_coverage.feature @@ -0,0 +1,39 @@ +@rspec @method_coverage +Feature: + + Simply executing method coverage gives ok results. + + Background: + Given I'm working on the project "faked_project" + + Scenario: + Given SimpleCov for RSpec is configured with: + """ + require 'simplecov' + SimpleCov.start do + enable_coverage :method + end + """ + When I open the coverage report generated with `bundle exec rspec spec` + Then I should see the groups: + | name | coverage | files | + | All Files | 91.8% | 7 | + And I should see a line coverage summary of 56/61 + And I should see a method coverage summary of 10/13 + And I should see the source files: + | name | coverage | method coverage | + | lib/faked_project.rb | 100.00 % | 100.00 % | + | lib/faked_project/some_class.rb | 80.00 % | 75.00 % | + | lib/faked_project/framework_specific.rb | 75.00 % | 33.33 % | + | lib/faked_project/meta_magic.rb | 100.00 % | 100.00 % | + | spec/forking_spec.rb | 100.00 % | 100.00 % | + | spec/meta_magic_spec.rb | 100.00 % | 100.00 % | + | spec/some_class_spec.rb | 100.00 % | 100.00 % | + + When I open the detailed view for "lib/faked_project/framework_specific.rb" + Then I should see a line coverage summary of 6/8 for the file + And I should see a method coverage summary of 1/3 for the file + And I should see missed methods list: + | name | + | ##test_unit | + | ##cucumber | diff --git a/features/step_definitions/html_steps.rb b/features/step_definitions/html_steps.rb index f4f080e7..69b5d42a 100644 --- a/features/step_definitions/html_steps.rb +++ b/features/step_definitions/html_steps.rb @@ -25,6 +25,7 @@ available_source_files = all(".t-file", visible: true, count: expected_files.count) include_branch_coverage = table.column_names.include?("branch coverage") + include_method_coverage = table.column_names.include?("method coverage") # Find all filenames and their coverage present in coverage report files = available_source_files.map do |file_row| @@ -35,6 +36,7 @@ } coverage_data["branch coverage"] = file_row.find(".t-file__branch-coverage").text if include_branch_coverage + coverage_data["method coverage"] = file_row.find(".t-file__method-coverage").text if include_method_coverage coverage_data end @@ -68,3 +70,9 @@ Then /^I should see coverage branch data like "(.+)"$/ do |text| expect(find(".hits", visible: true, text: text)).to be_truthy end + +Then /^I should see missed methods list:$/ do |table| + expected_list = table.hashes.map { |x| x.fetch("name") } + list = all(".t-missed-method-summary li", visible: true).map(&:text) + expect(list).to eq(expected_list) +end From b5c29b4414ff5d9c887b61f94418016b1095fe31 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Fri, 30 Apr 2021 19:03:44 +0300 Subject: [PATCH 21/33] fix indentation in features --- features/method_coverage.feature | 3 ++- features/step_definitions/simplecov_steps.rb | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/features/method_coverage.feature b/features/method_coverage.feature index aa52ba0d..98af2ddb 100644 --- a/features/method_coverage.feature +++ b/features/method_coverage.feature @@ -10,8 +10,9 @@ Feature: Given SimpleCov for RSpec is configured with: """ require 'simplecov' + SimpleCov.start do - enable_coverage :method + enable_coverage :method end """ When I open the coverage report generated with `bundle exec rspec spec` diff --git a/features/step_definitions/simplecov_steps.rb b/features/step_definitions/simplecov_steps.rb index 4e3081a0..d4e07137 100644 --- a/features/step_definitions/simplecov_steps.rb +++ b/features/step_definitions/simplecov_steps.rb @@ -22,7 +22,7 @@ steps %( Given a file named "#{framework_dir}/simplecov_config.rb" with: """ - #{config_body} +#{config_body.indent(6)} """ ) end From bb5aad1d74432ff7b964bb5c530fd2c9b8d75fab Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Fri, 30 Apr 2021 19:05:53 +0300 Subject: [PATCH 22/33] skip method coverage features if not supported --- features/support/env.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/features/support/env.rb b/features/support/env.rb index e5d3fb3a..75e39e29 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -28,6 +28,10 @@ skip_this_scenario unless SimpleCov.branch_coverage_supported? end +Before("@method_coverage") do + skip_this_scenario unless SimpleCov.method_coverage_supported? +end + Before("@rails6") do # Rails 6 only supports Ruby 2.5+ skip_this_scenario if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.5") From 0501b733836e278b5626575eeda09925c2c8f8fd Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Fri, 30 Apr 2021 19:25:15 +0300 Subject: [PATCH 23/33] fix build --- .github/workflows/stable.yml | 6 +++--- features/maximum_coverage_drop.feature | 1 - features/minimum_coverage.feature | 1 - features/minimum_coverage_by_file.feature | 1 - 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/stable.yml b/.github/workflows/stable.yml index 3234a65a..3a86f2ec 100644 --- a/.github/workflows/stable.yml +++ b/.github/workflows/stable.yml @@ -10,6 +10,9 @@ jobs: matrix: ruby: [2.5.8, 2.6.6, 2.7.2, 3.0.0, jruby-9.2.14.0] + env: + SIMPLECOV_HTML_MODE: methods + steps: - uses: actions/checkout@v2 @@ -21,9 +24,6 @@ jobs: - name: Get sqlite for Rails test projects run: sudo apt-get install libsqlite3-dev - - name: Install bundler - run: gem i bundler - - name: Install dependencies run: | bundle config set --local without benchmark diff --git a/features/maximum_coverage_drop.feature b/features/maximum_coverage_drop.feature index 5566a79c..7a8b60c5 100644 --- a/features/maximum_coverage_drop.feature +++ b/features/maximum_coverage_drop.feature @@ -314,7 +314,6 @@ Feature: When I run `bundle exec rake test` Then the exit status should not be 0 - And the output should not contain "Line coverage" And the output should contain "Branch coverage has dropped by 50.00% since the last time (maximum allowed: 0.00%)." And the output should contain "SimpleCov failed with exit 3" diff --git a/features/minimum_coverage.feature b/features/minimum_coverage.feature index ba1b8c60..6d38c869 100644 --- a/features/minimum_coverage.feature +++ b/features/minimum_coverage.feature @@ -84,5 +84,4 @@ Feature: When I run `bundle exec rake test` Then the exit status should not be 0 And the output should contain "Branch coverage (50.00%) is below the expected minimum coverage (80.00%)." - And the output should not contain "Line coverage" And the output should contain "SimpleCov failed with exit 2" diff --git a/features/minimum_coverage_by_file.feature b/features/minimum_coverage_by_file.feature index e4540ef9..49442a33 100644 --- a/features/minimum_coverage_by_file.feature +++ b/features/minimum_coverage_by_file.feature @@ -68,5 +68,4 @@ Feature: When I run `bundle exec rake test` Then the exit status should not be 0 And the output should contain "Branch coverage by file (50.00%) is below the expected minimum coverage (70.00%)." - And the output should not contain "Line coverage" And the output should contain "SimpleCov failed with exit 2" From ed40a9d8f50d1cbe8557a6efa7521cff2d0fa591 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Tue, 16 Nov 2021 23:32:48 +0300 Subject: [PATCH 24/33] add SimpleCov::Utils --- Gemfile.lock | 2 +- lib/simplecov.rb | 11 ++-------- .../exit_codes/maximum_coverage_drop_check.rb | 11 +++++----- .../minimum_coverage_by_file_check.rb | 10 +++++----- .../minimum_overall_coverage_check.rb | 8 ++++---- lib/simplecov/utils.rb | 20 +++++++++++++++++++ 6 files changed, 37 insertions(+), 25 deletions(-) create mode 100644 lib/simplecov/utils.rb diff --git a/Gemfile.lock b/Gemfile.lock index e686a04b..c3d7b5b2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -192,4 +192,4 @@ DEPENDENCIES webrick BUNDLED WITH - 2.2.16 + 2.2.30 diff --git a/lib/simplecov.rb b/lib/simplecov.rb index 7ac5c219..c90e21bc 100644 --- a/lib/simplecov.rb +++ b/lib/simplecov.rb @@ -285,18 +285,10 @@ def wait_for_other_processes def write_last_run(result) SimpleCov::LastRun.write(result: result.coverage_statistics.transform_values do |stats| - round_coverage(stats.percent) + SimpleCov::Utils.round_coverage(stats.percent) end) end - # - # @api private - # - # Rounding down to be extra strict, see #679 - def round_coverage(coverage) - coverage.floor(2) - end - private def initial_setup(profile, &block) @@ -467,6 +459,7 @@ def probably_running_parallel_tests? require_relative "simplecov/combine/results_combiner" require_relative "simplecov/useless_results_remover" require_relative "simplecov/simulate_coverage" +require_relative "simplecov/utils" # Load default config require_relative "simplecov/defaults" unless ENV["SIMPLECOV_NO_DEFAULTS"] diff --git a/lib/simplecov/exit_codes/maximum_coverage_drop_check.rb b/lib/simplecov/exit_codes/maximum_coverage_drop_check.rb index 7b65b96b..b1f3cdd1 100644 --- a/lib/simplecov/exit_codes/maximum_coverage_drop_check.rb +++ b/lib/simplecov/exit_codes/maximum_coverage_drop_check.rb @@ -17,10 +17,11 @@ def failing? def report coverage_drop_violations.each do |violation| $stderr.printf( - "%s coverage has dropped by %.2f%% since the last time (maximum allowed: %.2f%%).\n", + "%s coverage has dropped by %s since the last time " \ + "(maximum allowed: %s).\n", criterion: violation[:criterion].capitalize, - drop_percent: SimpleCov.round_coverage(violation[:drop_percent]), - max_drop: violation[:max_drop] + drop_percent: SimpleCov::Utils.render_coverage(violation[:drop_percent]), + max_drop: SimpleCov::Utils.render_coverage(violation[:max_drop]) ) end end @@ -60,9 +61,7 @@ def compute_coverage_drop_data MAX_DROP_ACCURACY = 10 def drop_percent(criterion) drop = last_coverage(criterion) - - SimpleCov.round_coverage( - result.coverage_statistics.fetch(criterion).percent - ) + SimpleCov::Utils.round_coverage(result.coverage_statistics.fetch(criterion).percent) # floats, I tell ya. # irb(main):001:0* 80.01 - 80.0 diff --git a/lib/simplecov/exit_codes/minimum_coverage_by_file_check.rb b/lib/simplecov/exit_codes/minimum_coverage_by_file_check.rb index a276d275..cf617201 100644 --- a/lib/simplecov/exit_codes/minimum_coverage_by_file_check.rb +++ b/lib/simplecov/exit_codes/minimum_coverage_by_file_check.rb @@ -15,10 +15,10 @@ def failing? def report minimum_violations.each do |violation| $stderr.printf( - "%s coverage by file (%.2f%%) is below the expected minimum coverage (%.2f%%).\n", - covered: SimpleCov.round_coverage(violation.fetch(:actual)), - minimum_coverage: violation.fetch(:minimum_expected), - criterion: violation.fetch(:criterion).capitalize + "%s coverage by file (%s) is below the expected minimum coverage (%s).\n", + criterion: violation.fetch(:criterion).capitalize, + covered: SimpleCov::Utils.render_coverage(violation.fetch(:actual)), + minimum_coverage: SimpleCov::Utils.render_coverage(violation.fetch(:minimum_expected)) ) end end @@ -44,7 +44,7 @@ def compute_minimum_coverage_data { criterion: criterion, minimum_expected: expected_percent, - actual: SimpleCov.round_coverage(actual_coverage.percent) + actual: SimpleCov::Utils.round_coverage(actual_coverage.percent) } end end diff --git a/lib/simplecov/exit_codes/minimum_overall_coverage_check.rb b/lib/simplecov/exit_codes/minimum_overall_coverage_check.rb index ea3a0ea9..5fd4fa3e 100644 --- a/lib/simplecov/exit_codes/minimum_overall_coverage_check.rb +++ b/lib/simplecov/exit_codes/minimum_overall_coverage_check.rb @@ -15,10 +15,10 @@ def failing? def report minimum_violations.each do |violation| $stderr.printf( - "%s coverage (%.2f%%) is below the expected minimum coverage (%.2f%%).\n", - covered: SimpleCov.round_coverage(violation.fetch(:actual)), - minimum_coverage: violation.fetch(:minimum_expected), - criterion: violation.fetch(:criterion).capitalize + "%s coverage (%s) is below the expected minimum coverage (%s).\n", + criterion: violation.fetch(:criterion).capitalize, + covered: SimpleCov::Utils.render_coverage(violation.fetch(:actual)), + minimum_coverage: SimpleCov::Utils.render_coverage(violation.fetch(:minimum_expected)) ) end end diff --git a/lib/simplecov/utils.rb b/lib/simplecov/utils.rb new file mode 100644 index 00000000..116351f1 --- /dev/null +++ b/lib/simplecov/utils.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module SimpleCov + # Functionally for rounding coverage results + module Utils + module_function + + # + # @api private + # + # Rounding down to be extra strict, see #679 + def round_coverage(coverage) + coverage.floor(2) + end + + def render_coverage(coverage) + format("%.2f%%", round_coverage(coverage)) + end + end +end From a9978b05199afe09797a0edde2a352c8aa59e4a0 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Wed, 17 Nov 2021 00:23:08 +0300 Subject: [PATCH 25/33] update bundler --- Gemfile.lock | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index c3d7b5b2..4c04536e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,10 +1,3 @@ -GIT - remote: https://github.com/umbrellio/simplecov-html.git - revision: fc9c7a1beaa75bad3a925d1296b94fcd0c96b126 - branch: add-method-coverage-support - specs: - simplecov-html (0.12.3) - PATH remote: . specs: @@ -147,6 +140,7 @@ GEM rubocop-ast (1.4.1) parser (>= 2.7.1.5) ruby-progressbar (1.11.0) + simplecov-html (0.12.3) simplecov_json_formatter (0.1.2) spoon (0.0.6) ffi @@ -187,9 +181,8 @@ DEPENDENCIES rspec (~> 3.2) rubocop simplecov! - simplecov-html! test-unit webrick BUNDLED WITH - 2.2.30 + 2.2.31 From 5cdbe219beb58ecfb8795161f7641b7579e9402a Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Sat, 7 Jan 2023 15:58:41 +0600 Subject: [PATCH 26/33] update nokogiri --- Gemfile.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4c04536e..c9a5336b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -81,13 +81,13 @@ GEM method_source (1.0.0) middleware (0.1.0) mini_mime (1.0.2) - mini_portile2 (2.5.0) + mini_portile2 (2.8.1) minitest (5.14.3) multi_test (0.1.2) - nokogiri (1.11.1) - mini_portile2 (~> 2.5.0) + nokogiri (1.13.10) + mini_portile2 (~> 2.8.0) racc (~> 1.4) - nokogiri (1.11.1-java) + nokogiri (1.13.10-java) racc (~> 1.4) parallel (1.20.1) parser (3.0.0.0) @@ -106,8 +106,8 @@ GEM method_source (~> 1.0) spoon (~> 0.0) public_suffix (4.0.6) - racc (1.5.2) - racc (1.5.2-java) + racc (1.6.2) + racc (1.6.2-java) rack (2.2.3) rack-test (1.1.0) rack (>= 1.0, < 3) @@ -185,4 +185,4 @@ DEPENDENCIES webrick BUNDLED WITH - 2.2.31 + 2.4.3 From a07dd23a063370409ea7492b81ea527578bc84b4 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Sat, 7 Jan 2023 16:11:56 +0600 Subject: [PATCH 27/33] update gemfiles --- Gemfile.lock | 11 +++++++++-- test_projects/rails/rspec_rails/Gemfile.lock | 14 +++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 66c4301d..2bf999dd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,6 +6,13 @@ GIT capybara (~> 3.13, < 4) websocket-driver (>= 0.6.5) +GIT + remote: https://github.com/umbrellio/simplecov-html.git + revision: fc9c7a1beaa75bad3a925d1296b94fcd0c96b126 + branch: add-method-coverage-support + specs: + simplecov-html (0.12.3) + PATH remote: . specs: @@ -147,7 +154,6 @@ GEM rubocop-ast (1.15.1) parser (>= 3.0.1.1) ruby-progressbar (1.11.0) - simplecov-html (0.12.3) simplecov_json_formatter (0.1.3) spoon (0.0.6) ffi @@ -189,8 +195,9 @@ DEPENDENCIES rspec (~> 3.2) rubocop simplecov! + simplecov-html! test-unit webrick BUNDLED WITH - 2.3.4 + 2.4.3 diff --git a/test_projects/rails/rspec_rails/Gemfile.lock b/test_projects/rails/rspec_rails/Gemfile.lock index 56f5d142..713a7ecd 100644 --- a/test_projects/rails/rspec_rails/Gemfile.lock +++ b/test_projects/rails/rspec_rails/Gemfile.lock @@ -106,24 +106,24 @@ GEM matrix (0.4.2) method_source (1.0.0) mini_mime (1.1.2) - mini_portile2 (2.5.3) + mini_portile2 (2.8.1) minitest (5.15.0) msgpack (1.3.3) msgpack (1.3.3-java) nio4r (2.5.4) nio4r (2.5.4-java) - nokogiri (1.11.0) - mini_portile2 (~> 2.5.0) + nokogiri (1.13.10) + mini_portile2 (~> 2.8.0) racc (~> 1.4) - nokogiri (1.11.0-java) + nokogiri (1.13.10-java) racc (~> 1.4) public_suffix (4.0.7) puma (5.1.1) nio4r (~> 2.0) puma (5.1.1-java) nio4r (~> 2.0) - racc (1.6.0) - racc (1.6.0-java) + racc (1.6.2) + racc (1.6.2-java) rack (2.2.3) rack-test (1.1.0) rack (>= 1.0, < 3) @@ -222,4 +222,4 @@ DEPENDENCIES web-console (>= 4.1.0) BUNDLED WITH - 2.3.4 + 2.4.3 From bb0fd38cfa34249906c8f7c673da3a23d22e69f6 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Sat, 7 Jan 2023 16:19:40 +0600 Subject: [PATCH 28/33] fix gh workflow --- .github/workflows/stable.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/stable.yml b/.github/workflows/stable.yml index 9e0d7bd9..696339a1 100644 --- a/.github/workflows/stable.yml +++ b/.github/workflows/stable.yml @@ -13,9 +13,7 @@ jobs: env: BUNDLE_WITHOUT: "benchmark" JRUBY_OPTS: "--debug" - - env: - SIMPLECOV_HTML_MODE: methods + SIMPLECOV_HTML_MODE: "methods" steps: - uses: actions/checkout@v3 From ed4fb86a21f0e051eedf335d81fce34c311a4895 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Sat, 7 Jan 2023 16:25:04 +0600 Subject: [PATCH 29/33] fix spec --- spec/coverage_for_eval_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/coverage_for_eval_spec.rb b/spec/coverage_for_eval_spec.rb index 7677b3a3..5e582cb9 100644 --- a/spec/coverage_for_eval_spec.rb +++ b/spec/coverage_for_eval_spec.rb @@ -19,7 +19,7 @@ let(:command) { "ruby eval_test.rb" } it "records coverage for erb" do - expect(@stdout).to include(" 2 / 3 LOC") + expect(@stdout).to include("Line coverage: 2 / 3") end end end From 15ab7902d4f2cd88b3490c4e78a3e662d14d58b2 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Mon, 9 Jan 2023 14:04:25 +0600 Subject: [PATCH 30/33] add some todos --- .github/workflows/stable.yml | 2 +- Gemfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/stable.yml b/.github/workflows/stable.yml index 696339a1..7bddcb4d 100644 --- a/.github/workflows/stable.yml +++ b/.github/workflows/stable.yml @@ -13,7 +13,7 @@ jobs: env: BUNDLE_WITHOUT: "benchmark" JRUBY_OPTS: "--debug" - SIMPLECOV_HTML_MODE: "methods" + SIMPLECOV_HTML_MODE: "methods" # TODO: remove after simplecov-html release steps: - uses: actions/checkout@v3 diff --git a/Gemfile b/Gemfile index 42b94000..b1545b32 100644 --- a/Gemfile +++ b/Gemfile @@ -9,7 +9,7 @@ when "local" when "github" # Use development version of html formatter from github gem "simplecov-html", github: "simplecov-ruby/simplecov-html" -when "methods" +when "methods" # TODO: remove after simplecov-html release gem "simplecov-html", github: "umbrellio/simplecov-html", branch: "add-method-coverage-support" end From c13f0b1c5017cfacb12b4d6a37151f1d551ec710 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Mon, 25 Dec 2023 19:03:01 +0300 Subject: [PATCH 31/33] fix rubocop issue --- lib/simplecov/result_merger.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/simplecov/result_merger.rb b/lib/simplecov/result_merger.rb index 78dbcc7c..fbaf5439 100644 --- a/lib/simplecov/result_merger.rb +++ b/lib/simplecov/result_merger.rb @@ -82,7 +82,7 @@ def within_merge_timeout?(result) def merge_coverage(results) results = results.compact - return nil if results.size.zero? + return nil if results.empty? return results.first if results.size == 1 parsed_results = results.map(&:original_result) From 037a493dd84119027557a8c89f4fb90a75ea03dd Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Mon, 25 Dec 2023 19:06:27 +0300 Subject: [PATCH 32/33] revert bundler version --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 51a82e3b..99eda27e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -208,4 +208,4 @@ DEPENDENCIES webrick BUNDLED WITH - 2.5.3 + 2.4.20 From 8ede952b825683bf3bff34fdfca068c53a614860 Mon Sep 17 00:00:00 2001 From: Yuri Smirnov Date: Mon, 25 Dec 2023 19:13:00 +0300 Subject: [PATCH 33/33] update simplecov-html --- .github/workflows/stable.yml | 1 - Gemfile.lock | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/stable.yml b/.github/workflows/stable.yml index 2239bef1..5557333f 100644 --- a/.github/workflows/stable.yml +++ b/.github/workflows/stable.yml @@ -22,7 +22,6 @@ jobs: uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - rubygems: latest bundler-cache: true # 'bundle install' and cache - name: Run tests diff --git a/Gemfile.lock b/Gemfile.lock index 99eda27e..a62b117b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,7 +8,7 @@ GIT GIT remote: https://github.com/umbrellio/simplecov-html.git - revision: dea7be12fce6364e9d7a7529a4fcd52075c18af8 + revision: 54879bd1080865cf8013bcda12e0c03ac687d7a9 branch: add-method-coverage-support specs: simplecov-html (0.12.3)