simplecov-patched 0.14.2

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 (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