simplecov 0.6.0 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +163 -80
  3. data/LICENSE +1 -1
  4. data/README.md +776 -277
  5. data/doc/alternate-formatters.md +71 -0
  6. data/doc/commercial-services.md +25 -0
  7. data/doc/editor-integration.md +18 -0
  8. data/lib/minitest/simplecov_plugin.rb +15 -0
  9. data/lib/simplecov/combine/branches_combiner.rb +32 -0
  10. data/lib/simplecov/combine/files_combiner.rb +24 -0
  11. data/lib/simplecov/combine/lines_combiner.rb +43 -0
  12. data/lib/simplecov/combine/results_combiner.rb +60 -0
  13. data/lib/simplecov/combine.rb +30 -0
  14. data/lib/simplecov/command_guesser.rb +53 -38
  15. data/lib/simplecov/configuration.rb +478 -193
  16. data/lib/simplecov/coverage_statistics.rb +56 -0
  17. data/lib/simplecov/default_formatter.rb +20 -0
  18. data/lib/simplecov/defaults.rb +40 -44
  19. data/lib/simplecov/exit_codes/exit_code_handling.rb +29 -0
  20. data/lib/simplecov/exit_codes/maximum_coverage_drop_check.rb +83 -0
  21. data/lib/simplecov/exit_codes/minimum_coverage_by_file_check.rb +54 -0
  22. data/lib/simplecov/exit_codes/minimum_overall_coverage_check.rb +53 -0
  23. data/lib/simplecov/exit_codes.rb +15 -0
  24. data/lib/simplecov/file_list.rb +112 -36
  25. data/lib/simplecov/filter.rb +54 -4
  26. data/lib/simplecov/formatter/multi_formatter.rb +32 -0
  27. data/lib/simplecov/formatter/simple_formatter.rb +21 -15
  28. data/lib/simplecov/formatter.rb +4 -1
  29. data/lib/simplecov/last_run.rb +28 -0
  30. data/lib/simplecov/lines_classifier.rb +48 -0
  31. data/lib/simplecov/load_global_config.rb +8 -0
  32. data/lib/simplecov/no_defaults.rb +4 -0
  33. data/lib/simplecov/process.rb +19 -0
  34. data/lib/simplecov/profiles/bundler_filter.rb +5 -0
  35. data/lib/simplecov/profiles/hidden_filter.rb +5 -0
  36. data/lib/simplecov/profiles/rails.rb +18 -0
  37. data/lib/simplecov/profiles/root_filter.rb +10 -0
  38. data/lib/simplecov/profiles/test_frameworks.rb +8 -0
  39. data/lib/simplecov/profiles.rb +35 -0
  40. data/lib/simplecov/result.rb +33 -64
  41. data/lib/simplecov/result_adapter.rb +30 -0
  42. data/lib/simplecov/result_merger.rb +178 -64
  43. data/lib/simplecov/simulate_coverage.rb +29 -0
  44. data/lib/simplecov/source_file/branch.rb +84 -0
  45. data/lib/simplecov/source_file/line.rb +72 -0
  46. data/lib/simplecov/source_file.rb +304 -123
  47. data/lib/simplecov/useless_results_remover.rb +18 -0
  48. data/lib/simplecov/version.rb +4 -2
  49. data/lib/simplecov.rb +396 -49
  50. metadata +81 -242
  51. data/.gitignore +0 -30
  52. data/.rvmrc +0 -1
  53. data/.travis.yml +0 -13
  54. data/Gemfile +0 -9
  55. data/Rakefile +0 -16
  56. data/cucumber.yml +0 -13
  57. data/features/config_adapters.feature +0 -44
  58. data/features/config_autoload.feature +0 -46
  59. data/features/config_command_name.feature +0 -33
  60. data/features/config_coverage_dir.feature +0 -20
  61. data/features/config_deactivate_merging.feature +0 -42
  62. data/features/config_merge_timeout.feature +0 -38
  63. data/features/config_nocov_token.feature +0 -79
  64. data/features/config_project_name.feature +0 -27
  65. data/features/config_styles.feature +0 -93
  66. data/features/cucumber_basic.feature +0 -29
  67. data/features/merging_test_unit_and_rspec.feature +0 -44
  68. data/features/rspec_basic.feature +0 -31
  69. data/features/rspec_fails_on_initialization.feature +0 -14
  70. data/features/rspec_groups_and_filters_basic.feature +0 -29
  71. data/features/rspec_groups_and_filters_complex.feature +0 -35
  72. data/features/rspec_groups_using_filter_class.feature +0 -40
  73. data/features/rspec_without_simplecov.feature +0 -20
  74. data/features/skipping_code_blocks_manually.feature +0 -70
  75. data/features/step_definitions/html_steps.rb +0 -45
  76. data/features/step_definitions/simplecov_steps.rb +0 -61
  77. data/features/step_definitions/transformers.rb +0 -13
  78. data/features/step_definitions/web_steps.rb +0 -64
  79. data/features/support/env.rb +0 -26
  80. data/features/test_unit_basic.feature +0 -34
  81. data/features/test_unit_groups_and_filters_basic.feature +0 -29
  82. data/features/test_unit_groups_and_filters_complex.feature +0 -35
  83. data/features/test_unit_groups_using_filter_class.feature +0 -40
  84. data/features/test_unit_without_simplecov.feature +0 -20
  85. data/features/unicode_compatiblity.feature +0 -67
  86. data/lib/simplecov/adapters.rb +0 -29
  87. data/lib/simplecov/merge_helpers.rb +0 -39
  88. data/lib/simplecov/railtie.rb +0 -7
  89. data/lib/simplecov/railties/tasks.rake +0 -11
  90. data/simplecov.gemspec +0 -28
  91. data/test/faked_project/Gemfile +0 -6
  92. data/test/faked_project/Rakefile +0 -8
  93. data/test/faked_project/cucumber.yml +0 -13
  94. data/test/faked_project/features/step_definitions/my_steps.rb +0 -23
  95. data/test/faked_project/features/support/env.rb +0 -12
  96. data/test/faked_project/features/test_stuff.feature +0 -6
  97. data/test/faked_project/lib/faked_project/framework_specific.rb +0 -18
  98. data/test/faked_project/lib/faked_project/meta_magic.rb +0 -24
  99. data/test/faked_project/lib/faked_project/some_class.rb +0 -29
  100. data/test/faked_project/lib/faked_project.rb +0 -11
  101. data/test/faked_project/spec/faked_spec.rb +0 -11
  102. data/test/faked_project/spec/meta_magic_spec.rb +0 -10
  103. data/test/faked_project/spec/some_class_spec.rb +0 -10
  104. data/test/faked_project/spec/spec_helper.rb +0 -15
  105. data/test/faked_project/test/faked_test.rb +0 -11
  106. data/test/faked_project/test/meta_magic_test.rb +0 -13
  107. data/test/faked_project/test/some_class_test.rb +0 -15
  108. data/test/faked_project/test/test_helper.rb +0 -16
  109. data/test/fixtures/app/controllers/sample_controller.rb +0 -10
  110. data/test/fixtures/app/models/user.rb +0 -10
  111. data/test/fixtures/deleted_source_sample.rb +0 -15
  112. data/test/fixtures/frameworks/rspec_bad.rb +0 -9
  113. data/test/fixtures/frameworks/rspec_good.rb +0 -9
  114. data/test/fixtures/frameworks/testunit_bad.rb +0 -9
  115. data/test/fixtures/frameworks/testunit_good.rb +0 -9
  116. data/test/fixtures/resultset1.rb +0 -4
  117. data/test/fixtures/resultset2.rb +0 -5
  118. data/test/fixtures/sample.rb +0 -16
  119. data/test/fixtures/utf-8.rb +0 -3
  120. data/test/helper.rb +0 -35
  121. data/test/shoulda_macros.rb +0 -29
  122. data/test/test_1_8_fallbacks.rb +0 -33
  123. data/test/test_command_guesser.rb +0 -21
  124. data/test/test_deleted_source.rb +0 -16
  125. data/test/test_file_list.rb +0 -24
  126. data/test/test_filters.rb +0 -80
  127. data/test/test_merge_helpers.rb +0 -107
  128. data/test/test_result.rb +0 -147
  129. data/test/test_return_codes.rb +0 -39
  130. data/test/test_source_file.rb +0 -86
  131. data/test/test_source_file_line.rb +0 -110
@@ -1,174 +1,355 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SimpleCov
2
4
  #
3
5
  # Representation of a source file including it's coverage data, source code,
4
6
  # source lines and featuring helpers to interpret that data.
5
7
  #
6
8
  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_method :source, :src
24
- alias_method :line, :line_number
25
- alias_method :number, :line_number
26
-
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?
31
- @src, @line_number, @coverage = src, line_number, coverage
32
- @skipped = false
33
- end
34
-
35
- # Returns true if this is a line that should have been covered, but was not
36
- def missed?
37
- not never? and not skipped? and coverage == 0
38
- end
39
-
40
- # Returns true if this is a line that has been covered
41
- def covered?
42
- not never? and not skipped? and coverage > 0
43
- end
44
-
45
- # Returns true if this line is not relevant for coverage
46
- def never?
47
- not skipped? and coverage.nil?
48
- end
49
-
50
- # Flags this line as skipped
51
- def skipped!
52
- @skipped = true
53
- end
54
-
55
- # Returns true if this line was skipped, false otherwise. Lines are skipped if they are wrapped with
56
- # # :nocov: comment lines.
57
- def skipped?
58
- !!skipped
59
- end
60
-
61
- # The status of this line - either covered, missed, skipped or never. Useful i.e. for direct use
62
- # as a css class in report generation
63
- def status
64
- return 'skipped' if skipped?
65
- return 'never' if never?
66
- return 'missed' if missed?
67
- return 'covered' if covered?
68
- end
69
- end
70
-
71
9
  # The full path to this source file (e.g. /User/colszowka/projects/simplecov/lib/simplecov/source_file.rb)
72
10
  attr_reader :filename
73
11
  # The array of coverage data received from the Coverage.result
74
- attr_reader :coverage
75
- # The source code for this file. Aliased as :source
76
- attr_reader :src
77
- alias_method :source, :src
12
+ attr_reader :coverage_data
78
13
 
79
- def initialize(filename, coverage)
80
- @filename, @coverage = filename, coverage
81
- File.open(filename, "r:UTF-8") {|f| @src = f.readlines }
14
+ def initialize(filename, coverage_data)
15
+ @filename = filename
16
+ @coverage_data = coverage_data
82
17
  end
83
18
 
84
- # Returns all source lines for this file as instances of SimpleCov::SourceFile::Line,
85
- # and thus including coverage data. Aliased as :source_lines
86
- def lines
87
- return @lines unless @lines.nil?
88
-
89
- # Warning to identify condition from Issue #56
90
- if coverage.size > src.size
91
- $stderr.puts "Warning: coverage data provided by Coverage [#{coverage.size}] exceeds number of lines in #{filename} [#{src.size}]"
92
- end
93
-
94
- # Initialize lines
95
- @lines = []
96
- src.each_with_index do |src, i|
97
- @lines << SimpleCov::SourceFile::Line.new(src, i+1, coverage[i])
98
- end
99
- process_skipped_lines!
100
- @lines
19
+ # The path to this source file relative to the projects directory
20
+ def project_filename
21
+ @filename.delete_prefix(SimpleCov.root)
101
22
  end
102
- alias_method :source_lines, :lines
103
23
 
104
- # Access SimpleCov::SourceFile::Line source lines by line number
105
- def line(number)
106
- lines[number-1]
24
+ # The source code for this file. Aliased as :source
25
+ def src
26
+ # We intentionally read source code lazily to
27
+ # suppress reading unused source code.
28
+ @src ||= load_source
107
29
  end
30
+ alias source src
108
31
 
109
- # The coverage for this file in percent. 0 if the file has no relevant lines
110
- def covered_percent
111
- return 100.0 if lines.length == 0 or lines.length == never_lines.count
112
- (covered_lines.count) * 100 / (lines.count - never_lines.count - skipped_lines.count).to_f
32
+ def coverage_statistics
33
+ @coverage_statistics ||=
34
+ {
35
+ **line_coverage_statistics,
36
+ **branch_coverage_statistics
37
+ }
113
38
  end
114
39
 
115
- def covered_strength
116
- return 0 if lines.length == 0 or lines.length == never_lines.count
117
- lines_strength = 0
118
- lines.each do |c|
119
- lines_strength += c.coverage if c.coverage
120
- end
121
- effective_lines_count = (lines.count - never_lines.count - skipped_lines.count).to_f
122
- strength = lines_strength / effective_lines_count
123
- round_float(strength, 1)
40
+ # Returns all source lines for this file as instances of SimpleCov::SourceFile::Line,
41
+ # and thus including coverage data. Aliased as :source_lines
42
+ def lines
43
+ @lines ||= build_lines
124
44
  end
45
+ alias source_lines lines
125
46
 
126
47
  # Returns all covered lines as SimpleCov::SourceFile::Line
127
48
  def covered_lines
128
- @covered_lines ||= lines.select {|c| c.covered? }
49
+ @covered_lines ||= lines.select(&:covered?)
129
50
  end
130
51
 
131
52
  # Returns all lines that should have been, but were not covered
132
53
  # as instances of SimpleCov::SourceFile::Line
133
54
  def missed_lines
134
- @missed_lines ||= lines.select {|c| c.missed? }
55
+ @missed_lines ||= lines.select(&:missed?)
135
56
  end
136
57
 
137
58
  # Returns all lines that are not relevant for coverage as
138
59
  # SimpleCov::SourceFile::Line instances
139
60
  def never_lines
140
- @never_lines ||= lines.select {|c| c.never? }
61
+ @never_lines ||= lines.select(&:never?)
141
62
  end
142
63
 
143
64
  # Returns all lines that were skipped as SimpleCov::SourceFile::Line instances
144
65
  def skipped_lines
145
- @skipped_lines ||= lines.select {|c| c.skipped? }
66
+ @skipped_lines ||= lines.select(&:skipped?)
146
67
  end
147
68
 
148
69
  # Returns the number of relevant lines (covered + missed)
149
70
  def lines_of_code
150
- covered_lines.count + missed_lines.count
71
+ coverage_statistics[:line]&.total
72
+ end
73
+
74
+ # Access SimpleCov::SourceFile::Line source lines by line number
75
+ def line(number)
76
+ lines[number - 1]
77
+ end
78
+
79
+ # The coverage for this file in percent. 0 if the file has no coverage lines
80
+ def covered_percent
81
+ coverage_statistics[:line]&.percent
82
+ end
83
+
84
+ def covered_strength
85
+ coverage_statistics[:line]&.strength
86
+ end
87
+
88
+ def no_lines?
89
+ lines.length.zero? || (lines.length == never_lines.size)
90
+ end
91
+
92
+ def relevant_lines
93
+ lines.size - never_lines.size - skipped_lines.size
94
+ end
95
+
96
+ #
97
+ # Return all the branches inside current source file
98
+ def branches
99
+ @branches ||= build_branches
100
+ end
101
+
102
+ def no_branches?
103
+ total_branches.empty?
104
+ end
105
+
106
+ def branches_coverage_percent
107
+ coverage_statistics[:branch]&.percent
108
+ end
109
+
110
+ #
111
+ # Return the relevant branches to source file
112
+ def total_branches
113
+ @total_branches ||= covered_branches + missed_branches
114
+ end
115
+
116
+ #
117
+ # Return hash with key of line number and branch coverage count as value
118
+ def branches_report
119
+ @branches_report ||= build_branches_report
120
+ end
121
+
122
+ #
123
+ # Select the covered branches
124
+ # Here we user tree schema because some conditions like case may have additional
125
+ # else that is not in declared inside the code but given by default by coverage report
126
+ #
127
+ # @return [Array]
128
+ #
129
+ def covered_branches
130
+ @covered_branches ||= branches.select(&:covered?)
131
+ end
132
+
133
+ #
134
+ # Select the missed branches with coverage equal to zero
135
+ #
136
+ # @return [Array]
137
+ #
138
+ def missed_branches
139
+ @missed_branches ||= branches.select(&:missed?)
140
+ end
141
+
142
+ def branches_for_line(line_number)
143
+ branches_report.fetch(line_number, [])
144
+ end
145
+
146
+ #
147
+ # Check if any branches missing on given line number
148
+ #
149
+ # @param [Integer] line_number
150
+ #
151
+ # @return [Boolean]
152
+ #
153
+ def line_with_missed_branch?(line_number)
154
+ branches_for_line(line_number).select { |_type, count| count.zero? }.any?
155
+ end
156
+
157
+ private
158
+
159
+ # no_cov_chunks is zero indexed to work directly with the array holding the lines
160
+ def no_cov_chunks
161
+ @no_cov_chunks ||= build_no_cov_chunks
162
+ end
163
+
164
+ def build_no_cov_chunks
165
+ no_cov_lines = src.map.with_index(1).select { |line_src, _index| LinesClassifier.no_cov_line?(line_src) }
166
+
167
+ # if we have an uneven number of nocovs we assume they go to the
168
+ # end of the file, the source doesn't really matter
169
+ # Can't deal with this within the each_slice due to differing
170
+ # behavior in JRuby: jruby/jruby#6048
171
+ no_cov_lines << ["", src.size] if no_cov_lines.size.odd?
172
+
173
+ no_cov_lines.each_slice(2).map do |(_line_src_start, index_start), (_line_src_end, index_end)|
174
+ index_start..index_end
175
+ end
176
+ end
177
+
178
+ def load_source
179
+ lines = []
180
+ # The default encoding is UTF-8
181
+ File.open(filename, "rb:UTF-8") do |file|
182
+ current_line = file.gets
183
+
184
+ if shebang?(current_line)
185
+ lines << current_line
186
+ current_line = file.gets
187
+ end
188
+
189
+ read_lines(file, lines, current_line)
190
+ end
151
191
  end
152
192
 
153
- # Will go through all source files and mark lines that are wrapped within # :nocov: comment blocks
154
- # as skipped.
155
- def process_skipped_lines!
156
- skipping = false
157
- lines.each do |line|
158
- if line.src =~ /^([\s]*)#([\s]*)(\:#{SimpleCov.nocov_token}\:)/
159
- skipping = !skipping
193
+ SHEBANG_REGEX = /\A#!/.freeze
194
+ def shebang?(line)
195
+ SHEBANG_REGEX.match?(line)
196
+ end
197
+
198
+ def read_lines(file, lines, current_line)
199
+ return lines unless current_line
200
+
201
+ set_encoding_based_on_magic_comment(file, current_line)
202
+ lines.concat([current_line], ensure_remove_undefs(file.readlines))
203
+ end
204
+
205
+ RUBY_FILE_ENCODING_MAGIC_COMMENT_REGEX = /\A#\s*(?:-\*-)?\s*(?:en)?coding:\s*(\S+)\s*(?:-\*-)?\s*\z/.freeze
206
+ def set_encoding_based_on_magic_comment(file, line)
207
+ # Check for encoding magic comment
208
+ # Encoding magic comment must be placed at first line except for shebang
209
+ if (match = RUBY_FILE_ENCODING_MAGIC_COMMENT_REGEX.match(line))
210
+ file.set_encoding(match[1], "UTF-8")
211
+ end
212
+ end
213
+
214
+ def ensure_remove_undefs(file_lines)
215
+ # invalid/undef replace are technically not really necessary but nice to
216
+ # have and work around a JRuby incompatibility. Also moved here from
217
+ # simplecov-html to have encoding shenaningans in one place. See #866
218
+ # also setting these option on `file.set_encoding` doesn't seem to work
219
+ # properly so it has to be done here.
220
+ file_lines.each do |line|
221
+ if line.encoding == Encoding::UTF_8
222
+ line
160
223
  else
161
- line.skipped! if skipping
224
+ line.encode!("UTF-8", invalid: :replace, undef: :replace)
162
225
  end
163
226
  end
164
227
  end
165
228
 
166
- private
229
+ def build_lines
230
+ coverage_exceeding_source_warn if coverage_data["lines"].size > src.size
231
+ lines = src.map.with_index(1) do |src, i|
232
+ SimpleCov::SourceFile::Line.new(src, i, coverage_data["lines"][i - 1])
233
+ end
234
+ process_skipped_lines(lines)
235
+ end
236
+
237
+ def process_skipped_lines(lines)
238
+ # the array the lines are kept in is 0-based whereas the line numbers in the nocov
239
+ # chunks are 1-based and are expected to be like this in other parts (and it's also
240
+ # arguably more understandable)
241
+ no_cov_chunks.each { |chunk| lines[(chunk.begin - 1)..(chunk.end - 1)].each(&:skipped!) }
242
+
243
+ lines
244
+ end
245
+
246
+ def lines_strength
247
+ lines.sum { |line| line.coverage.to_i }
248
+ end
249
+
250
+ # Warning to identify condition from Issue #56
251
+ def coverage_exceeding_source_warn
252
+ warn "Warning: coverage data provided by Coverage [#{coverage_data['lines'].size}] exceeds number of lines in #{filename} [#{src.size}]"
253
+ end
254
+
255
+ #
256
+ # Build full branches report
257
+ # Root branches represent the wrapper of all condition state that
258
+ # have inside the branches
259
+ #
260
+ # @return [Hash]
261
+ #
262
+ def build_branches_report
263
+ branches.reject(&:skipped?).each_with_object({}) do |branch, coverage_statistics|
264
+ coverage_statistics[branch.report_line] ||= []
265
+ coverage_statistics[branch.report_line] << branch.report
266
+ end
267
+ end
268
+
269
+ #
270
+ # Call recursive method that transform our static hash to array of objects
271
+ # @return [Array]
272
+ #
273
+ def build_branches
274
+ coverage_branch_data = coverage_data.fetch("branches", {})
275
+ branches = coverage_branch_data.flat_map do |condition, coverage_branches|
276
+ build_branches_from(condition, coverage_branches)
277
+ end
278
+
279
+ process_skipped_branches(branches)
280
+ end
281
+
282
+ def process_skipped_branches(branches)
283
+ return branches if no_cov_chunks.empty?
284
+
285
+ branches.each do |branch|
286
+ branch.skipped! if no_cov_chunks.any? { |no_cov_chunk| branch.overlaps_with?(no_cov_chunk) }
287
+ end
288
+
289
+ branches
290
+ end
291
+
292
+ # Since we are dumping to and loading from JSON, and we have arrays as keys those
293
+ # don't make their way back to us intact e.g. just as a string
294
+ #
295
+ # We should probably do something different here, but as it stands these are
296
+ # our data structures that we write so eval isn't _too_ bad.
297
+ #
298
+ # See #801
299
+ #
300
+ def restore_ruby_data_structure(structure)
301
+ # Tests use the real data structures (except for integration tests) so no need to
302
+ # put them through here.
303
+ return structure if structure.is_a?(Array)
304
+
305
+ # rubocop:disable Security/Eval
306
+ eval structure
307
+ # rubocop:enable Security/Eval
308
+ end
309
+
310
+ def build_branches_from(condition, branches)
311
+ # the format handed in from the coverage data is like this:
312
+ #
313
+ # [:then, 4, 6, 6, 6, 10]
314
+ #
315
+ # which is [type, id, start_line, start_col, end_line, end_col]
316
+ _condition_type, _condition_id, condition_start_line, * = restore_ruby_data_structure(condition)
317
+
318
+ branches.map do |branch_data, hit_count|
319
+ branch_data = restore_ruby_data_structure(branch_data)
320
+ build_branch(branch_data, hit_count, condition_start_line)
321
+ end
322
+ end
323
+
324
+ def build_branch(branch_data, hit_count, condition_start_line)
325
+ type, _id, start_line, _start_col, end_line, _end_col = branch_data
326
+
327
+ SourceFile::Branch.new(
328
+ start_line: start_line,
329
+ end_line: end_line,
330
+ coverage: hit_count,
331
+ inline: start_line == condition_start_line,
332
+ type: type
333
+ )
334
+ end
335
+
336
+ def line_coverage_statistics
337
+ {
338
+ line: CoverageStatistics.new(
339
+ total_strength: lines_strength,
340
+ covered: covered_lines.size,
341
+ missed: missed_lines.size
342
+ )
343
+ }
344
+ end
167
345
 
168
- # ruby 1.9 could use Float#round(places) instead
169
- def round_float(float, places)
170
- factor = (10 * places).to_f
171
- (float * factor).round / factor
346
+ def branch_coverage_statistics
347
+ {
348
+ branch: CoverageStatistics.new(
349
+ covered: covered_branches.size,
350
+ missed: missed_branches.size
351
+ )
352
+ }
172
353
  end
173
354
  end
174
355
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SimpleCov
4
+ #
5
+ # Select the files that related to working scope directory of SimpleCov
6
+ #
7
+ module UselessResultsRemover
8
+ def self.call(coverage_result)
9
+ coverage_result.select do |path, _coverage|
10
+ path =~ root_regx
11
+ end
12
+ end
13
+
14
+ def self.root_regx
15
+ @root_regx ||= /\A#{Regexp.escape(SimpleCov.root + File::SEPARATOR)}/i.freeze
16
+ end
17
+ end
18
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SimpleCov
2
- VERSION = "0.6.0"
3
- end
4
+ VERSION = "0.22.0"
5
+ end