simplecov 0.9.2 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -7
- data/.gitignore +0 -1
- data/.rubocop.yml +69 -0
- data/CHANGELOG.md +39 -22
- data/Gemfile +16 -15
- data/MIT-LICENSE +1 -1
- data/README.md +183 -178
- data/Rakefile +16 -7
- data/doc/alternate-formatters.md +36 -0
- data/doc/commercial-services.md +20 -0
- data/doc/editor-integration.md +13 -0
- data/features/rspec_basic.feature +3 -2
- data/features/rspec_groups_and_filters_complex.feature +2 -0
- data/features/rspec_groups_using_filter_class.feature +3 -2
- data/features/step_definitions/html_steps.rb +6 -7
- data/features/step_definitions/simplecov_steps.rb +18 -16
- data/features/step_definitions/transformers.rb +2 -2
- data/features/step_definitions/web_steps.rb +4 -4
- data/features/support/env.rb +17 -15
- data/lib/simplecov.rb +35 -24
- data/lib/simplecov/command_guesser.rb +33 -34
- data/lib/simplecov/configuration.rb +238 -234
- data/lib/simplecov/defaults.rb +37 -36
- data/lib/simplecov/exit_codes.rb +7 -5
- data/lib/simplecov/file_list.rb +38 -36
- data/lib/simplecov/filter.rb +12 -2
- data/lib/simplecov/formatter.rb +2 -2
- data/lib/simplecov/formatter/simple_formatter.rb +1 -1
- data/lib/simplecov/jruby_fix.rb +4 -4
- data/lib/simplecov/last_run.rb +15 -13
- data/lib/simplecov/merge_helpers.rb +26 -27
- data/lib/simplecov/no_defaults.rb +2 -2
- data/lib/simplecov/profiles.rb +21 -19
- data/lib/simplecov/railtie.rb +1 -1
- data/lib/simplecov/railties/tasks.rake +7 -7
- data/lib/simplecov/result.rb +5 -5
- data/lib/simplecov/result_merger.rb +65 -62
- data/lib/simplecov/source_file.rb +23 -24
- data/lib/simplecov/version.rb +20 -1
- data/simplecov.gemspec +14 -12
- data/test/faked_project/Gemfile +5 -5
- data/test/faked_project/Rakefile +4 -4
- data/test/faked_project/features/step_definitions/my_steps.rb +3 -4
- data/test/faked_project/features/support/env.rb +5 -5
- data/test/faked_project/lib/faked_project.rb +1 -1
- data/test/faked_project/lib/faked_project/some_class.rb +3 -4
- data/test/faked_project/spec/faked_spec.rb +2 -2
- data/test/faked_project/spec/forking_spec.rb +7 -0
- data/test/faked_project/spec/meta_magic_spec.rb +1 -1
- data/test/faked_project/spec/some_class_spec.rb +3 -3
- data/test/faked_project/spec/spec_helper.rb +4 -8
- data/test/faked_project/test/faked_test.rb +2 -2
- data/test/faked_project/test/meta_magic_test.rb +1 -1
- data/test/faked_project/test/some_class_test.rb +3 -3
- data/test/faked_project/test/test_helper.rb +5 -9
- data/test/fixtures/app/controllers/sample_controller.rb +1 -1
- data/test/fixtures/app/models/user.rb +1 -1
- data/test/fixtures/deleted_source_sample.rb +3 -3
- data/test/fixtures/frameworks/rspec_bad.rb +4 -4
- data/test/fixtures/frameworks/rspec_good.rb +4 -4
- data/test/fixtures/frameworks/testunit_bad.rb +3 -3
- data/test/fixtures/frameworks/testunit_good.rb +3 -3
- data/test/fixtures/resultset2.rb +0 -1
- data/test/fixtures/sample.rb +1 -1
- data/test/fixtures/utf-8.rb +1 -1
- data/test/helper.rb +8 -8
- data/test/test_1_8_fallbacks.rb +6 -6
- data/test/test_command_guesser.rb +7 -7
- data/test/test_deleted_source.rb +2 -2
- data/test/test_file_list.rb +8 -6
- data/test/test_filters.rb +29 -13
- data/test/test_merge_helpers.rb +26 -23
- data/test/test_result.rb +32 -23
- data/test/test_return_codes.rb +3 -3
- data/test/test_source_file.rb +4 -4
- data/test/test_source_file_line.rb +13 -13
- metadata +145 -63
- data/lib/simplecov/json.rb +0 -27
data/lib/simplecov/defaults.rb
CHANGED
@@ -1,51 +1,57 @@
|
|
1
1
|
# Load default formatter gem
|
2
|
-
require
|
2
|
+
require "simplecov-html"
|
3
3
|
|
4
|
-
SimpleCov.profiles.define
|
4
|
+
SimpleCov.profiles.define "root_filter" do
|
5
5
|
# Exclude all files outside of simplecov root
|
6
6
|
add_filter do |src|
|
7
7
|
!(src.filename =~ /^#{Regexp.escape(SimpleCov.root)}/i)
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
SimpleCov.profiles.define
|
12
|
-
add_filter
|
13
|
-
add_filter
|
14
|
-
add_filter
|
15
|
-
add_filter
|
11
|
+
SimpleCov.profiles.define "test_frameworks" do
|
12
|
+
add_filter "/test/"
|
13
|
+
add_filter "/features/"
|
14
|
+
add_filter "/spec/"
|
15
|
+
add_filter "/autotest/"
|
16
16
|
end
|
17
17
|
|
18
|
-
SimpleCov.profiles.define
|
19
|
-
|
18
|
+
SimpleCov.profiles.define "bundler_filter" do
|
19
|
+
add_filter "/vendor/bundle/"
|
20
|
+
end
|
21
|
+
|
22
|
+
SimpleCov.profiles.define "rails" do
|
23
|
+
load_profile "test_frameworks"
|
20
24
|
|
21
|
-
add_filter
|
22
|
-
add_filter
|
23
|
-
add_filter '/vendor/bundle/'
|
25
|
+
add_filter "/config/"
|
26
|
+
add_filter "/db/"
|
24
27
|
|
25
|
-
add_group
|
26
|
-
add_group
|
27
|
-
add_group
|
28
|
-
add_group
|
29
|
-
add_group
|
28
|
+
add_group "Controllers", "app/controllers"
|
29
|
+
add_group "Models", "app/models"
|
30
|
+
add_group "Mailers", "app/mailers"
|
31
|
+
add_group "Helpers", "app/helpers"
|
32
|
+
add_group "Libraries", "lib"
|
30
33
|
end
|
31
34
|
|
32
35
|
# Default configuration
|
33
36
|
SimpleCov.configure do
|
34
37
|
formatter SimpleCov::Formatter::HTMLFormatter
|
38
|
+
load_profile "bundler_filter"
|
35
39
|
# Exclude files outside of SimpleCov.root
|
36
|
-
load_profile
|
40
|
+
load_profile "root_filter"
|
37
41
|
end
|
38
42
|
|
39
43
|
# Gotta stash this a-s-a-p, see the CommandGuesser class and i.e. #110 for further info
|
40
|
-
SimpleCov::CommandGuesser.original_run_command = "#{$
|
44
|
+
SimpleCov::CommandGuesser.original_run_command = "#{$PROGRAM_NAME} #{ARGV.join(' ')}"
|
41
45
|
|
42
46
|
at_exit do
|
47
|
+
# If we are in a different process than called start, don't interfere.
|
48
|
+
next if SimpleCov.pid != Process.pid
|
43
49
|
|
44
|
-
if
|
50
|
+
if $ERROR_INFO # was an exception thrown?
|
45
51
|
# if it was a SystemExit, use the accompanying status
|
46
52
|
# otherwise set a non-zero status representing termination by some other exception
|
47
53
|
# (see github issue 41)
|
48
|
-
@exit_status =
|
54
|
+
@exit_status = $ERROR_INFO.is_a?(SystemExit) ? $ERROR_INFO.status : SimpleCov::ExitCodes::EXCEPTION
|
49
55
|
else
|
50
56
|
# Store the exit status of the test run since it goes away after calling the at_exit proc...
|
51
57
|
@exit_status = SimpleCov::ExitCodes::SUCCESS
|
@@ -57,18 +63,13 @@ at_exit do
|
|
57
63
|
covered_percent = SimpleCov.result.covered_percent.round(2)
|
58
64
|
|
59
65
|
if @exit_status == SimpleCov::ExitCodes::SUCCESS # No other errors
|
60
|
-
if covered_percent < SimpleCov.minimum_coverage
|
61
|
-
$stderr.
|
62
|
-
[covered_percent, SimpleCov.minimum_coverage]
|
63
|
-
|
66
|
+
if covered_percent < SimpleCov.minimum_coverage # rubocop:disable Metrics/BlockNesting
|
67
|
+
$stderr.printf("Coverage (%.2f%%) is below the expected minimum coverage (%.2f%%).\n", covered_percent, SimpleCov.minimum_coverage)
|
64
68
|
@exit_status = SimpleCov::ExitCodes::MINIMUM_COVERAGE
|
65
|
-
|
66
|
-
|
67
|
-
diff
|
68
|
-
|
69
|
-
$stderr.puts "Coverage has dropped by %.2f%% since the last time (maximum allowed: %.2f%%)." % \
|
70
|
-
[diff, SimpleCov.maximum_coverage_drop]
|
71
|
-
|
69
|
+
elsif (last_run = SimpleCov::LastRun.read) # rubocop:disable Metrics/BlockNesting
|
70
|
+
diff = last_run["result"]["covered_percent"] - covered_percent
|
71
|
+
if diff > SimpleCov.maximum_coverage_drop # rubocop:disable Metrics/BlockNesting
|
72
|
+
$stderr.printf("Coverage has dropped by %.2f%% since the last time (maximum allowed: %.2f%%).\n", diff, SimpleCov.maximum_coverage_drop)
|
72
73
|
@exit_status = SimpleCov::ExitCodes::MAXIMUM_COVERAGE_DROP
|
73
74
|
end
|
74
75
|
end
|
@@ -83,13 +84,13 @@ at_exit do
|
|
83
84
|
end
|
84
85
|
|
85
86
|
# Autoload config from ~/.simplecov if present
|
86
|
-
require
|
87
|
-
home_dir = File.expand_path(
|
87
|
+
require "etc"
|
88
|
+
home_dir = File.expand_path("~") || Etc.getpwuid.dir || (ENV["USER"] && File.expand_path("~#{ENV['USER']}"))
|
88
89
|
if home_dir
|
89
|
-
global_config_path = File.join(home_dir,
|
90
|
+
global_config_path = File.join(home_dir, ".simplecov")
|
90
91
|
load global_config_path if File.exist?(global_config_path)
|
91
92
|
end
|
92
93
|
|
93
94
|
# Autoload config from .simplecov if present
|
94
|
-
config_path = File.join(SimpleCov.root,
|
95
|
+
config_path = File.join(SimpleCov.root, ".simplecov")
|
95
96
|
load config_path if File.exist?(config_path)
|
data/lib/simplecov/exit_codes.rb
CHANGED
data/lib/simplecov/file_list.rb
CHANGED
@@ -1,46 +1,48 @@
|
|
1
1
|
# An array of SimpleCov SourceFile instances with additional collection helper
|
2
2
|
# methods for calculating coverage across them etc.
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
module SimpleCov
|
4
|
+
class FileList < Array
|
5
|
+
# Returns the count of lines that have coverage
|
6
|
+
def covered_lines
|
7
|
+
return 0.0 if empty?
|
8
|
+
map { |f| f.covered_lines.count }.inject(&:+)
|
9
|
+
end
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
# Returns the count of lines that have been missed
|
12
|
+
def missed_lines
|
13
|
+
return 0.0 if empty?
|
14
|
+
map { |f| f.missed_lines.count }.inject(&:+)
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
# Returns the count of lines that are not relevant for coverage
|
18
|
+
def never_lines
|
19
|
+
return 0.0 if empty?
|
20
|
+
map { |f| f.never_lines.count }.inject(&:+)
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
# Returns the count of skipped lines
|
24
|
+
def skipped_lines
|
25
|
+
return 0.0 if empty?
|
26
|
+
map { |f| f.skipped_lines.count }.inject(&:+)
|
27
|
+
end
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
# Returns the overall amount of relevant lines of code across all files in this list
|
30
|
+
def lines_of_code
|
31
|
+
covered_lines + missed_lines
|
32
|
+
end
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
# Computes the coverage based upon lines covered and lines missed
|
35
|
+
# @return [Float]
|
36
|
+
def covered_percent
|
37
|
+
return 100.0 if empty? || lines_of_code.zero?
|
38
|
+
Float(covered_lines * 100.0 / lines_of_code)
|
39
|
+
end
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
# Computes the strength (hits / line) based upon lines covered and lines missed
|
42
|
+
# @return [Float]
|
43
|
+
def covered_strength
|
44
|
+
return 0.0 if empty? || lines_of_code.zero?
|
45
|
+
Float(map { |f| f.covered_strength * f.lines_of_code }.inject(&:+) / lines_of_code)
|
46
|
+
end
|
45
47
|
end
|
46
48
|
end
|
data/lib/simplecov/filter.rb
CHANGED
@@ -16,8 +16,8 @@ module SimpleCov
|
|
16
16
|
@filter_argument = filter_argument
|
17
17
|
end
|
18
18
|
|
19
|
-
def matches?(
|
20
|
-
|
19
|
+
def matches?(_)
|
20
|
+
fail "The base filter class is not intended for direct use"
|
21
21
|
end
|
22
22
|
|
23
23
|
def passes?(source_file)
|
@@ -41,4 +41,14 @@ module SimpleCov
|
|
41
41
|
filter_argument.call(source_file)
|
42
42
|
end
|
43
43
|
end
|
44
|
+
|
45
|
+
class ArrayFilter < SimpleCov::Filter
|
46
|
+
# Returns true if any of the file paths passed in the given array matches the string
|
47
|
+
# configured when initializing this Filter with StringFilter.new(['some/path', 'other/path'])
|
48
|
+
def matches?(source_files_list)
|
49
|
+
filter_argument.any? do |arg|
|
50
|
+
source_files_list.filename =~ /#{arg}/
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
44
54
|
end
|
data/lib/simplecov/formatter.rb
CHANGED
@@ -9,7 +9,7 @@ module SimpleCov
|
|
9
9
|
output = ""
|
10
10
|
result.groups.each do |name, files|
|
11
11
|
output << "Group: #{name}\n"
|
12
|
-
output << "="*40
|
12
|
+
output << "=" * 40
|
13
13
|
output << "\n"
|
14
14
|
files.each do |file|
|
15
15
|
output << "#{file.filename} (coverage: #{file.covered_percent.round(2)}%)\n"
|
data/lib/simplecov/jruby_fix.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
if defined?(JRUBY_VERSION) && JRUBY_VERSION.to_f < 1.7
|
2
|
-
require
|
3
|
-
java_import
|
2
|
+
require "jruby"
|
3
|
+
java_import "org.jruby.ast.NodeType"
|
4
4
|
|
5
5
|
# Coverage for JRuby < 1.7.0 does not work correctly
|
6
6
|
#
|
@@ -11,9 +11,9 @@ if defined?(JRUBY_VERSION) && JRUBY_VERSION.to_f < 1.7
|
|
11
11
|
# This monkey patches Coverage to address those issues
|
12
12
|
module Coverage
|
13
13
|
class << self
|
14
|
-
|
14
|
+
alias_method :__broken_result__, :result
|
15
15
|
|
16
|
-
def result
|
16
|
+
def result # rubocop:disable Metrics/MethodLength
|
17
17
|
fixed = {}
|
18
18
|
__broken_result__.each do |path, executed_lines|
|
19
19
|
next unless File.file? path
|
data/lib/simplecov/last_run.rb
CHANGED
@@ -1,20 +1,22 @@
|
|
1
|
-
|
2
|
-
class << self
|
3
|
-
def last_run_path
|
4
|
-
File.join(SimpleCov.coverage_path, '.last_run.json')
|
5
|
-
end
|
1
|
+
require "json"
|
6
2
|
|
7
|
-
|
8
|
-
|
3
|
+
module SimpleCov
|
4
|
+
module LastRun
|
5
|
+
class << self
|
6
|
+
def last_run_path
|
7
|
+
File.join(SimpleCov.coverage_path, ".last_run.json")
|
8
|
+
end
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
def read
|
11
|
+
return nil unless File.exist?(last_run_path)
|
12
|
+
JSON.parse(File.read(last_run_path))
|
13
|
+
end
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
def write(json)
|
16
|
+
File.open(last_run_path, "w+") do |f|
|
17
|
+
f.puts JSON.pretty_generate(json)
|
18
|
+
end
|
16
19
|
end
|
17
20
|
end
|
18
21
|
end
|
19
22
|
end
|
20
|
-
|
@@ -1,37 +1,36 @@
|
|
1
|
-
module SimpleCov
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
local_value = element || 0
|
15
|
-
other_value = new_array[i] || 0
|
16
|
-
new_array[i] = local_value + other_value
|
1
|
+
module SimpleCov
|
2
|
+
module ArrayMergeHelper
|
3
|
+
# Merges an array of coverage results with self
|
4
|
+
def merge_resultset(array)
|
5
|
+
new_array = dup
|
6
|
+
array.each_with_index do |element, i|
|
7
|
+
if element.nil? && new_array[i].nil?
|
8
|
+
new_array[i] = nil
|
9
|
+
else
|
10
|
+
local_value = element || 0
|
11
|
+
other_value = new_array[i] || 0
|
12
|
+
new_array[i] = local_value + other_value
|
13
|
+
end
|
17
14
|
end
|
15
|
+
new_array
|
18
16
|
end
|
19
|
-
new_array
|
20
17
|
end
|
21
18
|
end
|
22
19
|
|
23
|
-
module SimpleCov
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
20
|
+
module SimpleCov
|
21
|
+
module HashMergeHelper
|
22
|
+
# Merges the given Coverage.result hash with self
|
23
|
+
def merge_resultset(hash)
|
24
|
+
new_resultset = {}
|
25
|
+
(keys + hash.keys).each do |filename|
|
26
|
+
new_resultset[filename] = []
|
27
|
+
end
|
30
28
|
|
31
|
-
|
32
|
-
|
29
|
+
new_resultset.each_key do |filename|
|
30
|
+
new_resultset[filename] = (self[filename] || []).merge_resultset(hash[filename] || [])
|
31
|
+
end
|
32
|
+
new_resultset
|
33
33
|
end
|
34
|
-
new_resultset
|
35
34
|
end
|
36
35
|
end
|
37
36
|
|
@@ -1,2 +1,2 @@
|
|
1
|
-
ENV[
|
2
|
-
require
|
1
|
+
ENV["SIMPLECOV_NO_DEFAULTS"] = "yes, no defaults"
|
2
|
+
require "simplecov"
|
data/lib/simplecov/profiles.rb
CHANGED
@@ -5,25 +5,27 @@
|
|
5
5
|
# # SimpleCov configuration here, same as in SimpleCov.configure
|
6
6
|
# end
|
7
7
|
#
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
name
|
17
|
-
|
18
|
-
|
19
|
-
|
8
|
+
module SimpleCov
|
9
|
+
class Profiles < Hash
|
10
|
+
#
|
11
|
+
# Define a SimpleCov profile:
|
12
|
+
# SimpleCov.profiles.define 'rails' do
|
13
|
+
# # Same as SimpleCov.configure do .. here
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
def define(name, &blk)
|
17
|
+
name = name.to_sym
|
18
|
+
fail "SimpleCov Profile '#{name}' is already defined" unless self[name].nil?
|
19
|
+
self[name] = blk
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
#
|
23
|
+
# Applies the profile of given name on SimpleCov.configure
|
24
|
+
#
|
25
|
+
def load(name)
|
26
|
+
name = name.to_sym
|
27
|
+
fail "Could not find SimpleCov Profile called '#{name}'" unless key?(name)
|
28
|
+
SimpleCov.configure(&self[name])
|
29
|
+
end
|
28
30
|
end
|
29
31
|
end
|