simplecov-patched 0.14.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +31 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +88 -0
  5. data/.travis.yml +29 -0
  6. data/.yardopts +1 -0
  7. data/CHANGELOG.md +435 -0
  8. data/CONTRIBUTING.md +48 -0
  9. data/Gemfile +38 -0
  10. data/MIT-LICENSE +20 -0
  11. data/README.md +646 -0
  12. data/Rakefile +41 -0
  13. data/cucumber.yml +13 -0
  14. data/doc/alternate-formatters.md +36 -0
  15. data/doc/commercial-services.md +20 -0
  16. data/doc/editor-integration.md +13 -0
  17. data/features/config_autoload.feature +46 -0
  18. data/features/config_command_name.feature +45 -0
  19. data/features/config_coverage_dir.feature +33 -0
  20. data/features/config_deactivate_merging.feature +42 -0
  21. data/features/config_formatters.feature +77 -0
  22. data/features/config_merge_timeout.feature +39 -0
  23. data/features/config_nocov_token.feature +79 -0
  24. data/features/config_profiles.feature +44 -0
  25. data/features/config_project_name.feature +27 -0
  26. data/features/config_styles.feature +121 -0
  27. data/features/config_tracked_files.feature +29 -0
  28. data/features/cucumber_basic.feature +29 -0
  29. data/features/maximum_coverage_drop.feature +89 -0
  30. data/features/merging_test_unit_and_rspec.feature +44 -0
  31. data/features/minimum_coverage.feature +59 -0
  32. data/features/refuse_coverage_drop.feature +95 -0
  33. data/features/rspec_basic.feature +32 -0
  34. data/features/rspec_fails_on_initialization.feature +14 -0
  35. data/features/rspec_groups_and_filters_basic.feature +29 -0
  36. data/features/rspec_groups_and_filters_complex.feature +37 -0
  37. data/features/rspec_groups_using_filter_class.feature +41 -0
  38. data/features/rspec_without_simplecov.feature +20 -0
  39. data/features/skipping_code_blocks_manually.feature +70 -0
  40. data/features/step_definitions/html_steps.rb +44 -0
  41. data/features/step_definitions/simplecov_steps.rb +68 -0
  42. data/features/step_definitions/transformers.rb +13 -0
  43. data/features/step_definitions/web_steps.rb +64 -0
  44. data/features/support/env.rb +50 -0
  45. data/features/test_unit_basic.feature +34 -0
  46. data/features/test_unit_groups_and_filters_basic.feature +29 -0
  47. data/features/test_unit_groups_and_filters_complex.feature +35 -0
  48. data/features/test_unit_groups_using_filter_class.feature +40 -0
  49. data/features/test_unit_without_simplecov.feature +20 -0
  50. data/features/unicode_compatiblity.feature +67 -0
  51. data/lib/simplecov.rb +189 -0
  52. data/lib/simplecov/command_guesser.rb +59 -0
  53. data/lib/simplecov/configuration.rb +307 -0
  54. data/lib/simplecov/defaults.rb +121 -0
  55. data/lib/simplecov/exit_codes.rb +8 -0
  56. data/lib/simplecov/file_list.rb +59 -0
  57. data/lib/simplecov/filter.rb +54 -0
  58. data/lib/simplecov/formatter.rb +8 -0
  59. data/lib/simplecov/formatter/multi_formatter.rb +32 -0
  60. data/lib/simplecov/formatter/simple_formatter.rb +23 -0
  61. data/lib/simplecov/jruby_fix.rb +42 -0
  62. data/lib/simplecov/last_run.rb +24 -0
  63. data/lib/simplecov/load_global_config.rb +6 -0
  64. data/lib/simplecov/no_defaults.rb +2 -0
  65. data/lib/simplecov/profiles.rb +31 -0
  66. data/lib/simplecov/railtie.rb +7 -0
  67. data/lib/simplecov/railties/tasks.rake +11 -0
  68. data/lib/simplecov/raw_coverage.rb +39 -0
  69. data/lib/simplecov/result.rb +86 -0
  70. data/lib/simplecov/result_merger.rb +95 -0
  71. data/lib/simplecov/source_file.rb +196 -0
  72. data/lib/simplecov/version.rb +25 -0
  73. data/spec/1_8_fallbacks_spec.rb +31 -0
  74. data/spec/command_guesser_spec.rb +48 -0
  75. data/spec/config_loader_spec.rb +14 -0
  76. data/spec/configuration_spec.rb +35 -0
  77. data/spec/deleted_source_spec.rb +12 -0
  78. data/spec/faked_project/Gemfile +6 -0
  79. data/spec/faked_project/Rakefile +8 -0
  80. data/spec/faked_project/cucumber.yml +13 -0
  81. data/spec/faked_project/features/step_definitions/my_steps.rb +22 -0
  82. data/spec/faked_project/features/support/env.rb +12 -0
  83. data/spec/faked_project/features/test_stuff.feature +6 -0
  84. data/spec/faked_project/lib/faked_project.rb +11 -0
  85. data/spec/faked_project/lib/faked_project/framework_specific.rb +18 -0
  86. data/spec/faked_project/lib/faked_project/meta_magic.rb +24 -0
  87. data/spec/faked_project/lib/faked_project/some_class.rb +28 -0
  88. data/spec/faked_project/lib/faked_project/untested_class.rb +11 -0
  89. data/spec/faked_project/spec/faked_spec.rb +11 -0
  90. data/spec/faked_project/spec/forking_spec.rb +8 -0
  91. data/spec/faked_project/spec/meta_magic_spec.rb +15 -0
  92. data/spec/faked_project/spec/some_class_spec.rb +13 -0
  93. data/spec/faked_project/spec/spec_helper.rb +11 -0
  94. data/spec/faked_project/test/faked_test.rb +11 -0
  95. data/spec/faked_project/test/meta_magic_test.rb +13 -0
  96. data/spec/faked_project/test/some_class_test.rb +15 -0
  97. data/spec/faked_project/test/test_helper.rb +12 -0
  98. data/spec/file_list_spec.rb +50 -0
  99. data/spec/filters_spec.rb +98 -0
  100. data/spec/fixtures/app/controllers/sample_controller.rb +10 -0
  101. data/spec/fixtures/app/models/user.rb +10 -0
  102. data/spec/fixtures/deleted_source_sample.rb +15 -0
  103. data/spec/fixtures/frameworks/rspec_bad.rb +9 -0
  104. data/spec/fixtures/frameworks/rspec_good.rb +9 -0
  105. data/spec/fixtures/frameworks/testunit_bad.rb +9 -0
  106. data/spec/fixtures/frameworks/testunit_good.rb +9 -0
  107. data/spec/fixtures/iso-8859.rb +3 -0
  108. data/spec/fixtures/never.rb +2 -0
  109. data/spec/fixtures/resultset1.rb +4 -0
  110. data/spec/fixtures/resultset2.rb +4 -0
  111. data/spec/fixtures/sample.rb +16 -0
  112. data/spec/fixtures/skipped.rb +4 -0
  113. data/spec/fixtures/skipped_and_executed.rb +8 -0
  114. data/spec/fixtures/utf-8.rb +3 -0
  115. data/spec/helper.rb +26 -0
  116. data/spec/last_run_spec.rb +48 -0
  117. data/spec/multi_formatter_spec.rb +20 -0
  118. data/spec/raw_coverage_spec.rb +92 -0
  119. data/spec/result_merger_spec.rb +96 -0
  120. data/spec/result_spec.rb +209 -0
  121. data/spec/return_codes_spec.rb +34 -0
  122. data/spec/simplecov_spec.rb +110 -0
  123. data/spec/source_file_line_spec.rb +155 -0
  124. data/spec/source_file_spec.rb +141 -0
  125. data/spec/support/fail_rspec_on_ruby_warning.rb +75 -0
  126. metadata +320 -0
@@ -0,0 +1,95 @@
1
+ require "json"
2
+
3
+ #
4
+ # Singleton that is responsible for caching, loading and merging
5
+ # SimpleCov::Results into a single result for coverage analysis based
6
+ # upon multiple test suites.
7
+ #
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
15
+
16
+ def resultset_writelock
17
+ File.join(SimpleCov.coverage_path, ".resultset.json.lock")
18
+ end
19
+
20
+ # Loads the cached resultset from JSON and returns it as a Hash,
21
+ # caching it for subsequent accesses.
22
+ def resultset(force_reload = false)
23
+ @resultset = nil if force_reload
24
+
25
+ @resultset ||= if (data = stored_data)
26
+ begin
27
+ JSON.parse(data) || {}
28
+ rescue
29
+ {}
30
+ end
31
+ else
32
+ {}
33
+ end
34
+ end
35
+
36
+ # Returns the contents of the resultset cache as a string or if the file is missing or empty nil
37
+ def stored_data
38
+ return unless File.exist?(resultset_path)
39
+ data = File.read(resultset_path)
40
+ return if data.nil? || data.length < 2
41
+ data
42
+ end
43
+
44
+ # Gets the resultset hash and re-creates all included instances
45
+ # of SimpleCov::Result from that.
46
+ # All results that are above the SimpleCov.merge_timeout will be
47
+ # dropped. Returns an array of SimpleCov::Result items.
48
+ def results
49
+ results = []
50
+ resultset.each do |command_name, data|
51
+ result = SimpleCov::Result.from_hash(command_name => data)
52
+ # Only add result if the timeout is above the configured threshold
53
+ if (Time.now - result.created_at) < SimpleCov.merge_timeout
54
+ results << result
55
+ end
56
+ end
57
+ results
58
+ end
59
+
60
+ # Merge two or more SimpleCov::Results into a new one with merged
61
+ # coverage data and the command_name for the result consisting of a join
62
+ # on all source result's names
63
+ def merge_results(*results)
64
+ merged = SimpleCov::RawCoverage.merge_results(*results.map(&:original_result))
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
+
71
+ #
72
+ # Gets all SimpleCov::Results from cache, merges them and produces a new
73
+ # SimpleCov::Result with merged coverage data and the command_name
74
+ # for the result consisting of a join on all source result's names
75
+ #
76
+ def merged_result
77
+ merge_results(*results)
78
+ end
79
+
80
+ # Saves the given SimpleCov::Result in the resultset cache
81
+ def store_result(result)
82
+ File.open(resultset_writelock, "w+") do |f|
83
+ f.flock(File::LOCK_EX)
84
+ new_set = resultset(true)
85
+ command_name, data = result.to_hash.first
86
+ new_set[command_name] = data
87
+ File.open(resultset_path, "w+") do |f_|
88
+ f_.puts JSON.pretty_generate(new_set)
89
+ end
90
+ end
91
+ true
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,196 @@
1
+ module SimpleCov
2
+ #
3
+ # Representation of a source file including it's coverage data, source code,
4
+ # source lines and featuring helpers to interpret that data.
5
+ #
6
+ class SourceFile
7
+ # Representation of a single line in a source file including
8
+ # this specific line's source code, line_number and code coverage,
9
+ # with the coverage being either nil (coverage not applicable, e.g. comment
10
+ # line), 0 (line not covered) or >1 (the amount of times the line was
11
+ # executed)
12
+ class Line
13
+ # The source code for this line. Aliased as :source
14
+ attr_reader :src
15
+ # The line number in the source file. Aliased as :line, :number
16
+ attr_reader :line_number
17
+ # The coverage data for this line: either nil (never), 0 (missed) or >=1 (times covered)
18
+ attr_reader :coverage
19
+ # Whether this line was skipped
20
+ attr_reader :skipped
21
+
22
+ # Lets grab some fancy aliases, shall we?
23
+ alias source src
24
+ alias line line_number
25
+ alias number line_number
26
+
27
+ def initialize(src, line_number, coverage)
28
+ raise ArgumentError, "Only String accepted for source" unless src.is_a?(String)
29
+ raise ArgumentError, "Only Integer accepted for line_number" unless line_number.is_a?(Integer)
30
+ raise ArgumentError, "Only Integer and nil accepted for coverage" unless coverage.is_a?(Integer) || coverage.nil?
31
+ @src = src
32
+ @line_number = line_number
33
+ @coverage = coverage
34
+ @skipped = false
35
+ end
36
+
37
+ # Returns true if this is a line that should have been covered, but was not
38
+ def missed?
39
+ !never? && !skipped? && coverage.zero?
40
+ end
41
+
42
+ # Returns true if this is a line that has been covered
43
+ def covered?
44
+ !never? && !skipped? && coverage > 0
45
+ end
46
+
47
+ # Returns true if this line is not relevant for coverage
48
+ def never?
49
+ !skipped? && coverage.nil?
50
+ end
51
+
52
+ # Flags this line as skipped
53
+ def skipped!
54
+ @skipped = true
55
+ end
56
+
57
+ # Returns true if this line was skipped, false otherwise. Lines are skipped if they are wrapped with
58
+ # # :nocov: comment lines.
59
+ def skipped?
60
+ !!skipped
61
+ end
62
+
63
+ # The status of this line - either covered, missed, skipped or never. Useful i.e. for direct use
64
+ # as a css class in report generation
65
+ def status
66
+ return "skipped" if skipped?
67
+ return "never" if never?
68
+ return "missed" if missed?
69
+ return "covered" if covered?
70
+ end
71
+ end
72
+
73
+ # The full path to this source file (e.g. /User/colszowka/projects/simplecov/lib/simplecov/source_file.rb)
74
+ attr_reader :filename
75
+ # The array of coverage data received from the Coverage.result
76
+ attr_reader :coverage
77
+
78
+ def initialize(filename, coverage)
79
+ @filename = filename
80
+ @coverage = coverage
81
+ end
82
+
83
+ # The source code for this file. Aliased as :source
84
+ def src
85
+ # We intentionally read source code lazily to
86
+ # suppress reading unused source code.
87
+ @src ||= File.open(filename, "rb", &:readlines)
88
+ end
89
+ alias source src
90
+
91
+ # Returns all source lines for this file as instances of SimpleCov::SourceFile::Line,
92
+ # and thus including coverage data. Aliased as :source_lines
93
+ def lines
94
+ @lines ||= build_lines
95
+ end
96
+ alias source_lines lines
97
+
98
+ def build_lines
99
+ coverage_exceeding_source_warn if coverage.size > src.size
100
+
101
+ lines = src.map.with_index(1) do |src, i|
102
+ SimpleCov::SourceFile::Line.new(src, i, coverage[i - 1])
103
+ end
104
+
105
+ process_skipped_lines(lines)
106
+ end
107
+
108
+ # Warning to identify condition from Issue #56
109
+ def coverage_exceeding_source_warn
110
+ $stderr.puts "Warning: coverage data provided by Coverage [#{coverage.size}] exceeds number of lines in #{filename} [#{src.size}]"
111
+ end
112
+
113
+ # Access SimpleCov::SourceFile::Line source lines by line number
114
+ def line(number)
115
+ lines[number - 1]
116
+ end
117
+
118
+ # The coverage for this file in percent. 0 if the file has no relevant lines
119
+ def covered_percent
120
+ return 100.0 if no_lines?
121
+
122
+ return 0.0 if relevant_lines.zero?
123
+
124
+ Float(covered_lines.size * 100.0 / relevant_lines.to_f)
125
+ end
126
+
127
+ def covered_strength
128
+ return 0.0 if relevant_lines.zero?
129
+
130
+ round_float(lines_strength / relevant_lines.to_f, 1)
131
+ end
132
+
133
+ def no_lines?
134
+ lines.length.zero? || (lines.length == never_lines.size)
135
+ end
136
+
137
+ def lines_strength
138
+ lines.map(&:coverage).compact.reduce(:+)
139
+ end
140
+
141
+ def relevant_lines
142
+ lines.size - never_lines.size - skipped_lines.size
143
+ end
144
+
145
+ # Returns all covered lines as SimpleCov::SourceFile::Line
146
+ def covered_lines
147
+ @covered_lines ||= lines.select(&:covered?)
148
+ end
149
+
150
+ # Returns all lines that should have been, but were not covered
151
+ # as instances of SimpleCov::SourceFile::Line
152
+ def missed_lines
153
+ @missed_lines ||= lines.select(&:missed?)
154
+ end
155
+
156
+ # Returns all lines that are not relevant for coverage as
157
+ # SimpleCov::SourceFile::Line instances
158
+ def never_lines
159
+ @never_lines ||= lines.select(&:never?)
160
+ end
161
+
162
+ # Returns all lines that were skipped as SimpleCov::SourceFile::Line instances
163
+ def skipped_lines
164
+ @skipped_lines ||= lines.select(&:skipped?)
165
+ end
166
+
167
+ # Returns the number of relevant lines (covered + missed)
168
+ def lines_of_code
169
+ covered_lines.size + missed_lines.size
170
+ end
171
+
172
+ # Will go through all source files and mark lines that are wrapped within # :nocov: comment blocks
173
+ # as skipped.
174
+ def process_skipped_lines(lines)
175
+ skipping = false
176
+
177
+ lines.each do |line|
178
+ if line.src =~ /^([\s]*)#([\s]*)(\:#{SimpleCov.nocov_token}\:)/
179
+ skipping = !skipping
180
+ line.skipped!
181
+ elsif skipping
182
+ line.skipped!
183
+ end
184
+ end
185
+ end
186
+
187
+ private
188
+
189
+ # ruby 1.9 could use Float#round(places) instead
190
+ # @return [Float]
191
+ def round_float(float, places)
192
+ factor = Float(10 * places)
193
+ Float((float * factor).round / factor)
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,25 @@
1
+ module SimpleCov
2
+ version = "0.14.2"
3
+
4
+ def version.to_a
5
+ split(".").map(&:to_i)
6
+ end
7
+
8
+ def version.major
9
+ to_a[0]
10
+ end
11
+
12
+ def version.minor
13
+ to_a[1]
14
+ end
15
+
16
+ def version.patch
17
+ to_a[2]
18
+ end
19
+
20
+ def version.pre
21
+ to_a[3]
22
+ end
23
+
24
+ VERSION = version
25
+ end
@@ -0,0 +1,31 @@
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
+ if RUBY_VERSION.start_with? "1.8"
10
+ describe "Ruby 1.8 fallback" do
11
+ it "return false when calling SimpleCov.start" do
12
+ expect(SimpleCov.start).to be false
13
+ end
14
+
15
+ it "return false when calling SimpleCov.start with a block" do
16
+ expect(SimpleCov.start { raise "Shouldn't reach this!" }).to be false
17
+ end
18
+
19
+ it "return false when calling SimpleCov.configure with a block" do
20
+ expect(SimpleCov.configure { raise "Shouldn't reach this!" }).to be false
21
+ end
22
+
23
+ it "allow to define a profile" do
24
+ expect do
25
+ SimpleCov.profiles.define "testprofile" do
26
+ add_filter "/config/"
27
+ end
28
+ end.not_to raise_error
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,48 @@
1
+ require "helper"
2
+
3
+ if SimpleCov.usable?
4
+ describe SimpleCov::CommandGuesser do
5
+ subject { SimpleCov::CommandGuesser }
6
+ it 'correctly guesses "Unit Tests" for unit tests' do
7
+ subject.original_run_command = "/some/path/test/units/foo_bar_test.rb"
8
+ expect(subject.guess).to eq("Unit Tests")
9
+ subject.original_run_command = "test/units/foo.rb"
10
+ expect(subject.guess).to eq("Unit Tests")
11
+ subject.original_run_command = "test/foo.rb"
12
+ expect(subject.guess).to eq("Unit Tests")
13
+ subject.original_run_command = "test/{models,helpers,unit}/**/*_test.rb"
14
+ expect(subject.guess).to eq("Unit Tests")
15
+ end
16
+
17
+ it 'correctly guesses "Functional Tests" for functional tests' do
18
+ subject.original_run_command = "/some/path/test/functional/foo_bar_controller_test.rb"
19
+ expect(subject.guess).to eq("Functional Tests")
20
+ subject.original_run_command = "test/{controllers,mailers,functional}/**/*_test.rb"
21
+ expect(subject.guess).to eq("Functional Tests")
22
+ end
23
+
24
+ it 'correctly guesses "Integration Tests" for integration tests' do
25
+ subject.original_run_command = "/some/path/test/integration/foo_bar_controller_test.rb"
26
+ expect(subject.guess).to eq("Integration Tests")
27
+ subject.original_run_command = "test/integration/**/*_test.rb"
28
+ expect(subject.guess).to eq("Integration Tests")
29
+ end
30
+
31
+ it 'correctly guesses "Cucumber Features" for cucumber features' do
32
+ subject.original_run_command = "features"
33
+ expect(subject.guess).to eq("Cucumber Features")
34
+ subject.original_run_command = "cucumber"
35
+ expect(subject.guess).to eq("Cucumber Features")
36
+ end
37
+
38
+ it 'correctly guesses "RSpec" for RSpec' do
39
+ subject.original_run_command = "/some/path/spec/foo.rb"
40
+ expect(subject.guess).to eq("RSpec")
41
+ end
42
+
43
+ it "defaults to RSpec because RSpec constant is defined" do
44
+ subject.original_run_command = "some_arbitrary_command with arguments"
45
+ expect(subject.guess).to eq("RSpec")
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,14 @@
1
+ require "helper"
2
+
3
+ describe "loading config" do
4
+ context "without ENV[HOME]" do
5
+ it "shouldn't raise any errors" do
6
+ home = ENV.delete("HOME")
7
+ begin
8
+ expect { load "simplecov/load_global_config.rb" }.not_to raise_error
9
+ ensure
10
+ ENV["HOME"] = home
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,35 @@
1
+ require "helper"
2
+
3
+ describe SimpleCov::Configuration do
4
+ let(:config_class) do
5
+ Class.new do
6
+ include SimpleCov::Configuration
7
+ end
8
+ end
9
+ let(:config) { config_class.new }
10
+
11
+ describe "#tracked_files" do
12
+ context "when configured" do
13
+ let(:glob) { "{app,lib}/**/*.rb" }
14
+ before { config.track_files(glob) }
15
+
16
+ it "returns the configured glob" do
17
+ expect(config.tracked_files).to eq glob
18
+ end
19
+
20
+ context "and configured again with nil" do
21
+ before { config.track_files(nil) }
22
+
23
+ it "returns nil" do
24
+ expect(config.tracked_files).to be_nil
25
+ end
26
+ end
27
+ end
28
+
29
+ context "when unconfigured" do
30
+ it "returns nil" do
31
+ expect(config.tracked_files).to be_nil
32
+ end
33
+ end
34
+ end
35
+ end