deep-cover-core 0.6.3.pre

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 (131) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +4 -0
  3. data/.rspec_all +3 -0
  4. data/.rubocop.yml +1 -0
  5. data/Gemfile +11 -0
  6. data/deep_cover_core.gemspec +46 -0
  7. data/lib/deep-cover.rb +3 -0
  8. data/lib/deep_cover/analyser/base.rb +104 -0
  9. data/lib/deep_cover/analyser/branch.rb +41 -0
  10. data/lib/deep_cover/analyser/covered_code_source.rb +21 -0
  11. data/lib/deep_cover/analyser/function.rb +14 -0
  12. data/lib/deep_cover/analyser/node.rb +54 -0
  13. data/lib/deep_cover/analyser/per_char.rb +38 -0
  14. data/lib/deep_cover/analyser/per_line.rb +41 -0
  15. data/lib/deep_cover/analyser/ruby25_like_branch.rb +211 -0
  16. data/lib/deep_cover/analyser/statement.rb +33 -0
  17. data/lib/deep_cover/analyser/stats.rb +54 -0
  18. data/lib/deep_cover/analyser/subset.rb +27 -0
  19. data/lib/deep_cover/analyser.rb +23 -0
  20. data/lib/deep_cover/auto_run.rb +71 -0
  21. data/lib/deep_cover/autoload_tracker.rb +215 -0
  22. data/lib/deep_cover/backports.rb +22 -0
  23. data/lib/deep_cover/base.rb +117 -0
  24. data/lib/deep_cover/basics.rb +22 -0
  25. data/lib/deep_cover/builtin_takeover.rb +10 -0
  26. data/lib/deep_cover/config.rb +104 -0
  27. data/lib/deep_cover/config_setter.rb +33 -0
  28. data/lib/deep_cover/core_ext/autoload_overrides.rb +112 -0
  29. data/lib/deep_cover/core_ext/coverage_replacement.rb +61 -0
  30. data/lib/deep_cover/core_ext/exec_callbacks.rb +27 -0
  31. data/lib/deep_cover/core_ext/instruction_sequence_load_iseq.rb +32 -0
  32. data/lib/deep_cover/core_ext/load_overrides.rb +19 -0
  33. data/lib/deep_cover/core_ext/require_overrides.rb +28 -0
  34. data/lib/deep_cover/coverage/analysis.rb +42 -0
  35. data/lib/deep_cover/coverage/persistence.rb +84 -0
  36. data/lib/deep_cover/coverage.rb +125 -0
  37. data/lib/deep_cover/covered_code.rb +145 -0
  38. data/lib/deep_cover/custom_requirer.rb +187 -0
  39. data/lib/deep_cover/flag_comment_associator.rb +68 -0
  40. data/lib/deep_cover/load.rb +66 -0
  41. data/lib/deep_cover/memoize.rb +48 -0
  42. data/lib/deep_cover/module_override.rb +39 -0
  43. data/lib/deep_cover/node/arguments.rb +51 -0
  44. data/lib/deep_cover/node/assignments.rb +273 -0
  45. data/lib/deep_cover/node/base.rb +155 -0
  46. data/lib/deep_cover/node/begin.rb +27 -0
  47. data/lib/deep_cover/node/block.rb +61 -0
  48. data/lib/deep_cover/node/branch.rb +32 -0
  49. data/lib/deep_cover/node/case.rb +113 -0
  50. data/lib/deep_cover/node/collections.rb +31 -0
  51. data/lib/deep_cover/node/const.rb +12 -0
  52. data/lib/deep_cover/node/def.rb +40 -0
  53. data/lib/deep_cover/node/empty_body.rb +32 -0
  54. data/lib/deep_cover/node/exceptions.rb +79 -0
  55. data/lib/deep_cover/node/if.rb +73 -0
  56. data/lib/deep_cover/node/keywords.rb +86 -0
  57. data/lib/deep_cover/node/literals.rb +100 -0
  58. data/lib/deep_cover/node/loops.rb +74 -0
  59. data/lib/deep_cover/node/mixin/can_augment_children.rb +65 -0
  60. data/lib/deep_cover/node/mixin/check_completion.rb +18 -0
  61. data/lib/deep_cover/node/mixin/child_can_be_empty.rb +27 -0
  62. data/lib/deep_cover/node/mixin/executed_after_children.rb +15 -0
  63. data/lib/deep_cover/node/mixin/execution_location.rb +66 -0
  64. data/lib/deep_cover/node/mixin/filters.rb +47 -0
  65. data/lib/deep_cover/node/mixin/flow_accounting.rb +71 -0
  66. data/lib/deep_cover/node/mixin/has_child.rb +145 -0
  67. data/lib/deep_cover/node/mixin/has_child_handler.rb +75 -0
  68. data/lib/deep_cover/node/mixin/has_tracker.rb +46 -0
  69. data/lib/deep_cover/node/mixin/is_statement.rb +20 -0
  70. data/lib/deep_cover/node/mixin/rewriting.rb +35 -0
  71. data/lib/deep_cover/node/mixin/wrapper.rb +15 -0
  72. data/lib/deep_cover/node/module.rb +66 -0
  73. data/lib/deep_cover/node/root.rb +20 -0
  74. data/lib/deep_cover/node/send.rb +161 -0
  75. data/lib/deep_cover/node/short_circuit.rb +42 -0
  76. data/lib/deep_cover/node/splat.rb +15 -0
  77. data/lib/deep_cover/node/variables.rb +16 -0
  78. data/lib/deep_cover/node.rb +23 -0
  79. data/lib/deep_cover/parser_ext/range.rb +21 -0
  80. data/lib/deep_cover/problem_with_diagnostic.rb +63 -0
  81. data/lib/deep_cover/reporter/base.rb +68 -0
  82. data/lib/deep_cover/reporter/html/base.rb +14 -0
  83. data/lib/deep_cover/reporter/html/index.rb +59 -0
  84. data/lib/deep_cover/reporter/html/site.rb +68 -0
  85. data/lib/deep_cover/reporter/html/source.rb +136 -0
  86. data/lib/deep_cover/reporter/html/template/assets/32px.png +0 -0
  87. data/lib/deep_cover/reporter/html/template/assets/40px.png +0 -0
  88. data/lib/deep_cover/reporter/html/template/assets/deep_cover.css +291 -0
  89. data/lib/deep_cover/reporter/html/template/assets/deep_cover.css.sass +336 -0
  90. data/lib/deep_cover/reporter/html/template/assets/jquery-3.2.1.min.js +4 -0
  91. data/lib/deep_cover/reporter/html/template/assets/jquery-3.2.1.min.map +1 -0
  92. data/lib/deep_cover/reporter/html/template/assets/jstree.css +1108 -0
  93. data/lib/deep_cover/reporter/html/template/assets/jstree.js +8424 -0
  94. data/lib/deep_cover/reporter/html/template/assets/jstreetable.js +1069 -0
  95. data/lib/deep_cover/reporter/html/template/assets/throbber.gif +0 -0
  96. data/lib/deep_cover/reporter/html/template/index.html.erb +75 -0
  97. data/lib/deep_cover/reporter/html/template/source.html.erb +35 -0
  98. data/lib/deep_cover/reporter/html.rb +15 -0
  99. data/lib/deep_cover/reporter/istanbul.rb +184 -0
  100. data/lib/deep_cover/reporter/text.rb +58 -0
  101. data/lib/deep_cover/reporter/tree/util.rb +86 -0
  102. data/lib/deep_cover/reporter.rb +10 -0
  103. data/lib/deep_cover/tools/blank.rb +25 -0
  104. data/lib/deep_cover/tools/builtin_coverage.rb +55 -0
  105. data/lib/deep_cover/tools/camelize.rb +13 -0
  106. data/lib/deep_cover/tools/content_tag.rb +11 -0
  107. data/lib/deep_cover/tools/covered.rb +9 -0
  108. data/lib/deep_cover/tools/execute_sample.rb +34 -0
  109. data/lib/deep_cover/tools/format.rb +18 -0
  110. data/lib/deep_cover/tools/format_char_cover.rb +19 -0
  111. data/lib/deep_cover/tools/format_generated_code.rb +27 -0
  112. data/lib/deep_cover/tools/indent_string.rb +26 -0
  113. data/lib/deep_cover/tools/merge.rb +16 -0
  114. data/lib/deep_cover/tools/number_lines.rb +22 -0
  115. data/lib/deep_cover/tools/our_coverage.rb +11 -0
  116. data/lib/deep_cover/tools/profiling.rb +68 -0
  117. data/lib/deep_cover/tools/render_template.rb +13 -0
  118. data/lib/deep_cover/tools/require_relative_dir.rb +12 -0
  119. data/lib/deep_cover/tools/scan_match_datas.rb +10 -0
  120. data/lib/deep_cover/tools/silence_warnings.rb +18 -0
  121. data/lib/deep_cover/tools/slice.rb +9 -0
  122. data/lib/deep_cover/tools/strip_heredoc.rb +18 -0
  123. data/lib/deep_cover/tools/truncate_backtrace.rb +32 -0
  124. data/lib/deep_cover/tools.rb +22 -0
  125. data/lib/deep_cover/tracker_bucket.rb +50 -0
  126. data/lib/deep_cover/tracker_hits_per_path.rb +35 -0
  127. data/lib/deep_cover/tracker_storage.rb +76 -0
  128. data/lib/deep_cover/tracker_storage_per_path.rb +34 -0
  129. data/lib/deep_cover/version.rb +5 -0
  130. data/lib/deep_cover.rb +22 -0
  131. metadata +329 -0
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ module Tools::IndentString
5
+ # In-place implementation copied from active-support.
6
+ IMPLEMENTATION = ->(amount, indent_string = nil, indent_empty_lines = false) do
7
+ indent_string = indent_string || self[/^[ \t]/] || ' '
8
+ re = indent_empty_lines ? /^/ : /^(?!$)/
9
+ gsub!(re, indent_string * amount)
10
+ end
11
+
12
+ # Same as #indent! from active-support
13
+ # https://github.com/rails/rails/blob/10e1f1f9a129f2f197a44009a99b73b8ff9dbc0d/activesupport/lib/active_support/core_ext/string/indent.rb#L7
14
+ def indent_string!(string, *args)
15
+ string.instance_exec(*args, &IMPLEMENTATION)
16
+ end
17
+
18
+ # Same as #indent from active-support
19
+ # https://github.com/rails/rails/blob/10e1f1f9a129f2f197a44009a99b73b8ff9dbc0d/activesupport/lib/active_support/core_ext/string/indent.rb#L42
20
+ def indent_string(string, *args)
21
+ string = string.dup
22
+ indent_string!(string, *args)
23
+ string
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ module Tools::Merge
5
+ def merge(*hashes)
6
+ if hashes.last.is_a?(Symbol)
7
+ oper = hashes.pop
8
+ merge(*hashes) { |a, b| a.public_send(oper, b) }
9
+ elsif !block_given?
10
+ merge(*hashes, &:last)
11
+ else
12
+ hashes.inject { |result, h| result.merge(h) { |key, a, b| yield [a, b] } }
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ module Tools::NumberLines
5
+ def number_lines(lines, lineno: 1, bad_linenos: [])
6
+ max_lineno = lineno + lines.size - 1
7
+ nb_lineno_digits = max_lineno.to_s.size
8
+ lines.map.with_index do |line, i|
9
+ cur_lineno = lineno + i
10
+ cur_lineno_s = cur_lineno.to_s.rjust(nb_lineno_digits)
11
+ if bad_linenos.include?(cur_lineno)
12
+ cur_lineno_s = "*#{cur_lineno_s}" unless bad_linenos.empty?
13
+ prefix = Term::ANSIColor.red("#{cur_lineno_s} | ")
14
+ else
15
+ cur_lineno_s = " #{cur_lineno_s}" unless bad_linenos.empty?
16
+ prefix = Term::ANSIColor.white("#{cur_lineno_s} | ")
17
+ end
18
+ "#{prefix}#{line}"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ module Tools::OurCoverage
5
+ def our_coverage(source, filename, lineno, **options)
6
+ covered_code = CoveredCode.new(source: source, path: filename, lineno: lineno)
7
+ Tools.execute_sample(covered_code)
8
+ covered_code.line_coverage(options)[(lineno - 1)..-1]
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'delegate'
4
+
5
+ module DeepCover
6
+ module Tools::Profiling
7
+ # Simple forwarding to implementation
8
+ def start
9
+ profiler.start
10
+ end
11
+
12
+ def stop
13
+ @results = profiler.stop
14
+ end
15
+
16
+ def pause
17
+ profiler.pause
18
+ end
19
+
20
+ def resume
21
+ profiler.resume
22
+ end
23
+
24
+ def report
25
+ profiler.report(@results)
26
+ end
27
+
28
+ # Basic utilities using forwarding methods
29
+ def profile(do_start = true)
30
+ return yield unless do_start
31
+ start
32
+ yield
33
+ stop
34
+ report
35
+ end
36
+
37
+ def dont_profile
38
+ pause if profiler_loaded?
39
+ yield
40
+ ensure
41
+ resume if profiler_loaded?
42
+ end
43
+
44
+ def profiler_loaded?
45
+ !!@profiler
46
+ end
47
+
48
+ private
49
+
50
+ # Dependency injection
51
+ def profiler
52
+ @profiler = RubyProfProfiler.new
53
+ end
54
+
55
+ class RubyProfProfiler < SimpleDelegator
56
+ def initialize
57
+ raise 'Profiling is not available when using JRuby' if RUBY_PLATFORM == 'java'
58
+ require 'ruby-prof'
59
+ super(RubyProf)
60
+ end
61
+
62
+ def report(results)
63
+ printer = RubyProf::GraphPrinter.new(results)
64
+ printer.print(STDOUT, {})
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ module Tools::RenderTemplate
5
+ def render_template(template, bound_object)
6
+ require 'erb'
7
+ caller_path = Pathname.new(caller(1..1).first.partition(/\.rb:\d/).first).dirname
8
+ template = caller_path.join("template/#{template}.html.erb").read
9
+ erb = ERB.new(template)
10
+ erb.result(bound_object.instance_eval { binding })
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ module Tools::RequireRelativeDir
5
+ def require_relative_dir(dir_name, except: [])
6
+ dir = File.dirname(caller(1..1).first.partition(/\.rb:\d/).first)
7
+ Dir["#{dir}/#{dir_name}/*.rb"].sort.each do |file|
8
+ require file unless except.include? File.basename(file, '.rb')
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ module Tools::RequireRelativeDir
5
+ # Like String#scan, but return the MatchData object instead
6
+ def scan_match_datas(source, matcher)
7
+ source.to_enum(:scan, matcher).map { Regexp.last_match }
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ module Tools::SilenceWarnings
5
+ # copied from: activesupport/lib/active_support/core_ext/kernel/reporting.rb
6
+ def silence_warnings
7
+ with_warnings(nil) { yield }
8
+ end
9
+
10
+ def with_warnings(flag)
11
+ old_verbose = $VERBOSE
12
+ $VERBOSE = flag
13
+ yield
14
+ ensure
15
+ $VERBOSE = old_verbose
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ module Tools::Slice
5
+ def slice(hash, *keys)
6
+ keys.each_with_object({}) { |k, h| h[k] = hash[k] if hash.has_key?(k) }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ module Tools::StripHeredoc
5
+ # In-place implementation copied from active-support.
6
+ IMPLEMENTATION = -> do
7
+ gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, ''.freeze).tap do |stripped|
8
+ stripped.freeze if frozen?
9
+ end
10
+ end
11
+
12
+ # Same as #strip_heredoc from active-support
13
+ # https://github.com/rails/rails/blob/16574409f813e2197f88e4a06b527618d64d9ff0/activesupport/lib/active_support/core_ext/string/strip.rb#L22
14
+ def strip_heredoc(string)
15
+ string.instance_exec(&IMPLEMENTATION)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ module Tools::TruncateBacktrace
5
+ def truncate_backtrace(backtrace, extra_context: 10)
6
+ backtrace = backtrace.backtrace if backtrace.is_a?(Exception)
7
+ trace_lines = backtrace.uniq
8
+
9
+ keep_from_begin = 0
10
+ keep_from_end = backtrace.size - 1
11
+
12
+ trace_lines.each do |line|
13
+ from_begin = backtrace.index(line)
14
+ from_end = backtrace.rindex(line)
15
+ if from_begin <= backtrace.size - 1 - from_end
16
+ keep_from_begin = [keep_from_begin, from_begin].max
17
+ else
18
+ keep_from_end = [keep_from_end, from_end].min
19
+ end
20
+ end
21
+
22
+ keep_from_begin += extra_context
23
+ keep_from_end -= extra_context
24
+
25
+ return backtrace if keep_from_begin + 5 >= keep_from_end
26
+
27
+ result = backtrace[0..keep_from_begin]
28
+ result << "... #{keep_from_end - keep_from_begin - 1} levels..."
29
+ result.concat backtrace[keep_from_end..-1]
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ module Tools
5
+ end
6
+
7
+ require_relative 'tools/require_relative_dir'
8
+ extend Tools::RequireRelativeDir
9
+ require_relative 'tools/silence_warnings'
10
+ extend Tools::SilenceWarnings
11
+ require_relative_dir 'tools'
12
+
13
+ # The functions defined in the submodules of Tools can be accessed
14
+ # either by extending the desired module, or all of them by extending
15
+ # Tools, or by calling them directly Tool.my_function.
16
+ module Tools
17
+ constants.each do |module_name|
18
+ include const_get(module_name)
19
+ end
20
+ extend self
21
+ end
22
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ bootstrap
5
+
6
+ require_relative 'tracker_storage'
7
+
8
+ # A holder for TrackerStorages, using some `global_name`.
9
+ class TrackerBucket
10
+ @@index = {}
11
+
12
+ def self.[](global_name)
13
+ raise ArgumentError, "'#{global_name}' is not a valid global name" unless global_name.start_with? '$'
14
+ @@index[global_name] ||= new(global_name)
15
+ end
16
+
17
+ def setup_source
18
+ "#{source} ||= {}"
19
+ end
20
+
21
+ def source
22
+ @global_name
23
+ end
24
+
25
+ class << self
26
+ alias_method :_load, :[]
27
+ private :_load, :new
28
+ end
29
+
30
+ def inspect
31
+ %{#<DeepCover::TrackerBucket "#{@global_name}">}
32
+ end
33
+
34
+ def create_storage(index = nil)
35
+ index ||= @global.size
36
+ TrackerStorage.new(bucket: self, array: @global[index] ||= [], index: index)
37
+ end
38
+
39
+ private
40
+
41
+ def initialize(global_name)
42
+ @global_name = global_name
43
+ @global = eval(setup_source) # rubocop:disable Security/Eval
44
+ end
45
+
46
+ def _dump(_level)
47
+ @global_name
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ bootstrap
5
+
6
+ # Should be seen as a hash like {path => tracker_hits, ...},
7
+ # where tracker_hits is simply an array of integers returned from
8
+ # TrackerStorage#tracker_hits.
9
+ # Make it easier to separate some concerns, as well as marshalling.
10
+ #
11
+ class TrackerHitsPerPath
12
+ extend Forwardable
13
+ def_delegators :@index, :each, :each_key, :map, :transform_values, :to_h, :to_hash
14
+
15
+ def initialize(index = {})
16
+ @index = index
17
+ end
18
+
19
+ def [](val)
20
+ @index[val] ||= []
21
+ end
22
+
23
+ def merge!(tracker_hits_per_path)
24
+ @index.merge!(tracker_hits_per_path) { |_h, actual, to_merge| merge_tracker_hits(actual, to_merge) }
25
+ self
26
+ end
27
+
28
+ private def merge_tracker_hits(hits, to_merge)
29
+ unless hits.size == to_merge.size
30
+ raise "Attempting to merge trackers of different sizes: #{hits.size} vs #{to_merge.size}"
31
+ end
32
+ hits.map!.with_index { |val, i| val + to_merge[i] }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ bootstrap
5
+
6
+ # List of allocated trackers from a bucket.
7
+ # Should be thought of as a simple array of integers with
8
+ # a limited interface.
9
+ class TrackerBucket
10
+ class TrackerStorage
11
+ extend Forwardable
12
+ def_delegators :@array, :[], :size, :each, :map, :fetch
13
+
14
+ attr_reader :bucket
15
+
16
+ def initialize(bucket:, array:, index:)
17
+ @bucket = bucket
18
+ @array = array
19
+ @index = index
20
+ @allocated = 0
21
+ end
22
+
23
+ # Returns a range of tracker ids
24
+ def allocate_trackers(nb_needed)
25
+ prev = @allocated
26
+ @allocated += nb_needed
27
+ missing = @allocated - @array.size
28
+ @array.concat(Array.new(missing, 0)) if missing > 0
29
+ prev...@allocated
30
+ end
31
+
32
+ def setup_source
33
+ "(#{bucket.setup_source})[#{@index}]||=Array.new(#{size},0)"
34
+ end
35
+
36
+ def tracker_source(tracker_id)
37
+ "#{bucket.source}[#{@index}][#{tracker_id}]+=1"
38
+ end
39
+
40
+ def tracker_hits
41
+ @array.dup.freeze
42
+ end
43
+
44
+ def tracker_hits=(new_hits)
45
+ if new_hits.size != @array.size
46
+ warn 'Replacing tracker hits with array of different size'
47
+ end
48
+ @array.replace(new_hits)
49
+ end
50
+
51
+ private
52
+
53
+ def dump
54
+ {bucket: @bucket, index: @index, size: @array.size}
55
+ end
56
+
57
+ def _dump(_level)
58
+ Marshal.dump(dump)
59
+ end
60
+
61
+ class << self
62
+ private def load(bucket:, index:, size:)
63
+ storage = bucket.create_storage(index)
64
+ storage.allocate_trackers(size - storage.size)
65
+ storage
66
+ end
67
+
68
+ private def _load(data)
69
+ load(Marshal.load(data)) # rubocop:disable Security/MarshalLoad
70
+ end
71
+ end
72
+ end
73
+
74
+ private_constant :TrackerStorage
75
+ end
76
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ bootstrap
5
+
6
+ # Should be seen as a hash like {path => tracker_storage, ...}
7
+ # Make it easier to separate some concerns, as well as marshalling
8
+ #
9
+ class TrackerStoragePerPath
10
+ extend Forwardable
11
+ def_delegators :@index, :each, :each_key, :map, :transform_values
12
+
13
+ attr_reader :bucket
14
+
15
+ def initialize(bucket)
16
+ @bucket = bucket
17
+ @index = {}
18
+ end
19
+
20
+ def [](path)
21
+ @index[path] ||= @bucket.create_storage
22
+ end
23
+
24
+ def tracker_hits_per_path
25
+ TrackerHitsPerPath.new(@index.transform_values(&:tracker_hits))
26
+ end
27
+
28
+ def tracker_hits_per_path=(tracker_hits_per_path)
29
+ tracker_hits_per_path.each do |path, tracker_hits|
30
+ self[path].tracker_hits = tracker_hits
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ VERSION = '0.6.3.pre'
5
+ end
data/lib/deep_cover.rb ADDED
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ require_relative 'deep_cover/load'
5
+
6
+ load_absolute_basics
7
+
8
+ extend Base
9
+ extend ConfigSetter
10
+ end
11
+ DeepCover::GLOBAL_BINDING = binding
12
+
13
+ require './.deep_cover.rb' if File.exist?('./.deep_cover.rb')
14
+
15
+ if ENV['DEEP_COVER_OPTIONS']
16
+ DeepCover.config.set(YAML.load(ENV['DEEP_COVER_OPTIONS']))
17
+ end
18
+ if %w[1 t true].include?(ENV['DEEP_COVER'])
19
+ DeepCover.start
20
+ require_relative 'deep_cover/auto_run'
21
+ DeepCover::AutoRun.run!('.').report!(**DeepCover.config)
22
+ end