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.
Files changed (78) hide show
  1. checksums.yaml +7 -7
  2. data/.gitignore +0 -1
  3. data/.rubocop.yml +69 -0
  4. data/CHANGELOG.md +39 -22
  5. data/Gemfile +16 -15
  6. data/MIT-LICENSE +1 -1
  7. data/README.md +183 -178
  8. data/Rakefile +16 -7
  9. data/doc/alternate-formatters.md +36 -0
  10. data/doc/commercial-services.md +20 -0
  11. data/doc/editor-integration.md +13 -0
  12. data/features/rspec_basic.feature +3 -2
  13. data/features/rspec_groups_and_filters_complex.feature +2 -0
  14. data/features/rspec_groups_using_filter_class.feature +3 -2
  15. data/features/step_definitions/html_steps.rb +6 -7
  16. data/features/step_definitions/simplecov_steps.rb +18 -16
  17. data/features/step_definitions/transformers.rb +2 -2
  18. data/features/step_definitions/web_steps.rb +4 -4
  19. data/features/support/env.rb +17 -15
  20. data/lib/simplecov.rb +35 -24
  21. data/lib/simplecov/command_guesser.rb +33 -34
  22. data/lib/simplecov/configuration.rb +238 -234
  23. data/lib/simplecov/defaults.rb +37 -36
  24. data/lib/simplecov/exit_codes.rb +7 -5
  25. data/lib/simplecov/file_list.rb +38 -36
  26. data/lib/simplecov/filter.rb +12 -2
  27. data/lib/simplecov/formatter.rb +2 -2
  28. data/lib/simplecov/formatter/simple_formatter.rb +1 -1
  29. data/lib/simplecov/jruby_fix.rb +4 -4
  30. data/lib/simplecov/last_run.rb +15 -13
  31. data/lib/simplecov/merge_helpers.rb +26 -27
  32. data/lib/simplecov/no_defaults.rb +2 -2
  33. data/lib/simplecov/profiles.rb +21 -19
  34. data/lib/simplecov/railtie.rb +1 -1
  35. data/lib/simplecov/railties/tasks.rake +7 -7
  36. data/lib/simplecov/result.rb +5 -5
  37. data/lib/simplecov/result_merger.rb +65 -62
  38. data/lib/simplecov/source_file.rb +23 -24
  39. data/lib/simplecov/version.rb +20 -1
  40. data/simplecov.gemspec +14 -12
  41. data/test/faked_project/Gemfile +5 -5
  42. data/test/faked_project/Rakefile +4 -4
  43. data/test/faked_project/features/step_definitions/my_steps.rb +3 -4
  44. data/test/faked_project/features/support/env.rb +5 -5
  45. data/test/faked_project/lib/faked_project.rb +1 -1
  46. data/test/faked_project/lib/faked_project/some_class.rb +3 -4
  47. data/test/faked_project/spec/faked_spec.rb +2 -2
  48. data/test/faked_project/spec/forking_spec.rb +7 -0
  49. data/test/faked_project/spec/meta_magic_spec.rb +1 -1
  50. data/test/faked_project/spec/some_class_spec.rb +3 -3
  51. data/test/faked_project/spec/spec_helper.rb +4 -8
  52. data/test/faked_project/test/faked_test.rb +2 -2
  53. data/test/faked_project/test/meta_magic_test.rb +1 -1
  54. data/test/faked_project/test/some_class_test.rb +3 -3
  55. data/test/faked_project/test/test_helper.rb +5 -9
  56. data/test/fixtures/app/controllers/sample_controller.rb +1 -1
  57. data/test/fixtures/app/models/user.rb +1 -1
  58. data/test/fixtures/deleted_source_sample.rb +3 -3
  59. data/test/fixtures/frameworks/rspec_bad.rb +4 -4
  60. data/test/fixtures/frameworks/rspec_good.rb +4 -4
  61. data/test/fixtures/frameworks/testunit_bad.rb +3 -3
  62. data/test/fixtures/frameworks/testunit_good.rb +3 -3
  63. data/test/fixtures/resultset2.rb +0 -1
  64. data/test/fixtures/sample.rb +1 -1
  65. data/test/fixtures/utf-8.rb +1 -1
  66. data/test/helper.rb +8 -8
  67. data/test/test_1_8_fallbacks.rb +6 -6
  68. data/test/test_command_guesser.rb +7 -7
  69. data/test/test_deleted_source.rb +2 -2
  70. data/test/test_file_list.rb +8 -6
  71. data/test/test_filters.rb +29 -13
  72. data/test/test_merge_helpers.rb +26 -23
  73. data/test/test_result.rb +32 -23
  74. data/test/test_return_codes.rb +3 -3
  75. data/test/test_source_file.rb +4 -4
  76. data/test/test_source_file_line.rb +13 -13
  77. metadata +145 -63
  78. data/lib/simplecov/json.rb +0 -27
@@ -1,11 +1,11 @@
1
- require 'rake/testtask'
1
+ require "rake/testtask"
2
2
  Rake::TestTask.new do |t|
3
- t.name = 'simplecov'
3
+ t.name = "simplecov"
4
4
  t.loader = :direct # uses require() which skips PWD in Ruby 1.9
5
- t.libs.push 'test', 'spec', Dir.pwd
6
- t.test_files = FileList['{test,spec}/**/*_{test,spec}.rb']
7
- t.ruby_opts.push '-r', 'simplecov', '-e', 'SimpleCov.start(:rails)'.inspect
5
+ t.libs.push "test", "spec", Dir.pwd
6
+ t.test_files = FileList["{test,spec}/**/*_{test,spec}.rb"]
7
+ t.ruby_opts.push "-r", "simplecov", "-e", "SimpleCov.start(:rails)".inspect
8
8
  end
9
9
 
10
- require 'rake/clean'
11
- CLOBBER.include 'coverage'
10
+ require "rake/clean"
11
+ CLOBBER.include "coverage"
@@ -1,5 +1,5 @@
1
- require 'digest/sha1'
2
- require 'forwardable'
1
+ require "digest/sha1"
2
+ require "forwardable"
3
3
 
4
4
  module SimpleCov
5
5
  #
@@ -57,9 +57,9 @@ module SimpleCov
57
57
  @command_name ||= SimpleCov.command_name
58
58
  end
59
59
 
60
- # Returns a hash representation of this Result that can be used for marshalling it into YAML
60
+ # Returns a hash representation of this Result that can be used for marshalling it into JSON
61
61
  def to_hash
62
- {command_name => {"coverage" => original_result.reject {|filename, result| !filenames.include?(filename) }, "timestamp" => created_at.to_i}}
62
+ {command_name => {"coverage" => original_result.reject { |filename, _| !filenames.include?(filename) }, "timestamp" => created_at.to_i}}
63
63
  end
64
64
 
65
65
  # Loads a SimpleCov::Result#to_hash dump
@@ -71,7 +71,7 @@ module SimpleCov
71
71
  result
72
72
  end
73
73
 
74
- private
74
+ private
75
75
 
76
76
  # Applies all configured SimpleCov filters on this result's source files
77
77
  def filter!
@@ -1,85 +1,88 @@
1
+ require "json"
2
+
1
3
  #
2
4
  # Singleton that is responsible for caching, loading and merging
3
5
  # SimpleCov::Results into a single result for coverage analysis based
4
6
  # upon multiple test suites.
5
7
  #
6
- module SimpleCov::ResultMerger
7
- class << self
8
- # The path to the .resultset.json cache file
9
- def resultset_path
10
- File.join(SimpleCov.coverage_path, '.resultset.json')
11
- end
8
+ module SimpleCov
9
+ module ResultMerger
10
+ class << self
11
+ # The path to the .resultset.json cache file
12
+ def resultset_path
13
+ File.join(SimpleCov.coverage_path, ".resultset.json")
14
+ end
12
15
 
13
- def resultset_writelock
14
- File.join(SimpleCov.coverage_path, '.resultset.json.lock')
15
- end
16
+ def resultset_writelock
17
+ File.join(SimpleCov.coverage_path, ".resultset.json.lock")
18
+ end
16
19
 
17
- # Loads the cached resultset from YAML and returns it as a Hash
18
- def resultset
19
- if stored_data
20
- begin
21
- SimpleCov::JSON.parse(stored_data)
22
- rescue
20
+ # Loads the cached resultset from JSON and returns it as a Hash
21
+ def resultset
22
+ if stored_data
23
+ begin
24
+ JSON.parse(stored_data)
25
+ rescue
26
+ {}
27
+ end
28
+ else
23
29
  {}
24
30
  end
25
- else
26
- {}
27
31
  end
28
- end
29
32
 
30
- # Returns the contents of the resultset cache as a string or if the file is missing or empty nil
31
- def stored_data
32
- if File.exist?(resultset_path) and stored_data = File.read(resultset_path) and stored_data.length >= 2
33
- stored_data
34
- else
35
- nil
33
+ # Returns the contents of the resultset cache as a string or if the file is missing or empty nil
34
+ def stored_data
35
+ return unless File.exist?(resultset_path)
36
+ data = File.read(resultset_path)
37
+ return if data.nil? || data.length < 2
38
+ data
36
39
  end
37
- end
38
40
 
39
- # Gets the resultset hash and re-creates all included instances
40
- # of SimpleCov::Result from that.
41
- # All results that are above the SimpleCov.merge_timeout will be
42
- # dropped. Returns an array of SimpleCov::Result items.
43
- def results
44
- results = []
45
- resultset.each do |command_name, data|
46
- result = SimpleCov::Result.from_hash(command_name => data)
47
- # Only add result if the timeout is above the configured threshold
48
- if (Time.now - result.created_at) < SimpleCov.merge_timeout
49
- results << result
41
+ # Gets the resultset hash and re-creates all included instances
42
+ # of SimpleCov::Result from that.
43
+ # All results that are above the SimpleCov.merge_timeout will be
44
+ # dropped. Returns an array of SimpleCov::Result items.
45
+ def results
46
+ results = []
47
+ resultset.each do |command_name, data|
48
+ result = SimpleCov::Result.from_hash(command_name => data)
49
+ # Only add result if the timeout is above the configured threshold
50
+ if (Time.now - result.created_at) < SimpleCov.merge_timeout
51
+ results << result
52
+ end
50
53
  end
54
+ results
51
55
  end
52
- results
53
- end
54
56
 
55
- #
56
- # Gets all SimpleCov::Results from cache, merges them and produces a new
57
- # SimpleCov::Result with merged coverage data and the command_name
58
- # for the result consisting of a join on all source result's names
59
- #
60
- def merged_result
61
- merged = {}
62
- results.each do |result|
63
- merged = result.original_result.merge_resultset(merged)
57
+ #
58
+ # Gets all SimpleCov::Results from cache, merges them and produces a new
59
+ # SimpleCov::Result with merged coverage data and the command_name
60
+ # for the result consisting of a join on all source result's names
61
+ #
62
+ def merged_result
63
+ merged = {}
64
+ results.each do |result|
65
+ merged = result.original_result.merge_resultset(merged)
66
+ end
67
+ result = SimpleCov::Result.new(merged)
68
+ # Specify the command name
69
+ result.command_name = results.map(&:command_name).sort.join(", ")
70
+ result
64
71
  end
65
- result = SimpleCov::Result.new(merged)
66
- # Specify the command name
67
- result.command_name = results.map(&:command_name).sort.join(", ")
68
- result
69
- end
70
72
 
71
- # Saves the given SimpleCov::Result in the resultset cache
72
- def store_result(result)
73
- File.open(resultset_writelock, "w+") do |f|
74
- f.flock(File::LOCK_EX)
75
- new_set = resultset
76
- command_name, data = result.to_hash.first
77
- new_set[command_name] = data
78
- File.open(resultset_path, "w+") do |f_|
79
- f_.puts SimpleCov::JSON.dump(new_set)
73
+ # Saves the given SimpleCov::Result in the resultset cache
74
+ def store_result(result)
75
+ File.open(resultset_writelock, "w+") do |f|
76
+ f.flock(File::LOCK_EX)
77
+ new_set = resultset
78
+ command_name, data = result.to_hash.first
79
+ new_set[command_name] = data
80
+ File.open(resultset_path, "w+") do |f_|
81
+ f_.puts JSON.pretty_generate(new_set)
82
+ end
80
83
  end
84
+ true
81
85
  end
82
- true
83
86
  end
84
87
  end
85
88
  end
@@ -25,26 +25,26 @@ module SimpleCov
25
25
  alias_method :number, :line_number
26
26
 
27
27
  def initialize(src, line_number, coverage)
28
- raise ArgumentError, "Only String accepted for source" unless src.kind_of?(String)
29
- raise ArgumentError, "Only Fixnum accepted for line_number" unless line_number.kind_of?(Fixnum)
30
- raise ArgumentError, "Only Fixnum and nil accepted for coverage" unless coverage.kind_of?(Fixnum) or coverage.nil?
28
+ fail ArgumentError, "Only String accepted for source" unless src.is_a?(String)
29
+ fail ArgumentError, "Only Fixnum accepted for line_number" unless line_number.is_a?(Fixnum)
30
+ fail ArgumentError, "Only Fixnum and nil accepted for coverage" unless coverage.is_a?(Fixnum) || coverage.nil?
31
31
  @src, @line_number, @coverage = src, line_number, coverage
32
32
  @skipped = false
33
33
  end
34
34
 
35
35
  # Returns true if this is a line that should have been covered, but was not
36
36
  def missed?
37
- not never? and not skipped? and coverage == 0
37
+ !never? && !skipped? && coverage.zero?
38
38
  end
39
39
 
40
40
  # Returns true if this is a line that has been covered
41
41
  def covered?
42
- not never? and not skipped? and coverage > 0
42
+ !never? && !skipped? && coverage > 0
43
43
  end
44
44
 
45
45
  # Returns true if this line is not relevant for coverage
46
46
  def never?
47
- not skipped? and coverage.nil?
47
+ !skipped? && coverage.nil?
48
48
  end
49
49
 
50
50
  # Flags this line as skipped
@@ -55,16 +55,16 @@ module SimpleCov
55
55
  # Returns true if this line was skipped, false otherwise. Lines are skipped if they are wrapped with
56
56
  # # :nocov: comment lines.
57
57
  def skipped?
58
- !!skipped
58
+ !!skipped
59
59
  end
60
60
 
61
61
  # The status of this line - either covered, missed, skipped or never. Useful i.e. for direct use
62
62
  # as a css class in report generation
63
63
  def status
64
- return 'skipped' if skipped?
65
- return 'never' if never?
66
- return 'missed' if missed?
67
- return 'covered' if covered?
64
+ return "skipped" if skipped?
65
+ return "never" if never?
66
+ return "missed" if missed?
67
+ return "covered" if covered?
68
68
  end
69
69
  end
70
70
 
@@ -78,7 +78,7 @@ module SimpleCov
78
78
 
79
79
  def initialize(filename, coverage)
80
80
  @filename, @coverage = filename, coverage
81
- File.open(filename, "rb") {|f| @src = f.readlines }
81
+ File.open(filename, "rb") { |f| @src = f.readlines }
82
82
  end
83
83
 
84
84
  # Returns all source lines for this file as instances of SimpleCov::SourceFile::Line,
@@ -94,7 +94,7 @@ module SimpleCov
94
94
  # Initialize lines
95
95
  @lines = []
96
96
  src.each_with_index do |src, i|
97
- @lines << SimpleCov::SourceFile::Line.new(src, i+1, coverage[i])
97
+ @lines << SimpleCov::SourceFile::Line.new(src, i + 1, coverage[i])
98
98
  end
99
99
  process_skipped_lines!
100
100
  @lines
@@ -103,14 +103,14 @@ module SimpleCov
103
103
 
104
104
  # Access SimpleCov::SourceFile::Line source lines by line number
105
105
  def line(number)
106
- lines[number-1]
106
+ lines[number - 1]
107
107
  end
108
108
 
109
109
  # The coverage for this file in percent. 0 if the file has no relevant lines
110
110
  def covered_percent
111
- return 100.0 if lines.length == 0 or lines.length == never_lines.count
111
+ return 100.0 if lines.length.zero? || lines.length == never_lines.count
112
112
  relevant_lines = lines.count - never_lines.count - skipped_lines.count
113
- if relevant_lines == 0
113
+ if relevant_lines.zero?
114
114
  0.0
115
115
  else
116
116
  Float((covered_lines.count) * 100.0 / relevant_lines.to_f)
@@ -118,7 +118,7 @@ module SimpleCov
118
118
  end
119
119
 
120
120
  def covered_strength
121
- return 0.0 if lines.length == 0 or lines.length == never_lines.count
121
+ return 0.0 if lines.length.zero? || lines.length == never_lines.count
122
122
 
123
123
  lines_strength = 0
124
124
  lines.each do |c|
@@ -127,7 +127,7 @@ module SimpleCov
127
127
 
128
128
  effective_lines_count = Float(lines.count - never_lines.count - skipped_lines.count)
129
129
 
130
- if effective_lines_count == 0
130
+ if effective_lines_count.zero?
131
131
  0.0
132
132
  else
133
133
  strength = lines_strength / effective_lines_count
@@ -137,24 +137,24 @@ module SimpleCov
137
137
 
138
138
  # Returns all covered lines as SimpleCov::SourceFile::Line
139
139
  def covered_lines
140
- @covered_lines ||= lines.select {|c| c.covered? }
140
+ @covered_lines ||= lines.select(&:covered?)
141
141
  end
142
142
 
143
143
  # Returns all lines that should have been, but were not covered
144
144
  # as instances of SimpleCov::SourceFile::Line
145
145
  def missed_lines
146
- @missed_lines ||= lines.select {|c| c.missed? }
146
+ @missed_lines ||= lines.select(&:missed?)
147
147
  end
148
148
 
149
149
  # Returns all lines that are not relevant for coverage as
150
150
  # SimpleCov::SourceFile::Line instances
151
151
  def never_lines
152
- @never_lines ||= lines.select {|c| c.never? }
152
+ @never_lines ||= lines.select(&:never?)
153
153
  end
154
154
 
155
155
  # Returns all lines that were skipped as SimpleCov::SourceFile::Line instances
156
156
  def skipped_lines
157
- @skipped_lines ||= lines.select {|c| c.skipped? }
157
+ @skipped_lines ||= lines.select(&:skipped?)
158
158
  end
159
159
 
160
160
  # Returns the number of relevant lines (covered + missed)
@@ -175,7 +175,7 @@ module SimpleCov
175
175
  end
176
176
  end
177
177
 
178
- private
178
+ private
179
179
 
180
180
  # ruby 1.9 could use Float#round(places) instead
181
181
  # @return [Float]
@@ -185,4 +185,3 @@ module SimpleCov
185
185
  end
186
186
  end
187
187
  end
188
-
@@ -1,3 +1,22 @@
1
1
  module SimpleCov
2
- VERSION = "0.9.2"
2
+ VERSION = "0.10.0"
3
+ def VERSION.to_a
4
+ split(".").map(&:to_i)
5
+ end
6
+
7
+ def VERSION.major
8
+ to_a[0]
9
+ end
10
+
11
+ def VERSION.minor
12
+ to_a[1]
13
+ end
14
+
15
+ def VERSION.patch
16
+ to_a[2]
17
+ end
18
+
19
+ def VERSION.pre
20
+ to_a[3]
21
+ end
3
22
  end
@@ -1,25 +1,27 @@
1
- # encoding: utf-8
2
- $:.push File.expand_path('../lib', __FILE__)
3
- require 'simplecov/version'
1
+ $LOAD_PATH.push File.expand_path("../lib", __FILE__)
2
+ require "simplecov/version"
4
3
 
5
4
  Gem::Specification.new do |gem|
6
- gem.name = 'simplecov'
5
+ gem.name = "simplecov"
7
6
  gem.version = SimpleCov::VERSION
8
7
  gem.platform = Gem::Platform::RUBY
9
8
  gem.authors = ["Christoph Olszowka"]
10
- gem.email = ['christoph at olszowka de']
11
- gem.homepage = 'http://github.com/colszowka/simplecov'
12
- gem.description = %Q{Code coverage for Ruby 1.9+ with a powerful configuration library and automatic merging of coverage across test suites}
9
+ gem.email = ["christoph at olszowka de"]
10
+ gem.homepage = "http://github.com/colszowka/simplecov"
11
+ gem.description = %(Code coverage for Ruby 1.9+ with a powerful configuration library and automatic merging of coverage across test suites)
13
12
  gem.summary = gem.description
14
13
  gem.license = "MIT"
15
14
 
16
15
  gem.required_ruby_version = ">= 1.8.7"
17
- gem.add_dependency 'multi_json', '~> 1.0'
18
- gem.add_dependency 'simplecov-html', '~> 0.9.0'
19
- gem.add_dependency 'docile', '~> 1.1.0'
16
+
17
+ gem.add_dependency "json", "~> 1.8"
18
+ gem.add_dependency "simplecov-html", "~> 0.10.0"
19
+ gem.add_dependency "docile", "~> 1.1.0"
20
+
21
+ gem.add_development_dependency "bundler", "~> 1.9"
20
22
 
21
23
  gem.files = `git ls-files`.split("\n")
22
24
  gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
- gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
- gem.require_paths = ['lib']
25
+ gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
26
+ gem.require_paths = ["lib"]
25
27
  end
@@ -1,6 +1,6 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
- gem 'simplecov', :path => '../../../'
4
- gem 'rake'
5
- gem 'rspec', '>= 2.6.0'
6
- gem 'cucumber'
3
+ gem "simplecov", :path => "../../../"
4
+ gem "rake"
5
+ gem "rspec", ">= 2.6.0"
6
+ gem "cucumber"
@@ -1,8 +1,8 @@
1
- require 'bundler'
1
+ require "bundler"
2
2
 
3
- require 'rake/testtask'
3
+ require "rake/testtask"
4
4
  Rake::TestTask.new(:test) do |test|
5
- test.libs << 'lib' << 'test'
6
- test.test_files = FileList['test/**/*_test.rb'].sort
5
+ test.libs << "lib" << "test"
6
+ test.test_files = FileList["test/**/*_test.rb"].sort
7
7
  test.verbose = true
8
8
  end
@@ -7,7 +7,7 @@ When /^I write my cukes for the fake project$/ do
7
7
  end
8
8
 
9
9
  Then /^I make all neccessary tests in a single step$/ do
10
- expect(FakedProject.foo).to eq('bar')
10
+ expect(FakedProject.foo).to eq("bar")
11
11
 
12
12
  expect(FrameworkSpecific.cucumber).to eq("Only tested in Cucumber")
13
13
 
@@ -17,7 +17,6 @@ Then /^I make all neccessary tests in a single step$/ do
17
17
  expect(FakedProject.new.dynamic).to eq("A dynamically defined instance method")
18
18
 
19
19
  something = SomeClass.new("foo")
20
- expect(something.reverse).to eq('oof')
21
- expect(something.compare_with('foo')).to be true
20
+ expect(something.reverse).to eq("oof")
21
+ expect(something.compare_with("foo")).to be true
22
22
  end
23
-