simplecov 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +7 -7
  2. data/.rspec +3 -1
  3. data/.rubocop.yml +6 -5
  4. data/CHANGELOG.md +16 -2
  5. data/Gemfile +14 -14
  6. data/README.md +28 -12
  7. data/Rakefile +5 -8
  8. data/features/config_formatters.feature +1 -1
  9. data/features/config_tracked_files.feature +29 -0
  10. data/features/step_definitions/transformers.rb +1 -1
  11. data/features/support/env.rb +6 -3
  12. data/lib/simplecov.rb +19 -2
  13. data/lib/simplecov/configuration.rb +24 -4
  14. data/lib/simplecov/defaults.rb +28 -5
  15. data/lib/simplecov/file_list.rb +11 -0
  16. data/lib/simplecov/filter.rb +1 -1
  17. data/lib/simplecov/formatter/multi_formatter.rb +17 -13
  18. data/lib/simplecov/result.rb +1 -1
  19. data/lib/simplecov/source_file.rb +6 -3
  20. data/lib/simplecov/version.rb +1 -1
  21. data/spec/1_8_fallbacks_spec.rb +29 -0
  22. data/spec/command_guesser_spec.rb +46 -0
  23. data/spec/deleted_source_spec.rb +12 -0
  24. data/{test → spec}/faked_project/Gemfile +0 -0
  25. data/{test → spec}/faked_project/Rakefile +0 -0
  26. data/{test → spec}/faked_project/cucumber.yml +0 -0
  27. data/{test → spec}/faked_project/features/step_definitions/my_steps.rb +0 -0
  28. data/{test → spec}/faked_project/features/support/env.rb +0 -0
  29. data/{test → spec}/faked_project/features/test_stuff.feature +0 -0
  30. data/{test → spec}/faked_project/lib/faked_project.rb +1 -1
  31. data/{test → spec}/faked_project/lib/faked_project/framework_specific.rb +0 -0
  32. data/{test → spec}/faked_project/lib/faked_project/meta_magic.rb +0 -0
  33. data/{test → spec}/faked_project/lib/faked_project/some_class.rb +0 -0
  34. data/spec/faked_project/lib/faked_project/untested_class.rb +11 -0
  35. data/{test → spec}/faked_project/spec/faked_spec.rb +0 -0
  36. data/{test → spec}/faked_project/spec/forking_spec.rb +0 -0
  37. data/{test → spec}/faked_project/spec/meta_magic_spec.rb +0 -0
  38. data/{test → spec}/faked_project/spec/some_class_spec.rb +0 -0
  39. data/{test → spec}/faked_project/spec/spec_helper.rb +0 -0
  40. data/{test → spec}/faked_project/test/faked_test.rb +0 -0
  41. data/{test → spec}/faked_project/test/meta_magic_test.rb +0 -0
  42. data/{test → spec}/faked_project/test/some_class_test.rb +0 -0
  43. data/{test → spec}/faked_project/test/test_helper.rb +0 -0
  44. data/spec/file_list_spec.rb +48 -0
  45. data/spec/filters_spec.rb +96 -0
  46. data/{test → spec}/fixtures/app/controllers/sample_controller.rb +0 -0
  47. data/{test → spec}/fixtures/app/models/user.rb +0 -0
  48. data/{test → spec}/fixtures/deleted_source_sample.rb +0 -0
  49. data/{test → spec}/fixtures/frameworks/rspec_bad.rb +0 -0
  50. data/{test → spec}/fixtures/frameworks/rspec_good.rb +0 -0
  51. data/{test → spec}/fixtures/frameworks/testunit_bad.rb +0 -0
  52. data/{test → spec}/fixtures/frameworks/testunit_good.rb +0 -0
  53. data/{test → spec}/fixtures/iso-8859.rb +0 -0
  54. data/{test → spec}/fixtures/resultset1.rb +0 -0
  55. data/{test → spec}/fixtures/resultset2.rb +0 -0
  56. data/{test → spec}/fixtures/sample.rb +0 -0
  57. data/{test → spec}/fixtures/utf-8.rb +0 -0
  58. data/{test → spec}/helper.rb +3 -7
  59. data/spec/merge_helpers_spec.rb +108 -0
  60. data/spec/result_spec.rb +207 -0
  61. data/spec/return_codes_spec.rb +37 -0
  62. data/spec/source_file_line_spec.rb +153 -0
  63. data/spec/source_file_spec.rb +75 -0
  64. metadata +163 -149
  65. data/test/shoulda_macros.rb +0 -19
  66. data/test/test_1_8_fallbacks.rb +0 -31
  67. data/test/test_command_guesser.rb +0 -19
  68. data/test/test_deleted_source.rb +0 -14
  69. data/test/test_file_list.rb +0 -23
  70. data/test/test_filters.rb +0 -94
  71. data/test/test_merge_helpers.rb +0 -112
  72. data/test/test_result.rb +0 -175
  73. data/test/test_return_codes.rb +0 -41
  74. data/test/test_source_file.rb +0 -73
  75. data/test/test_source_file_line.rb +0 -106
@@ -26,6 +26,17 @@ module SimpleCov
26
26
  map { |f| f.skipped_lines.count }.inject(&:+)
27
27
  end
28
28
 
29
+ # Computes the coverage based upon lines covered and lines missed for each file
30
+ # Returns an array with all coverage percentages
31
+ def covered_percentages
32
+ map(&:covered_percent)
33
+ end
34
+
35
+ # Finds the least covered file and returns that file's name
36
+ def least_covered_file
37
+ sort_by(&:covered_percent).first.filename
38
+ end
39
+
29
40
  # Returns the overall amount of relevant lines of code across all files in this list
30
41
  def lines_of_code
31
42
  covered_lines + missed_lines
@@ -21,7 +21,7 @@ module SimpleCov
21
21
  end
22
22
 
23
23
  def passes?(source_file)
24
- warn "DEPRECATION: SimpleCov::Filter#passes?(x) has been renamed to #matches?. Please update your custom filters accordingly!"
24
+ warn "#{Kernel.caller.first}: [DEPRECATION] #passes? is deprecated. Use #matches? instead."
25
25
  matches?(source_file)
26
26
  end
27
27
  end
@@ -1,27 +1,31 @@
1
1
  module SimpleCov
2
2
  module Formatter
3
3
  class MultiFormatter
4
- def self.[](*args)
5
- Class.new(self) do
6
- define_method :formatters do
7
- @formatters ||= args
4
+ module InstanceMethods
5
+ def format(result)
6
+ formatters.map do |formatter|
7
+ begin
8
+ formatter.new.format(result)
9
+ rescue => e
10
+ STDERR.puts("Formatter #{formatter} failed with #{e.class}: #{e.message} (#{e.backtrace.first})")
11
+ nil
12
+ end
8
13
  end
9
14
  end
10
15
  end
11
16
 
12
- def format(result)
13
- formatters.map do |formatter|
14
- begin
15
- formatter.new.format(result)
16
- rescue => e
17
- STDERR.puts("Formatter #{formatter} failed with #{e.class}: #{e.message} (#{e.backtrace.first})")
18
- nil
17
+ def self.new(formatters = nil)
18
+ Class.new do
19
+ define_method :formatters do
20
+ @formatters ||= Array(formatters)
19
21
  end
22
+ include InstanceMethods
20
23
  end
21
24
  end
22
25
 
23
- def formatters
24
- @formatters ||= []
26
+ def self.[](*args)
27
+ warn "#{Kernel.caller.first}: [DEPRECATION] ::[] is deprecated. Use ::new instead."
28
+ new(*args)
25
29
  end
26
30
  end
27
31
  end
@@ -18,7 +18,7 @@ module SimpleCov
18
18
  # Explicitly set the command name that was used for this coverage result. Defaults to SimpleCov.command_name
19
19
  attr_writer :command_name
20
20
 
21
- def_delegators :files, :covered_percent, :covered_strength, :covered_lines, :missed_lines
21
+ def_delegators :files, :covered_percent, :covered_percentages, :least_covered_file, :covered_strength, :covered_lines, :missed_lines
22
22
  def_delegator :files, :lines_of_code, :total_lines
23
23
 
24
24
  # Initialize a new SimpleCov::Result from given Coverage.result (a Hash of filenames each containing an array of
@@ -28,8 +28,10 @@ module SimpleCov
28
28
  fail ArgumentError, "Only String accepted for source" unless src.is_a?(String)
29
29
  fail ArgumentError, "Only Fixnum accepted for line_number" unless line_number.is_a?(Fixnum)
30
30
  fail ArgumentError, "Only Fixnum and nil accepted for coverage" unless coverage.is_a?(Fixnum) || coverage.nil?
31
- @src, @line_number, @coverage = src, line_number, coverage
32
- @skipped = false
31
+ @src = src
32
+ @line_number = line_number
33
+ @coverage = coverage
34
+ @skipped = false
33
35
  end
34
36
 
35
37
  # Returns true if this is a line that should have been covered, but was not
@@ -77,7 +79,8 @@ module SimpleCov
77
79
  alias_method :source, :src
78
80
 
79
81
  def initialize(filename, coverage)
80
- @filename, @coverage = filename, coverage
82
+ @filename = filename
83
+ @coverage = coverage
81
84
  File.open(filename, "rb") { |f| @src = f.readlines }
82
85
  end
83
86
 
@@ -1,5 +1,5 @@
1
1
  module SimpleCov
2
- VERSION = "0.10.0"
2
+ VERSION = "0.11.0"
3
3
  def VERSION.to_a
4
4
  split(".").map(&:to_i)
5
5
  end
@@ -0,0 +1,29 @@
1
+ require "helper"
2
+
3
+ # Tests that verify that on 1.8 versions of ruby, simplecov simply
4
+ # does not launch and does not cause errors on the way
5
+ #
6
+ # TODO: This should be expanded upon all methods that could potentially
7
+ # be called in a test/spec-helper simplecov config block
8
+ #
9
+ describe "Ruby 1.8 fallback" do
10
+ it "return false when calling SimpleCov.start" do
11
+ expect(SimpleCov.start).to be false
12
+ end
13
+
14
+ it "return false when calling SimpleCov.start with a block" do
15
+ expect(SimpleCov.start { fail "Shouldn't reach this!" }).to be false
16
+ end
17
+
18
+ it "return false when calling SimpleCov.configure with a block" do
19
+ expect(SimpleCov.configure { fail "Shouldn't reach this!" }).to be false
20
+ end
21
+
22
+ it "allow to define a profile" do
23
+ expect do
24
+ SimpleCov.profiles.define "testprofile" do
25
+ add_filter "/config/"
26
+ end
27
+ end.not_to raise_error
28
+ end
29
+ end if RUBY_VERSION.start_with? "1.8"
@@ -0,0 +1,46 @@
1
+ require "helper"
2
+
3
+ describe SimpleCov::CommandGuesser do
4
+ subject { SimpleCov::CommandGuesser }
5
+ it 'correctly guesses "Unit Tests" for unit tests' do
6
+ subject.original_run_command = "/some/path/test/units/foo_bar_test.rb"
7
+ expect(subject.guess).to eq("Unit Tests")
8
+ subject.original_run_command = "test/units/foo.rb"
9
+ expect(subject.guess).to eq("Unit Tests")
10
+ subject.original_run_command = "test/foo.rb"
11
+ expect(subject.guess).to eq("Unit Tests")
12
+ subject.original_run_command = "test/{models,helpers,unit}/**/*_test.rb"
13
+ expect(subject.guess).to eq("Unit Tests")
14
+ end
15
+
16
+ it 'correctly guesses "Functional Tests" for functional tests' do
17
+ subject.original_run_command = "/some/path/test/functional/foo_bar_controller_test.rb"
18
+ expect(subject.guess).to eq("Functional Tests")
19
+ subject.original_run_command = "test/{controllers,mailers,functional}/**/*_test.rb"
20
+ expect(subject.guess).to eq("Functional Tests")
21
+ end
22
+
23
+ it 'correctly guesses "Integration Tests" for integration tests' do
24
+ subject.original_run_command = "/some/path/test/integration/foo_bar_controller_test.rb"
25
+ expect(subject.guess).to eq("Integration Tests")
26
+ subject.original_run_command = "test/integration/**/*_test.rb"
27
+ expect(subject.guess).to eq("Integration Tests")
28
+ end
29
+
30
+ it 'correctly guesses "Cucumber Features" for cucumber features' do
31
+ subject.original_run_command = "features"
32
+ expect(subject.guess).to eq("Cucumber Features")
33
+ subject.original_run_command = "cucumber"
34
+ expect(subject.guess).to eq("Cucumber Features")
35
+ end
36
+
37
+ it 'correctly guesses "RSpec" for RSpec' do
38
+ subject.original_run_command = "/some/path/spec/foo.rb"
39
+ expect(subject.guess).to eq("RSpec")
40
+ end
41
+
42
+ it "defaults to RSpec because RSpec constant is defined" do
43
+ subject.original_run_command = "some_arbitrary_command with arguments"
44
+ expect(subject.guess).to eq("RSpec")
45
+ end
46
+ end if SimpleCov.usable?
@@ -0,0 +1,12 @@
1
+ require "helper"
2
+
3
+ # Test to verify correct handling of deleted files
4
+ # See https://github.com/colszowka/simplecov/issues/9
5
+ describe "A source file which is subsequently deleted" do
6
+ it "does not cause an error" do
7
+ Dir.chdir(File.join(File.dirname(__FILE__), "fixtures")) do
8
+ `ruby deleted_source_sample.rb`
9
+ expect($?.exitstatus).to be_zero
10
+ end
11
+ end
12
+ end
File without changes
File without changes
@@ -4,7 +4,7 @@ class FakedProject
4
4
  end
5
5
  end
6
6
 
7
- Dir[File.join(File.dirname(__FILE__), "faked_project/*.rb")].each do |file|
7
+ Dir[File.join(File.dirname(__FILE__), "faked_project/*.rb")].reject { |f| /untested/.match(f) }.each do |file|
8
8
  require file # Require all source files in project dynamically so we can inject some stuff depending on test situation
9
9
  end
10
10
 
@@ -0,0 +1,11 @@
1
+ class UntestedClass
2
+ def initialize(yogurts)
3
+ @yogurts = yogurts
4
+ end
5
+
6
+ def power_level
7
+ @yogurts.map do |yo|
8
+ yo.experience_points**2
9
+ end.reduce(0, &:+)
10
+ end
11
+ end
@@ -0,0 +1,48 @@
1
+ require "helper"
2
+
3
+ describe SimpleCov::Result do
4
+ subject do
5
+ original_result = {
6
+ source_fixture("sample.rb") => [nil, 1, 1, 1, nil, nil, 1, 1, nil, nil],
7
+ source_fixture("app/models/user.rb") => [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil],
8
+ source_fixture("app/controllers/sample_controller.rb") => [nil, 2, 2, 0, nil, nil, 0, nil, nil, nil],
9
+ }
10
+ SimpleCov::Result.new(original_result).files
11
+ end
12
+
13
+ it "has 11 covered lines" do
14
+ expect(subject.covered_lines).to eq(11)
15
+ end
16
+
17
+ it "has 3 missed lines" do
18
+ expect(subject.missed_lines).to eq(3)
19
+ end
20
+
21
+ it "has 19 never lines" do
22
+ expect(subject.never_lines).to eq(19)
23
+ end
24
+
25
+ it "has 14 lines of code" do
26
+ expect(subject.lines_of_code).to eq(14)
27
+ end
28
+
29
+ it "has 3 skipped lines" do
30
+ expect(subject.skipped_lines).to eq(3)
31
+ end
32
+
33
+ it "has the correct covered percent" do
34
+ expect(subject.covered_percent).to eq(78.57142857142857)
35
+ end
36
+
37
+ it "has the correct covered percentages" do
38
+ expect(subject.covered_percentages).to eq([50.0, 80.0, 100.0])
39
+ end
40
+
41
+ it "has the correct least covered file" do
42
+ expect(subject.least_covered_file).to match(/sample_controller.rb/)
43
+ end
44
+
45
+ it "has the correct covered strength" do
46
+ expect(subject.covered_strength).to eq(0.9285714285714286)
47
+ end
48
+ end if SimpleCov.usable?
@@ -0,0 +1,96 @@
1
+ require "helper"
2
+
3
+ describe SimpleCov::SourceFile do
4
+ subject do
5
+ SimpleCov::SourceFile.new(source_fixture("sample.rb"), [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil])
6
+ end
7
+
8
+ it "doesn't match a new SimpleCov::StringFilter 'foobar'" do
9
+ expect(SimpleCov::StringFilter.new("foobar")).not_to be_matches subject
10
+ end
11
+
12
+ it "doesn't match a new SimpleCov::StringFilter 'some/path'" do
13
+ expect(SimpleCov::StringFilter.new("some/path")).not_to be_matches subject
14
+ end
15
+
16
+ it "matches a new SimpleCov::StringFilter 'spec/fixtures'" do
17
+ expect(SimpleCov::StringFilter.new("spec/fixtures")).to be_matches subject
18
+ end
19
+
20
+ it "matches a new SimpleCov::StringFilter 'spec/fixtures/sample.rb'" do
21
+ expect(SimpleCov::StringFilter.new("spec/fixtures/sample.rb")).to be_matches subject
22
+ end
23
+
24
+ it "matches a new SimpleCov::StringFilter 'sample.rb'" do
25
+ expect(SimpleCov::StringFilter.new("sample.rb")).to be_matches subject
26
+ end
27
+
28
+ it "doesn't match a new SimpleCov::BlockFilter that is not applicable" do
29
+ expect(SimpleCov::BlockFilter.new(proc { |s| File.basename(s.filename) == "foo.rb" })).not_to be_matches subject
30
+ end
31
+
32
+ it "matches a new SimpleCov::BlockFilter that is applicable" do
33
+ expect(SimpleCov::BlockFilter.new(proc { |s| File.basename(s.filename) == "sample.rb" })).to be_matches subject
34
+ end
35
+
36
+ it "matches a new SimpleCov::ArrayFilter when 'sample.rb' is passed as array" do
37
+ expect(SimpleCov::ArrayFilter.new(["sample.rb"])).to be_matches subject
38
+ end
39
+
40
+ it "doesn't match a new SimpleCov::ArrayFilter when a file path different than 'sample.rb' is passed as array" do
41
+ expect(SimpleCov::ArrayFilter.new(["other_file.rb"])).not_to be_matches subject
42
+ end
43
+
44
+ it "matches a new SimpleCov::ArrayFilter when two file paths including 'sample.rb' are passed as array" do
45
+ expect(SimpleCov::ArrayFilter.new(["sample.rb", "other_file.rb"])).to be_matches subject
46
+ end
47
+
48
+ context "with no filters set up and a basic source file in an array" do
49
+ before do
50
+ @prev_filters = SimpleCov.filters
51
+ SimpleCov.filters = []
52
+ end
53
+
54
+ subject do
55
+ [SimpleCov::SourceFile.new(source_fixture("sample.rb"), [nil, 1, 1, 1, nil, nil, 1, 0, nil, nil])]
56
+ end
57
+
58
+ after do
59
+ SimpleCov.filters = @prev_filters
60
+ end
61
+
62
+ it 'returns 0 items after executing SimpleCov.filtered on files when using a "sample" string filter' do
63
+ SimpleCov.add_filter "sample"
64
+ expect(SimpleCov.filtered(subject).count).to be_zero
65
+ end
66
+
67
+ it 'returns 0 items after executing SimpleCov.filtered on files when using a "spec/fixtures" string filter' do
68
+ SimpleCov.add_filter "spec/fixtures"
69
+ expect(SimpleCov.filtered(subject).count).to be_zero
70
+ end
71
+
72
+ it 'returns 1 item after executing SimpleCov.filtered on files when using a "fooo" string filter' do
73
+ SimpleCov.add_filter "fooo"
74
+ expect(SimpleCov.filtered(subject).count).to eq(1)
75
+ end
76
+
77
+ it "returns 0 items after executing SimpleCov.filtered on files when using a block filter that returns true" do
78
+ SimpleCov.add_filter do
79
+ true
80
+ end
81
+ expect(SimpleCov.filtered(subject).count).to be_zero
82
+ end
83
+
84
+ it "returns 1 item after executing SimpleCov.filtered on files when using an always-false block filter" do
85
+ SimpleCov.add_filter do
86
+ false
87
+ end
88
+ expect(SimpleCov.filtered(subject).count).to eq(1)
89
+ end
90
+
91
+ it "returns a FileList after filtering" do
92
+ SimpleCov.add_filter "fooo"
93
+ expect(SimpleCov.filtered(subject)).to be_a SimpleCov::FileList
94
+ end
95
+ end
96
+ end if SimpleCov.usable?
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,7 +1,5 @@
1
- require "bundler/setup"
2
1
  require "simplecov"
3
- require "minitest/autorun"
4
- require "shoulda"
2
+ require "rspec"
5
3
 
6
4
  SimpleCov.coverage_dir("tmp/coverage")
7
5
 
@@ -9,9 +7,6 @@ def source_fixture(filename)
9
7
  File.expand_path(File.join(File.dirname(__FILE__), "fixtures", filename))
10
8
  end
11
9
 
12
- require "shoulda_macros"
13
- Minitest::Test.send :extend, ShouldaMacros
14
-
15
10
  # Taken from http://stackoverflow.com/questions/4459330/how-do-i-temporarily-redirect-stderr-in-ruby
16
11
  require "stringio"
17
12
 
@@ -19,7 +14,8 @@ def capture_stderr
19
14
  # The output stream must be an IO-like object. In this case we capture it in
20
15
  # an in-memory IO object so we can return the string value. You can assign any
21
16
  # IO object here.
22
- previous_stderr, $stderr = $stderr, StringIO.new
17
+ previous_stderr = $stderr
18
+ $stderr = StringIO.new
23
19
  yield
24
20
  $stderr.string
25
21
  ensure