deep-cover 0.6.2 → 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 (139) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.rspec +2 -1
  4. data/.rspec_all +2 -1
  5. data/.rubocop.yml +8 -9
  6. data/Gemfile +2 -0
  7. data/Rakefile +32 -6
  8. data/bin/cov +3 -3
  9. data/deep_cover.gemspec +3 -16
  10. data/exe/deep-cover +5 -0
  11. data/lib/deep_cover/cli/debugger.rb +1 -1
  12. data/lib/deep_cover/cli/exec.rb +1 -1
  13. data/lib/deep_cover/cli/instrumented_clone_reporter.rb +5 -3
  14. data/lib/deep_cover/cli/runner.rb +2 -2
  15. data/lib/deep_cover/{tools/dump_covered_code.rb → dump_covered_code.rb} +2 -0
  16. metadata +10 -203
  17. data/lib/deep-cover.rb +0 -3
  18. data/lib/deep_cover.rb +0 -22
  19. data/lib/deep_cover/analyser.rb +0 -23
  20. data/lib/deep_cover/analyser/base.rb +0 -104
  21. data/lib/deep_cover/analyser/branch.rb +0 -41
  22. data/lib/deep_cover/analyser/covered_code_source.rb +0 -21
  23. data/lib/deep_cover/analyser/function.rb +0 -14
  24. data/lib/deep_cover/analyser/node.rb +0 -54
  25. data/lib/deep_cover/analyser/per_char.rb +0 -38
  26. data/lib/deep_cover/analyser/per_line.rb +0 -41
  27. data/lib/deep_cover/analyser/ruby25_like_branch.rb +0 -211
  28. data/lib/deep_cover/analyser/statement.rb +0 -33
  29. data/lib/deep_cover/analyser/stats.rb +0 -54
  30. data/lib/deep_cover/analyser/subset.rb +0 -27
  31. data/lib/deep_cover/auto_run.rb +0 -71
  32. data/lib/deep_cover/autoload_tracker.rb +0 -215
  33. data/lib/deep_cover/backports.rb +0 -22
  34. data/lib/deep_cover/base.rb +0 -117
  35. data/lib/deep_cover/basics.rb +0 -22
  36. data/lib/deep_cover/builtin_takeover.rb +0 -10
  37. data/lib/deep_cover/config.rb +0 -104
  38. data/lib/deep_cover/config_setter.rb +0 -33
  39. data/lib/deep_cover/core_ext/autoload_overrides.rb +0 -112
  40. data/lib/deep_cover/core_ext/coverage_replacement.rb +0 -61
  41. data/lib/deep_cover/core_ext/exec_callbacks.rb +0 -27
  42. data/lib/deep_cover/core_ext/instruction_sequence_load_iseq.rb +0 -32
  43. data/lib/deep_cover/core_ext/load_overrides.rb +0 -19
  44. data/lib/deep_cover/core_ext/require_overrides.rb +0 -28
  45. data/lib/deep_cover/coverage.rb +0 -125
  46. data/lib/deep_cover/coverage/analysis.rb +0 -42
  47. data/lib/deep_cover/coverage/persistence.rb +0 -84
  48. data/lib/deep_cover/covered_code.rb +0 -145
  49. data/lib/deep_cover/custom_requirer.rb +0 -187
  50. data/lib/deep_cover/flag_comment_associator.rb +0 -68
  51. data/lib/deep_cover/load.rb +0 -66
  52. data/lib/deep_cover/memoize.rb +0 -48
  53. data/lib/deep_cover/module_override.rb +0 -39
  54. data/lib/deep_cover/node.rb +0 -23
  55. data/lib/deep_cover/node/arguments.rb +0 -51
  56. data/lib/deep_cover/node/assignments.rb +0 -273
  57. data/lib/deep_cover/node/base.rb +0 -155
  58. data/lib/deep_cover/node/begin.rb +0 -27
  59. data/lib/deep_cover/node/block.rb +0 -61
  60. data/lib/deep_cover/node/branch.rb +0 -32
  61. data/lib/deep_cover/node/case.rb +0 -113
  62. data/lib/deep_cover/node/collections.rb +0 -31
  63. data/lib/deep_cover/node/const.rb +0 -12
  64. data/lib/deep_cover/node/def.rb +0 -40
  65. data/lib/deep_cover/node/empty_body.rb +0 -32
  66. data/lib/deep_cover/node/exceptions.rb +0 -79
  67. data/lib/deep_cover/node/if.rb +0 -73
  68. data/lib/deep_cover/node/keywords.rb +0 -86
  69. data/lib/deep_cover/node/literals.rb +0 -100
  70. data/lib/deep_cover/node/loops.rb +0 -74
  71. data/lib/deep_cover/node/mixin/can_augment_children.rb +0 -65
  72. data/lib/deep_cover/node/mixin/check_completion.rb +0 -18
  73. data/lib/deep_cover/node/mixin/child_can_be_empty.rb +0 -27
  74. data/lib/deep_cover/node/mixin/executed_after_children.rb +0 -15
  75. data/lib/deep_cover/node/mixin/execution_location.rb +0 -66
  76. data/lib/deep_cover/node/mixin/filters.rb +0 -47
  77. data/lib/deep_cover/node/mixin/flow_accounting.rb +0 -71
  78. data/lib/deep_cover/node/mixin/has_child.rb +0 -145
  79. data/lib/deep_cover/node/mixin/has_child_handler.rb +0 -75
  80. data/lib/deep_cover/node/mixin/has_tracker.rb +0 -46
  81. data/lib/deep_cover/node/mixin/is_statement.rb +0 -20
  82. data/lib/deep_cover/node/mixin/rewriting.rb +0 -35
  83. data/lib/deep_cover/node/mixin/wrapper.rb +0 -15
  84. data/lib/deep_cover/node/module.rb +0 -66
  85. data/lib/deep_cover/node/root.rb +0 -20
  86. data/lib/deep_cover/node/send.rb +0 -161
  87. data/lib/deep_cover/node/short_circuit.rb +0 -42
  88. data/lib/deep_cover/node/splat.rb +0 -15
  89. data/lib/deep_cover/node/variables.rb +0 -16
  90. data/lib/deep_cover/parser_ext/range.rb +0 -21
  91. data/lib/deep_cover/problem_with_diagnostic.rb +0 -63
  92. data/lib/deep_cover/reporter.rb +0 -10
  93. data/lib/deep_cover/reporter/base.rb +0 -68
  94. data/lib/deep_cover/reporter/html.rb +0 -15
  95. data/lib/deep_cover/reporter/html/base.rb +0 -14
  96. data/lib/deep_cover/reporter/html/index.rb +0 -59
  97. data/lib/deep_cover/reporter/html/site.rb +0 -70
  98. data/lib/deep_cover/reporter/html/source.rb +0 -136
  99. data/lib/deep_cover/reporter/html/template/assets/32px.png +0 -0
  100. data/lib/deep_cover/reporter/html/template/assets/40px.png +0 -0
  101. data/lib/deep_cover/reporter/html/template/assets/deep_cover.css.sass +0 -336
  102. data/lib/deep_cover/reporter/html/template/assets/jquery-3.2.1.min.js +0 -4
  103. data/lib/deep_cover/reporter/html/template/assets/jquery-3.2.1.min.map +0 -1
  104. data/lib/deep_cover/reporter/html/template/assets/jstree.css +0 -1108
  105. data/lib/deep_cover/reporter/html/template/assets/jstree.js +0 -8424
  106. data/lib/deep_cover/reporter/html/template/assets/jstreetable.js +0 -1069
  107. data/lib/deep_cover/reporter/html/template/assets/throbber.gif +0 -0
  108. data/lib/deep_cover/reporter/html/template/index.html.erb +0 -75
  109. data/lib/deep_cover/reporter/html/template/source.html.erb +0 -35
  110. data/lib/deep_cover/reporter/istanbul.rb +0 -184
  111. data/lib/deep_cover/reporter/text.rb +0 -58
  112. data/lib/deep_cover/reporter/tree/util.rb +0 -86
  113. data/lib/deep_cover/tools.rb +0 -22
  114. data/lib/deep_cover/tools/blank.rb +0 -25
  115. data/lib/deep_cover/tools/builtin_coverage.rb +0 -55
  116. data/lib/deep_cover/tools/camelize.rb +0 -13
  117. data/lib/deep_cover/tools/content_tag.rb +0 -11
  118. data/lib/deep_cover/tools/covered.rb +0 -9
  119. data/lib/deep_cover/tools/execute_sample.rb +0 -34
  120. data/lib/deep_cover/tools/format.rb +0 -18
  121. data/lib/deep_cover/tools/format_char_cover.rb +0 -19
  122. data/lib/deep_cover/tools/format_generated_code.rb +0 -27
  123. data/lib/deep_cover/tools/indent_string.rb +0 -26
  124. data/lib/deep_cover/tools/merge.rb +0 -16
  125. data/lib/deep_cover/tools/number_lines.rb +0 -22
  126. data/lib/deep_cover/tools/our_coverage.rb +0 -11
  127. data/lib/deep_cover/tools/profiling.rb +0 -68
  128. data/lib/deep_cover/tools/render_template.rb +0 -13
  129. data/lib/deep_cover/tools/require_relative_dir.rb +0 -12
  130. data/lib/deep_cover/tools/scan_match_datas.rb +0 -10
  131. data/lib/deep_cover/tools/silence_warnings.rb +0 -18
  132. data/lib/deep_cover/tools/slice.rb +0 -9
  133. data/lib/deep_cover/tools/strip_heredoc.rb +0 -18
  134. data/lib/deep_cover/tools/truncate_backtrace.rb +0 -32
  135. data/lib/deep_cover/tracker_bucket.rb +0 -50
  136. data/lib/deep_cover/tracker_hits_per_path.rb +0 -35
  137. data/lib/deep_cover/tracker_storage.rb +0 -76
  138. data/lib/deep_cover/tracker_storage_per_path.rb +0 -34
  139. data/lib/deep_cover/version.rb +0 -5
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DeepCover
4
- module Node::Mixin
5
- module HasChildHandler
6
- def self.included(base)
7
- base.extend ClassMethods
8
- end
9
-
10
- def call_child_handler(template, child, child_name = nil)
11
- child_name ||= self.child_index_to_name(child.index)
12
- method_name = format(template, name: child_name)
13
- if respond_to?(method_name)
14
- args = [child, child_name]
15
- arity = method(method_name).arity
16
- if arity >= 0
17
- args = args[0...arity]
18
- end
19
- answer = send(method_name, *args)
20
- end
21
- answer
22
- end
23
- private :call_child_handler
24
-
25
- module ClassMethods
26
- def has_child_handler(template)
27
- child_method_name = format(template, name: 'child')
28
- action = template.gsub(/_%{name}/, '').gsub(/%{name}_/, '')
29
- const_name = "#{Tools.camelize(action)}Handler"
30
- class_eval <<-EVAL, __FILE__, __LINE__ + 1
31
- module #{const_name} # module RewriteHandler
32
- module ClassMethods # module ClassMethods
33
- def has_child(#{action}: nil, **args) # def has_child(rewrite: nil, **args)
34
- name, _types = args.first # name, _types = args.first
35
- define_child_handler(#{template.inspect}, # define_child_handler('rewrite_%{child}',
36
- name, #{action}) # name, rewrite)
37
- super(**args) # super(**args)
38
- end # end
39
- end # end
40
-
41
- def #{child_method_name}(child, name = nil) # def rewrite_child(child, name = nil)
42
- call_child_handler(#{template.inspect}, child, # call_child_handler('rewrite_%{child}', child,
43
- name) || super # name) || super
44
- end # end
45
- end # end
46
- include #{const_name} # include RewriteHandler
47
- singleton_class.prepend #{const_name}::ClassMethods # singleton_class.prepend RewriteHandler::ClassMethods
48
- EVAL
49
- end
50
-
51
- def define_child_handler(template, name, action)
52
- method_name = format(template, name: name)
53
- case action
54
- when nil
55
- # Nothing to do
56
- when Symbol
57
- define_method(method_name) do |*args|
58
- arity = method(action).arity
59
- if arity < 0
60
- send(action, *args)
61
- else
62
- send(action, *args[0...arity])
63
- end
64
- end
65
- when Proc
66
- define_method(method_name, &action)
67
- else
68
- define_method(method_name) { |*| action }
69
- end
70
- end
71
- private :define_child_handler
72
- end
73
- end
74
- end
75
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DeepCover
4
- module Node::Mixin
5
- module HasTracker
6
- def self.included(base)
7
- base.extend ClassMethods
8
- end
9
- TRACKERS = {}
10
-
11
- def initialize(*)
12
- @tracker_offset = tracker_storage.allocate_trackers(self.class::TRACKERS.size).begin
13
- super
14
- end
15
-
16
- def tracker_storage
17
- covered_code.tracker_storage
18
- end
19
-
20
- def tracker_sources
21
- self.class::TRACKERS.map do |name, _|
22
- [:"#{name}_tracker", send(:"#{name}_tracker_source")]
23
- end.to_h
24
- end
25
-
26
- module ClassMethods
27
- def inherited(base)
28
- base.const_set :TRACKERS, self::TRACKERS.dup
29
- super
30
- end
31
-
32
- def has_tracker(name)
33
- i = self::TRACKERS[name] = self::TRACKERS.size
34
- class_eval <<-EVAL, __FILE__, __LINE__ + 1
35
- def #{name}_tracker_source
36
- tracker_storage.tracker_source(@tracker_offset + #{i})
37
- end
38
- def #{name}_tracker_hits
39
- tracker_storage[@tracker_offset + #{i}]
40
- end
41
- EVAL
42
- end
43
- end
44
- end
45
- end
46
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DeepCover
4
- module Node::Mixin
5
- module IsStatement
6
- def self.included(base)
7
- base.has_child_handler('is_%{name}_statement')
8
- end
9
-
10
- def is_statement
11
- parent.is_child_statement(self)
12
- end
13
-
14
- # Default child rewriting rule
15
- def is_child_statement(child, name = nil)
16
- :if_incompatible
17
- end
18
- end
19
- end
20
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DeepCover
4
- module Node::Mixin
5
- module Rewriting
6
- def self.included(base)
7
- base.has_child_handler('rewrite_%{name}')
8
- end
9
-
10
- # Code to add before and after the node for covering purposes
11
- def rewrite
12
- end
13
-
14
- # Default child rewriting rule
15
- def rewrite_child(child, name = nil)
16
- end
17
-
18
- # Replaces all the '%{local}' or '%{some_tracker}' in rewriting rules
19
- def resolve_rewrite(rule, context)
20
- return if rule == nil
21
- sources = context.tracker_sources
22
- format(rule, local: covered_code.local_var, node: '%{node}', **sources)
23
- end
24
-
25
- # Returns an array of [range, rule], where rule is a string containing '%{node}'
26
- # Rules must be ordered inner-most first
27
- def rewriting_rules
28
- [
29
- resolve_rewrite(rewrite, self),
30
- resolve_rewrite(parent.rewrite_child(self), parent),
31
- ].compact.map { |rule| [expression, rule] }
32
- end
33
- end
34
- end
35
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DeepCover
4
- module Node::Mixin
5
- module Wrapper
6
- def initialize(base_node, **kwargs)
7
- super(base_node, base_children: [base_node], **kwargs)
8
- end
9
-
10
- def executed_loc_keys
11
- []
12
- end
13
- end
14
- end
15
- end
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'const'
4
-
5
- module DeepCover
6
- class Node
7
- class ModuleName < Node
8
- has_child scope: [Node, nil]
9
- has_child const_name: Symbol
10
-
11
- def flow_completion_count
12
- parent.execution_count
13
- end
14
-
15
- def execution_count
16
- if scope
17
- scope.flow_completion_count
18
- else
19
- super
20
- end
21
- end
22
- end
23
-
24
- class Module < Node
25
- check_completion
26
- has_tracker :body_entry
27
- has_child const: {const: ModuleName}
28
- has_child body: Node,
29
- can_be_empty: -> { base_node.loc.end.begin },
30
- rewrite: '%{body_entry_tracker};%{local}=nil;%{node}',
31
- is_statement: true,
32
- flow_entry_count: :body_entry_tracker_hits
33
- executed_loc_keys :keyword
34
-
35
- def execution_count
36
- body_entry_tracker_hits
37
- end
38
- end
39
-
40
- class Class < Node
41
- check_completion
42
- has_tracker :body_entry
43
- has_child const: {const: ModuleName}
44
- has_child inherit: [Node, nil] # TODO
45
- has_child body: Node,
46
- can_be_empty: -> { base_node.loc.end.begin },
47
- rewrite: '%{body_entry_tracker};%{node}',
48
- is_statement: true,
49
- flow_entry_count: :body_entry_tracker_hits
50
- executed_loc_keys :keyword
51
-
52
- def execution_count
53
- body_entry_tracker_hits
54
- end
55
- end
56
-
57
- # class << foo
58
- class Sclass < Node
59
- has_child object: Node
60
- has_child body: Node,
61
- can_be_empty: -> { base_node.loc.end.begin },
62
- is_statement: true
63
- # TODO
64
- end
65
- end
66
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DeepCover
4
- class Node::Root < Node
5
- has_tracker :root
6
- has_child main: Node,
7
- can_be_empty: -> { Parser::Source::Range.new(covered_code.buffer, 0, 0) },
8
- is_statement: true,
9
- rewrite: -> {
10
- "#{tracker_storage.setup_source};%{root_tracker};%{local}=nil;%{node}"
11
- }
12
- attr_reader :covered_code
13
- alias_method :flow_entry_count, :root_tracker_hits
14
-
15
- def initialize(child_ast, covered_code)
16
- @covered_code = covered_code
17
- super(nil, parent: nil, base_children: [child_ast])
18
- end
19
- end
20
- end
@@ -1,161 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'literals'
4
- require_relative 'branch'
5
-
6
- module DeepCover
7
- class Node
8
- class SendBase < Node
9
- has_child receiver: [Node, nil]
10
- has_child message: Symbol
11
- has_extra_children arguments: Node
12
- executed_loc_keys :dot, :selector_begin, :selector_end, :operator
13
-
14
- def loc_hash
15
- hash = super.dup
16
- selector = hash.delete(:selector)
17
-
18
- # Special case for foo[bar]=baz, but not for foo.[]= bar, baz: we split selector into begin and end
19
- if base_node.location.dot == nil && [:[], :[]=].include?(message)
20
- hash[:selector_begin] = selector.resize(1)
21
- hash[:selector_end] = Parser::Source::Range.new(selector.source_buffer, selector.end_pos - 1, selector.end_pos)
22
- else
23
- hash.delete(:dot) if type == :safe_send # Hack. API to get a Parser::AST::Send::Map without the dot is crappy.
24
- hash[:selector_begin] = selector
25
- end
26
-
27
- hash
28
- end
29
-
30
- # Rules must be ordered inner-most first
31
- def rewriting_rules
32
- rules = super
33
- if need_parentheses?
34
- range = arguments.last.expression.with(begin_pos: loc_hash[:selector_begin].end_pos)
35
- rules.unshift [range, '(%{node})']
36
- end
37
- rules
38
- end
39
-
40
- private
41
-
42
- # In different circumstances, we need ().
43
- # Deal with ambiguous cases where a method is hidden by a local. Ex:
44
- # foo 42, 'hello' #=> Works
45
- # foo (42), 'hello' #=> Simplification of what DeepCover would generate, still works
46
- # foo = 1; foo 42, 'hello' #=> works
47
- # foo = 1; foo (42), 'hello' #=> syntax error.
48
- # foo = 1; foo((42), 'hello') #=> works
49
- # Deal with do/end block. Ex:
50
- # x.foo 42, 43 # => ok
51
- # x.foo (42), 43 # => ok
52
- # x.foo ((42)), 43 # => ok
53
- # x.foo 42, 43 do ; end # => ok
54
- # x.foo (42), 43 do ; end # => ok
55
- # x.foo ((42)), 43 do ; end # => parse error!
56
- def need_parentheses?
57
- true unless
58
- arguments.empty? || # No issue when no arguments
59
- loc_hash[:selector_end] || # No issue with foo[bar]= and such
60
- loc_hash[:operator] || # No issue with foo.bar=
61
- (receiver && !loc_hash[:dot]) || # No issue with foo + bar
62
- loc_hash[:begin] # Ok if has parentheses
63
- end
64
- end
65
-
66
- class Send < SendBase
67
- check_completion
68
- end
69
-
70
- class CsendInnerSend < SendBase
71
- has_tracker :completion
72
- include ExecutedAfterChildren
73
-
74
- def has_block?
75
- parent.has_block?
76
- end
77
-
78
- def rewrite
79
- # All the rest of the rewriting logic is in Csend
80
- '%{node};%{completion_tracker};' unless has_block?
81
- end
82
-
83
- def flow_completion_count
84
- return parent.parent.flow_completion_count if has_block?
85
- completion_tracker_hits
86
- end
87
-
88
- def loc_hash
89
- # This is only a partial Send, the receiver param and the dot are actually handled by the parent Csend.
90
- h = super.dup
91
- h[:expression] = h[:expression].with(begin_pos: h[:selector_begin].begin_pos)
92
- h
93
- end
94
- end
95
-
96
- class Csend < Node
97
- # The overall rewriting goal is this:
98
- # temp = *receiver*;
99
- # if nil != temp
100
- # TRACK_my_NOT_NIL
101
- # temp = temp&.*actual_send*{block}
102
- # TRACK_actual_send_COMPLETION
103
- # t
104
- # else
105
- # nil
106
- # end
107
- # This is split across the children and the CsendInnerSend
108
- include Branch
109
- has_tracker :not_nil
110
- has_child receiver: Node,
111
- rewrite: '(%{local}=%{node};if nil != %{local};%{not_nil_tracker};%{local}=%{local}'
112
- REWRITE_SUFFIX = '%{node};%{local};else;nil;end)'
113
-
114
- has_child actual_send: {safe_send: CsendInnerSend},
115
- flow_entry_count: :not_nil_tracker_hits
116
-
117
- def initialize(base_node, base_children: base_node.children, **) # rubocop:disable Naming/UncommunicativeMethodParamName [#5436]
118
- send_without_receiver = base_node.updated(:safe_send, [nil, *base_node.children.drop(1)])
119
- base_children = [base_children.first, send_without_receiver]
120
- super
121
- end
122
-
123
- executed_loc_keys :dot
124
-
125
- def has_block?
126
- parent.is_a?(Block) && parent.child_index_to_name(index) == :call
127
- end
128
-
129
- def rewrite
130
- REWRITE_SUFFIX unless has_block?
131
- end
132
-
133
- def execution_count
134
- receiver.flow_completion_count
135
- end
136
-
137
- def message
138
- actual_send.message
139
- end
140
-
141
- def branches
142
- [TrivialBranch.new(condition: receiver, other_branch: actual_send),
143
- actual_send,
144
- ]
145
- end
146
-
147
- def branches_summary(of_branches = branches)
148
- of_branches.map do |jump|
149
- jump == actual_send ? 'safe send' : 'nil shortcut'
150
- end.join(' and ')
151
- end
152
- end
153
-
154
- class MatchWithLvasgn < Node
155
- check_completion
156
- has_child receiver: Regexp
157
- has_child compare_to: Node
158
- # TODO: test
159
- end
160
- end
161
- end