simplecov 0.17.1 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +111 -427
  3. data/README.md +388 -94
  4. data/doc/alternate-formatters.md +16 -1
  5. data/doc/commercial-services.md +5 -0
  6. data/lib/minitest/simplecov_plugin.rb +15 -0
  7. data/lib/simplecov/combine/branches_combiner.rb +32 -0
  8. data/lib/simplecov/combine/files_combiner.rb +24 -0
  9. data/lib/simplecov/combine/lines_combiner.rb +43 -0
  10. data/lib/simplecov/combine/results_combiner.rb +60 -0
  11. data/lib/simplecov/combine.rb +30 -0
  12. data/lib/simplecov/command_guesser.rb +6 -3
  13. data/lib/simplecov/configuration.rb +210 -15
  14. data/lib/simplecov/coverage_statistics.rb +56 -0
  15. data/lib/simplecov/default_formatter.rb +20 -0
  16. data/lib/simplecov/defaults.rb +14 -13
  17. data/lib/simplecov/exit_codes/exit_code_handling.rb +29 -0
  18. data/lib/simplecov/exit_codes/maximum_coverage_drop_check.rb +83 -0
  19. data/lib/simplecov/exit_codes/minimum_coverage_by_file_check.rb +54 -0
  20. data/lib/simplecov/exit_codes/minimum_overall_coverage_check.rb +53 -0
  21. data/lib/simplecov/exit_codes.rb +5 -0
  22. data/lib/simplecov/file_list.rb +72 -13
  23. data/lib/simplecov/filter.rb +9 -6
  24. data/lib/simplecov/formatter/multi_formatter.rb +5 -7
  25. data/lib/simplecov/formatter/simple_formatter.rb +4 -4
  26. data/lib/simplecov/formatter.rb +2 -2
  27. data/lib/simplecov/last_run.rb +3 -1
  28. data/lib/simplecov/lines_classifier.rb +5 -5
  29. data/lib/simplecov/no_defaults.rb +1 -1
  30. data/lib/simplecov/process.rb +19 -0
  31. data/lib/simplecov/profiles.rb +9 -7
  32. data/lib/simplecov/result.rb +18 -12
  33. data/lib/simplecov/result_adapter.rb +30 -0
  34. data/lib/simplecov/result_merger.rb +130 -59
  35. data/lib/simplecov/simulate_coverage.rb +29 -0
  36. data/lib/simplecov/source_file/branch.rb +84 -0
  37. data/lib/simplecov/source_file/line.rb +72 -0
  38. data/lib/simplecov/source_file.rb +279 -127
  39. data/lib/simplecov/useless_results_remover.rb +18 -0
  40. data/lib/simplecov/version.rb +1 -1
  41. data/lib/simplecov.rb +296 -128
  42. metadata +47 -161
  43. data/CONTRIBUTING.md +0 -51
  44. data/ISSUE_TEMPLATE.md +0 -23
  45. data/lib/simplecov/jruby_fix.rb +0 -44
  46. data/lib/simplecov/railtie.rb +0 -9
  47. data/lib/simplecov/railties/tasks.rake +0 -13
  48. data/lib/simplecov/raw_coverage.rb +0 -41
data/lib/simplecov.rb CHANGED
@@ -2,29 +2,31 @@
2
2
 
3
3
  require "English"
4
4
 
5
- #
6
- # Code coverage for ruby 1.9. Please check out README for a full introduction.
7
- #
8
5
  # Coverage may be inaccurate under JRUBY.
9
- if defined?(JRUBY_VERSION) && defined?(JRuby)
6
+ if defined?(JRUBY_VERSION) && defined?(JRuby) && !org.jruby.RubyInstanceConfig.FULL_TRACE_ENABLED
10
7
 
11
8
  # @see https://github.com/jruby/jruby/issues/1196
12
9
  # @see https://github.com/metricfu/metric_fu/pull/226
13
- # @see https://github.com/colszowka/simplecov/issues/420
14
- # @see https://github.com/colszowka/simplecov/issues/86
10
+ # @see https://github.com/simplecov-ruby/simplecov/issues/420
11
+ # @see https://github.com/simplecov-ruby/simplecov/issues/86
15
12
  # @see https://jira.codehaus.org/browse/JRUBY-6106
16
13
 
17
- unless org.jruby.RubyInstanceConfig.FULL_TRACE_ENABLED
18
- warn 'Coverage may be inaccurate; set the "--debug" command line option,' \
19
- ' or do JRUBY_OPTS="--debug"' \
20
- ' or set the "debug.fullTrace=true" option in your .jrubyrc'
21
- end
14
+ warn 'Coverage may be inaccurate; set the "--debug" command line option,' \
15
+ ' or do JRUBY_OPTS="--debug"' \
16
+ ' or set the "debug.fullTrace=true" option in your .jrubyrc'
22
17
  end
18
+
19
+ #
20
+ # Code coverage for ruby. Please check out README for a full introduction.
21
+ #
23
22
  module SimpleCov
24
23
  class << self
25
- attr_accessor :running
26
- attr_accessor :pid
27
- attr_reader :exit_exception
24
+ attr_accessor :running, :pid
25
+
26
+ # Basically, should we take care of at_exit behavior or something else?
27
+ # Used by the minitest plugin. See lib/minitest/simplecov_plugin.rb
28
+ attr_accessor :external_at_exit
29
+ alias external_at_exit? external_at_exit
28
30
 
29
31
  #
30
32
  # Sets up SimpleCov to run against your project.
@@ -44,35 +46,52 @@ module SimpleCov
44
46
  # Please check out the RDoc for SimpleCov::Configuration to find about available config options
45
47
  #
46
48
  def start(profile = nil, &block)
47
- if SimpleCov.usable?
48
- load_profile(profile) if profile
49
- configure(&block) if block_given?
50
- @result = nil
51
- self.running = true
52
- self.pid = Process.pid
53
- Coverage.start
54
- else
55
- warn "WARNING: SimpleCov is activated, but you're not running Ruby 1.9+ - no coverage analysis will happen"
56
- warn "Starting with SimpleCov 1.0.0, even no-op compatibility with Ruby <= 1.8 will be entirely dropped."
57
- false
58
- end
49
+ require "coverage"
50
+ initial_setup(profile, &block)
51
+ require_relative "./simplecov/process" if SimpleCov.enabled_for_subprocesses? &&
52
+ ::Process.respond_to?(:fork)
53
+
54
+ make_parallel_tests_available
55
+
56
+ @result = nil
57
+ self.pid = Process.pid
58
+
59
+ start_coverage_measurement
59
60
  end
60
61
 
61
62
  #
62
- # Finds files that were to be tracked but were not loaded and initializes
63
- # the line-by-line coverage to zero (if relevant) or nil (comments / whitespace etc).
63
+ # Collate a series of SimpleCov result files into a single SimpleCov output.
64
64
  #
65
- def add_not_loaded_files(result)
66
- if tracked_files
67
- result = result.dup
68
- Dir[tracked_files].each do |file|
69
- absolute = File.expand_path(file)
65
+ # You can optionally specify configuration with a block:
66
+ # SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"]
67
+ # OR
68
+ # SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"], 'rails' # using rails profile
69
+ # OR
70
+ # SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"] do
71
+ # add_filter 'test'
72
+ # end
73
+ # OR
74
+ # SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"], 'rails' do
75
+ # add_filter 'test'
76
+ # end
77
+ #
78
+ # Please check out the RDoc for SimpleCov::Configuration to find about
79
+ # available config options, or checkout the README for more in-depth
80
+ # information about coverage collation
81
+ #
82
+ # By default `collate` ignores the merge_timeout so all results of all files specified will be
83
+ # merged together. If you want to honor the merge_timeout then provide the keyword argument
84
+ # `ignore_timeout: false`.
85
+ #
86
+ def collate(result_filenames, profile = nil, ignore_timeout: true, &block)
87
+ raise "There are no reports to be merged" if result_filenames.empty?
70
88
 
71
- result[absolute] ||= LinesClassifier.new.classify(File.foreach(absolute))
72
- end
73
- end
89
+ initial_setup(profile, &block)
74
90
 
75
- result
91
+ # Use the ResultMerger to produce a single, merged result, ready to use.
92
+ @result = ResultMerger.merge_and_store(*result_filenames, ignore_timeout: ignore_timeout)
93
+
94
+ run_exit_tasks!
76
95
  end
77
96
 
78
97
  #
@@ -83,9 +102,7 @@ module SimpleCov
83
102
  return @result if result?
84
103
 
85
104
  # Collect our coverage result
86
- if running
87
- @result = SimpleCov::Result.new add_not_loaded_files(Coverage.result)
88
- end
105
+ process_coverage_result if running
89
106
 
90
107
  # If we're using merging of results, store the current result
91
108
  # first (if there is one), then merge the results and return those
@@ -147,22 +164,6 @@ module SimpleCov
147
164
  load_profile(name)
148
165
  end
149
166
 
150
- #
151
- # Checks whether we're on a proper version of Ruby (likely 1.9+) which
152
- # provides coverage support
153
- #
154
- def usable?
155
- return @usable if defined?(@usable) && !@usable.nil?
156
-
157
- @usable = begin
158
- require "coverage"
159
- require "simplecov/jruby_fix"
160
- true
161
- rescue LoadError
162
- false
163
- end
164
- end
165
-
166
167
  #
167
168
  # Clear out the previously cached .result. Primarily useful in testing
168
169
  #
@@ -170,44 +171,71 @@ module SimpleCov
170
171
  @result = nil
171
172
  end
172
173
 
174
+ def at_exit_behavior
175
+ # If we are in a different process than called start, don't interfere.
176
+ return if SimpleCov.pid != Process.pid
177
+
178
+ # If SimpleCov is no longer running then don't run exit tasks
179
+ SimpleCov.run_exit_tasks! if SimpleCov.running
180
+ end
181
+
182
+ # @api private
173
183
  #
174
- # Capture the current exception if it exists
175
- # This will get called inside the at_exit block
184
+ # Called from at_exit block
176
185
  #
177
- def set_exit_exception
178
- @exit_exception = $ERROR_INFO
186
+ def run_exit_tasks!
187
+ error_exit_status = exit_status_from_exception
188
+
189
+ at_exit.call
190
+
191
+ exit_and_report_previous_error(error_exit_status) if previous_error?(error_exit_status)
192
+ process_results_and_report_error if ready_to_process_results?
179
193
  end
180
194
 
195
+ #
196
+ # @api private
181
197
  #
182
198
  # Returns the exit status from the exit exception
183
199
  #
184
200
  def exit_status_from_exception
185
- return SimpleCov::ExitCodes::SUCCESS unless exit_exception
201
+ # Capture the current exception if it exists
202
+ @exit_exception = $ERROR_INFO
203
+ return nil unless @exit_exception
186
204
 
187
- if exit_exception.is_a?(SystemExit)
188
- exit_exception.status
205
+ if @exit_exception.is_a?(SystemExit)
206
+ @exit_exception.status
189
207
  else
190
208
  SimpleCov::ExitCodes::EXCEPTION
191
209
  end
192
210
  end
193
211
 
194
212
  # @api private
213
+ def previous_error?(error_exit_status)
214
+ # Normally it'd be enough to check for previous error but when running test_unit
215
+ # status is 0
216
+ error_exit_status && error_exit_status != SimpleCov::ExitCodes::SUCCESS
217
+ end
218
+
195
219
  #
196
- # Called from at_exit block
220
+ # @api private
197
221
  #
198
- def run_exit_tasks!
199
- exit_status = SimpleCov.exit_status_from_exception
222
+ # Thinking: Move this behavior earlier so if there was an error we do nothing?
223
+ def exit_and_report_previous_error(exit_status)
224
+ warn("Stopped processing SimpleCov as a previous error not related to SimpleCov has been detected") if print_error_status
225
+ Kernel.exit(exit_status)
226
+ end
200
227
 
201
- SimpleCov.at_exit.call
228
+ # @api private
229
+ def ready_to_process_results?
230
+ final_result_process? && result?
231
+ end
202
232
 
203
- # Don't modify the exit status unless the result has already been
204
- # computed
205
- exit_status = SimpleCov.process_result(SimpleCov.result, exit_status) if SimpleCov.result?
233
+ def process_results_and_report_error
234
+ exit_status = process_result(result)
206
235
 
207
236
  # Force exit with stored status (see github issue #5)
208
- # unless it's nil or 0 (see github issue #281)
209
- if exit_status && exit_status > 0
210
- $stderr.printf("SimpleCov failed with exit %d", exit_status)
237
+ if exit_status.positive?
238
+ warn("SimpleCov failed with exit #{exit_status} due to a coverage related error") if print_error_status
211
239
  Kernel.exit exit_status
212
240
  end
213
241
  end
@@ -217,48 +245,29 @@ module SimpleCov
217
245
  # Usage:
218
246
  # exit_status = SimpleCov.process_result(SimpleCov.result, exit_status)
219
247
  #
220
- def process_result(result, exit_status)
221
- return exit_status if exit_status != SimpleCov::ExitCodes::SUCCESS # Existing errors
222
-
223
- covered_percent = result.covered_percent.round(2)
224
- result_exit_status = result_exit_status(result, covered_percent)
225
- if result_exit_status == SimpleCov::ExitCodes::SUCCESS # No result errors
226
- write_last_run(covered_percent)
227
- end
228
- final_result_process? ? result_exit_status : SimpleCov::ExitCodes::SUCCESS
248
+ def process_result(result)
249
+ result_exit_status = result_exit_status(result)
250
+ write_last_run(result) if result_exit_status == SimpleCov::ExitCodes::SUCCESS
251
+ result_exit_status
229
252
  end
230
253
 
231
254
  # @api private
232
- #
233
- # rubocop:disable Metrics/MethodLength
234
- def result_exit_status(result, covered_percent)
235
- covered_percentages = result.covered_percentages.map { |percentage| percentage.round(2) }
236
- if covered_percent < SimpleCov.minimum_coverage
237
- $stderr.printf("Coverage (%.2f%%) is below the expected minimum coverage (%.2f%%).\n", covered_percent, SimpleCov.minimum_coverage)
238
- SimpleCov::ExitCodes::MINIMUM_COVERAGE
239
- elsif covered_percentages.any? { |p| p < SimpleCov.minimum_coverage_by_file }
240
- $stderr.printf("File (%s) is only (%.2f%%) covered. This is below the expected minimum coverage per file of (%.2f%%).\n", result.least_covered_file, covered_percentages.min, SimpleCov.minimum_coverage_by_file)
241
- SimpleCov::ExitCodes::MINIMUM_COVERAGE
242
- elsif (last_run = SimpleCov::LastRun.read)
243
- coverage_diff = last_run["result"]["covered_percent"] - covered_percent
244
- if coverage_diff > SimpleCov.maximum_coverage_drop
245
- $stderr.printf("Coverage has dropped by %.2f%% since the last time (maximum allowed: %.2f%%).\n", coverage_diff, SimpleCov.maximum_coverage_drop)
246
- SimpleCov::ExitCodes::MAXIMUM_COVERAGE_DROP
247
- else
248
- SimpleCov::ExitCodes::SUCCESS
249
- end
250
- else
251
- SimpleCov::ExitCodes::SUCCESS
252
- end
255
+ CoverageLimits = Struct.new(:minimum_coverage, :minimum_coverage_by_file, :maximum_coverage_drop, keyword_init: true)
256
+ def result_exit_status(result)
257
+ coverage_limits = CoverageLimits.new(
258
+ minimum_coverage: minimum_coverage, minimum_coverage_by_file: minimum_coverage_by_file,
259
+ maximum_coverage_drop: maximum_coverage_drop
260
+ )
261
+
262
+ ExitCodes::ExitCodeHandling.call(result, coverage_limits: coverage_limits)
253
263
  end
254
- # rubocop:enable Metrics/MethodLength
255
264
 
256
265
  #
257
266
  # @api private
258
267
  #
259
268
  def final_result_process?
260
- # checking for ENV["TEST_ENV_NUMBER"] to determine if the tess are being run in parallel
261
- !defined?(ParallelTests) || !ENV["TEST_ENV_NUMBER"] || ParallelTests.number_of_running_processes <= 1
269
+ # checking for ENV["TEST_ENV_NUMBER"] to determine if the tests are being run in parallel
270
+ !defined?(ParallelTests) || !ENV["TEST_ENV_NUMBER"] || ParallelTests.last_process?
262
271
  end
263
272
 
264
273
  #
@@ -266,37 +275,196 @@ module SimpleCov
266
275
  #
267
276
  def wait_for_other_processes
268
277
  return unless defined?(ParallelTests) && final_result_process?
278
+
269
279
  ParallelTests.wait_for_other_processes_to_finish
270
280
  end
271
281
 
272
282
  #
273
283
  # @api private
274
284
  #
275
- def write_last_run(covered_percent)
276
- SimpleCov::LastRun.write(:result => {:covered_percent => covered_percent})
285
+ def write_last_run(result)
286
+ SimpleCov::LastRun.write(result:
287
+ result.coverage_statistics.transform_values do |stats|
288
+ round_coverage(stats.percent)
289
+ end)
290
+ end
291
+
292
+ #
293
+ # @api private
294
+ #
295
+ # Rounding down to be extra strict, see #679
296
+ def round_coverage(coverage)
297
+ coverage.floor(2)
298
+ end
299
+
300
+ private
301
+
302
+ def initial_setup(profile, &block)
303
+ load_profile(profile) if profile
304
+ configure(&block) if block_given?
305
+ self.running = true
306
+ end
307
+
308
+ #
309
+ # Trigger Coverage.start depends on given config coverage_criterion
310
+ #
311
+ # With Positive branch it supports all coverage measurement types
312
+ # With Negative branch it supports only line coverage measurement type
313
+ #
314
+ def start_coverage_measurement
315
+ # This blog post gives a good run down of the coverage criterias introduced
316
+ # in Ruby 2.5: https://blog.bigbinary.com/2018/04/11/ruby-2-5-supports-measuring-branch-and-method-coverages.html
317
+ # There is also a nice writeup of the different coverage criteria made in this
318
+ # comment https://github.com/simplecov-ruby/simplecov/pull/692#discussion_r281836176 :
319
+ # Ruby < 2.5:
320
+ # https://github.com/ruby/ruby/blob/v1_9_3_374/ext/coverage/coverage.c
321
+ # traditional mode (Array)
322
+ #
323
+ # Ruby 2.5:
324
+ # https://bugs.ruby-lang.org/issues/13901
325
+ # https://github.com/ruby/ruby/blob/v2_5_3/ext/coverage/coverage.c
326
+ # default: traditional/compatible mode (Array)
327
+ # :lines - like traditional mode but using Hash
328
+ # :branches
329
+ # :methods
330
+ # :all - same as lines + branches + methods
331
+ #
332
+ # Ruby >= 2.6:
333
+ # https://bugs.ruby-lang.org/issues/15022
334
+ # https://github.com/ruby/ruby/blob/v2_6_3/ext/coverage/coverage.c
335
+ # default: traditional/compatible mode (Array)
336
+ # :lines - like traditional mode but using Hash
337
+ # :branches
338
+ # :methods
339
+ # :oneshot_lines - can not be combined with lines
340
+ # :all - same as lines + branches + methods
341
+ #
342
+ if coverage_start_arguments_supported?
343
+ start_coverage_with_criteria
344
+ else
345
+ Coverage.start unless Coverage.running?
346
+ end
347
+ end
348
+
349
+ def start_coverage_with_criteria
350
+ start_arguments = coverage_criteria.map do |criterion|
351
+ [lookup_corresponding_ruby_coverage_name(criterion), true]
352
+ end.to_h
353
+
354
+ start_arguments[:eval] = true if coverage_for_eval_enabled?
355
+
356
+ Coverage.start(start_arguments) unless Coverage.running?
357
+ end
358
+
359
+ CRITERION_TO_RUBY_COVERAGE = {
360
+ branch: :branches,
361
+ line: :lines
362
+ }.freeze
363
+ def lookup_corresponding_ruby_coverage_name(criterion)
364
+ CRITERION_TO_RUBY_COVERAGE.fetch(criterion)
365
+ end
366
+
367
+ #
368
+ # Finds files that were to be tracked but were not loaded and initializes
369
+ # the line-by-line coverage to zero (if relevant) or nil (comments / whitespace etc).
370
+ #
371
+ def add_not_loaded_files(result)
372
+ if tracked_files
373
+ result = result.dup
374
+ Dir[tracked_files].each do |file|
375
+ absolute_path = File.expand_path(file)
376
+ result[absolute_path] ||= SimulateCoverage.call(absolute_path)
377
+ end
378
+ end
379
+
380
+ result
381
+ end
382
+
383
+ #
384
+ # Call steps that handle process coverage result
385
+ #
386
+ # @return [Hash]
387
+ #
388
+ def process_coverage_result
389
+ adapt_coverage_result
390
+ remove_useless_results
391
+ result_with_not_loaded_files
392
+ end
393
+
394
+ #
395
+ # Unite the result so it wouldn't matter what coverage type was called
396
+ #
397
+ # @return [Hash]
398
+ #
399
+ def adapt_coverage_result
400
+ @result = SimpleCov::ResultAdapter.call(Coverage.result)
401
+ end
402
+
403
+ #
404
+ # Filter coverage result
405
+ # The result before filter also has result of coverage for files
406
+ # are not related to the project like loaded gems coverage.
407
+ #
408
+ # @return [Hash]
409
+ #
410
+ def remove_useless_results
411
+ @result = SimpleCov::UselessResultsRemover.call(@result)
412
+ end
413
+
414
+ #
415
+ # Initialize result with files that are not included by coverage
416
+ # and added inside the config block
417
+ #
418
+ # @return [Hash]
419
+ #
420
+ def result_with_not_loaded_files
421
+ @result = SimpleCov::Result.new(add_not_loaded_files(@result))
422
+ end
423
+
424
+ # parallel_tests isn't always available, see: https://github.com/grosser/parallel_tests/issues/772
425
+ def make_parallel_tests_available
426
+ return if defined?(ParallelTests)
427
+ return unless probably_running_parallel_tests?
428
+
429
+ require "parallel_tests"
430
+ rescue LoadError
431
+ warn("SimpleCov guessed you were running inside parallel tests but couldn't load it. Please file a bug report with us!")
432
+ end
433
+
434
+ def probably_running_parallel_tests?
435
+ ENV["TEST_ENV_NUMBER"] && ENV["PARALLEL_TEST_GROUPS"]
277
436
  end
278
437
  end
279
438
  end
280
439
 
281
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__)))
282
- require "simplecov/configuration"
283
- SimpleCov.send :extend, SimpleCov::Configuration
284
- require "simplecov/exit_codes"
285
- require "simplecov/profiles"
286
- require "simplecov/source_file"
287
- require "simplecov/file_list"
288
- require "simplecov/result"
289
- require "simplecov/filter"
290
- require "simplecov/formatter"
291
- require "simplecov/last_run"
292
- require "simplecov/lines_classifier"
293
- require "simplecov/raw_coverage"
294
- require "simplecov/result_merger"
295
- require "simplecov/command_guesser"
296
- require "simplecov/version"
440
+ # requires are down here here for a load order reason I'm not sure what it is about
441
+ require "set"
442
+ require "forwardable"
443
+ require_relative "simplecov/configuration"
444
+ SimpleCov.extend SimpleCov::Configuration
445
+ require_relative "simplecov/coverage_statistics"
446
+ require_relative "simplecov/exit_codes"
447
+ require_relative "simplecov/profiles"
448
+ require_relative "simplecov/source_file/line"
449
+ require_relative "simplecov/source_file/branch"
450
+ require_relative "simplecov/source_file"
451
+ require_relative "simplecov/file_list"
452
+ require_relative "simplecov/result"
453
+ require_relative "simplecov/filter"
454
+ require_relative "simplecov/formatter"
455
+ require_relative "simplecov/last_run"
456
+ require_relative "simplecov/lines_classifier"
457
+ require_relative "simplecov/result_merger"
458
+ require_relative "simplecov/command_guesser"
459
+ require_relative "simplecov/version"
460
+ require_relative "simplecov/result_adapter"
461
+ require_relative "simplecov/combine"
462
+ require_relative "simplecov/combine/branches_combiner"
463
+ require_relative "simplecov/combine/files_combiner"
464
+ require_relative "simplecov/combine/lines_combiner"
465
+ require_relative "simplecov/combine/results_combiner"
466
+ require_relative "simplecov/useless_results_remover"
467
+ require_relative "simplecov/simulate_coverage"
297
468
 
298
469
  # Load default config
299
- require "simplecov/defaults" unless ENV["SIMPLECOV_NO_DEFAULTS"]
300
-
301
- # Load Rails integration (only for Rails 3, see #113)
302
- require "simplecov/railtie" if defined? Rails::Railtie
470
+ require_relative "simplecov/defaults" unless ENV["SIMPLECOV_NO_DEFAULTS"]