From 583e2525a9e19aa15edad31c9035e358b3e741bc Mon Sep 17 00:00:00 2001 From: Hugo Peixoto Date: Sun, 25 Oct 2015 02:13:53 +0000 Subject: [PATCH 1/3] Adds option to track uncovered source files Added a configuration option `track_files` that accepts a glob. With this enabled, coverage result will include uncovered files that match the glob. In the `rails` profile this is set to `{app,lib}/**/*.rb` --- features/config_tracked_files.feature | 29 +++++++++++++++ lib/simplecov.rb | 35 ++++++++++++++++++- lib/simplecov/configuration.rb | 4 +++ lib/simplecov/defaults.rb | 2 ++ spec/faked_project/lib/faked_project.rb | 2 +- .../lib/faked_project/untested_class.rb | 11 ++++++ 6 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 features/config_tracked_files.feature create mode 100644 spec/faked_project/lib/faked_project/untested_class.rb diff --git a/features/config_tracked_files.feature b/features/config_tracked_files.feature new file mode 100644 index 00000000..305558f4 --- /dev/null +++ b/features/config_tracked_files.feature @@ -0,0 +1,29 @@ +@test_unit +Feature: + + Using the setting `tracked_files` should add files that were not + required to the report. + + Scenario: + Given SimpleCov for Test/Unit is configured with: + """ + require 'simplecov' + SimpleCov.start do + track_files "lib/**/*.rb" + end + """ + + When I open the coverage report generated with `bundle exec rake test` + Then I should see the groups: + | name | coverage | files | + | All Files | 81.54% | 7 | + + And I should see the source files: + | name | coverage | + | lib/faked_project.rb | 100.0 % | + | lib/faked_project/untested_class.rb | 0.0 % | + | lib/faked_project/some_class.rb | 80.0 % | + | lib/faked_project/framework_specific.rb | 75.0 % | + | lib/faked_project/meta_magic.rb | 100.0 % | + | test/meta_magic_test.rb | 100.0 % | + | test/some_class_test.rb | 100.0 % | diff --git a/lib/simplecov.rb b/lib/simplecov.rb index f4a555ea..bdd09294 100644 --- a/lib/simplecov.rb +++ b/lib/simplecov.rb @@ -48,12 +48,45 @@ def start(profile = nil, &block) end end + # + # Finds files that were to be tracked but were not covered and initializes + # their coverage to zero, with an estimation of the line count. + # + def add_uncovered_files(result) + if @track_files_glob + result = result.dup + Dir[@track_files_glob].each do |file| + absolute = File.expand_path(file) + + unless result[absolute] + lines = File.readlines(absolute) + result[absolute] = [0] * lines.count { |l| relevant_line?(l) } + end + end + end + + result + end + + # + # Determines if a line should be considered by coverage tools. + # This method is just an estimation, but it is not very important + # that it is accurate. It is only used when all lines in a file + # are not covered. As soon as a single line is covered, the counting + # method will be the one provided by the Coverage module. + # + def relevant_line?(line) + l = line.strip + + !(l.empty? || l =~ /^else$/ || l =~ /^end$/ || l[0] == '#' || l =~ /^rescue(\s+.*)?$/) + end + # # Returns the result for the current coverage run, merging it across test suites # from cache using SimpleCov::ResultMerger if use_merging is activated (default) # def result - @result ||= SimpleCov::Result.new(Coverage.result) if running + @result ||= SimpleCov::Result.new(add_uncovered_files(Coverage.result)) if running # If we're using merging of results, store the current result # first, then merge the results and return those if use_merging diff --git a/lib/simplecov/configuration.rb b/lib/simplecov/configuration.rb index 3e0d6c46..73b68c65 100644 --- a/lib/simplecov/configuration.rb +++ b/lib/simplecov/configuration.rb @@ -42,6 +42,10 @@ def coverage_path coverage_path end + def track_files(glob) + @track_files_glob = glob + end + # # Returns the list of configured filters. Add filters using SimpleCov.add_filter. # diff --git a/lib/simplecov/defaults.rb b/lib/simplecov/defaults.rb index 09aad1c1..c60d9d6b 100644 --- a/lib/simplecov/defaults.rb +++ b/lib/simplecov/defaults.rb @@ -32,6 +32,8 @@ add_group "Mailers", "app/mailers" add_group "Helpers", "app/helpers" add_group "Libraries", "lib" + + track_files "{app,lib}/**/*.rb" end # Default configuration diff --git a/spec/faked_project/lib/faked_project.rb b/spec/faked_project/lib/faked_project.rb index c33c7917..ba5c49d7 100644 --- a/spec/faked_project/lib/faked_project.rb +++ b/spec/faked_project/lib/faked_project.rb @@ -4,7 +4,7 @@ def self.foo end end -Dir[File.join(File.dirname(__FILE__), "faked_project/*.rb")].each do |file| +Dir[File.join(File.dirname(__FILE__), "faked_project/*.rb")].reject { |f| /untested/.match(f) }.each do |file| require file # Require all source files in project dynamically so we can inject some stuff depending on test situation end diff --git a/spec/faked_project/lib/faked_project/untested_class.rb b/spec/faked_project/lib/faked_project/untested_class.rb new file mode 100644 index 00000000..dc03d0f9 --- /dev/null +++ b/spec/faked_project/lib/faked_project/untested_class.rb @@ -0,0 +1,11 @@ +class UntestedClass + def initialize(yogurts) + @yogurts = yogurts + end + + def power_level + @yogurts.map do |yo| + yo.experience_points**2 + end.reduce(0, &:+) + end +end From 81e2431d4047f921309f5f3e6abceb89692c0e95 Mon Sep 17 00:00:00 2001 From: Hugo Peixoto Date: Sun, 29 Nov 2015 14:24:57 +0000 Subject: [PATCH 2/3] When a file is not loaded, mark it completely as not covered --- features/config_tracked_files.feature | 2 +- lib/simplecov.rb | 26 +++++--------------------- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/features/config_tracked_files.feature b/features/config_tracked_files.feature index 305558f4..ba0c4f0c 100644 --- a/features/config_tracked_files.feature +++ b/features/config_tracked_files.feature @@ -16,7 +16,7 @@ Feature: When I open the coverage report generated with `bundle exec rake test` Then I should see the groups: | name | coverage | files | - | All Files | 81.54% | 7 | + | All Files | 76.81% | 7 | And I should see the source files: | name | coverage | diff --git a/lib/simplecov.rb b/lib/simplecov.rb index bdd09294..95da3ebd 100644 --- a/lib/simplecov.rb +++ b/lib/simplecov.rb @@ -49,44 +49,28 @@ def start(profile = nil, &block) end # - # Finds files that were to be tracked but were not covered and initializes - # their coverage to zero, with an estimation of the line count. + # Finds files that were to be tracked but were not loaded and initializes + # their coverage to zero. # - def add_uncovered_files(result) + def add_not_loaded_files(result) if @track_files_glob result = result.dup Dir[@track_files_glob].each do |file| absolute = File.expand_path(file) - unless result[absolute] - lines = File.readlines(absolute) - result[absolute] = [0] * lines.count { |l| relevant_line?(l) } - end + result[absolute] ||= [0] * File.foreach(absolute).count end end result end - # - # Determines if a line should be considered by coverage tools. - # This method is just an estimation, but it is not very important - # that it is accurate. It is only used when all lines in a file - # are not covered. As soon as a single line is covered, the counting - # method will be the one provided by the Coverage module. - # - def relevant_line?(line) - l = line.strip - - !(l.empty? || l =~ /^else$/ || l =~ /^end$/ || l[0] == '#' || l =~ /^rescue(\s+.*)?$/) - end - # # Returns the result for the current coverage run, merging it across test suites # from cache using SimpleCov::ResultMerger if use_merging is activated (default) # def result - @result ||= SimpleCov::Result.new(add_uncovered_files(Coverage.result)) if running + @result ||= SimpleCov::Result.new(add_not_loaded_files(Coverage.result)) if running # If we're using merging of results, store the current result # first, then merge the results and return those if use_merging From 3414dd6985fd2559d1bad83a82d8683fb4cbc76c Mon Sep 17 00:00:00 2001 From: Xavier Shay Date: Sun, 29 Nov 2015 11:38:33 -0800 Subject: [PATCH 3/3] Add track_files method documentation. --- lib/simplecov/configuration.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/simplecov/configuration.rb b/lib/simplecov/configuration.rb index 73b68c65..d7d20da5 100644 --- a/lib/simplecov/configuration.rb +++ b/lib/simplecov/configuration.rb @@ -42,6 +42,11 @@ def coverage_path coverage_path end + # + # Coverage results will always include files matched by this glob, whether + # or not they were explicitly required. Without this, un-required files + # will not be present in the final report. + # def track_files(glob) @track_files_glob = glob end