deep-cover 0.1.1 → 0.1.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.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.travis.yml +3 -1
- data/Rakefile +1 -1
- data/bin/selfcov +1 -1
- data/deep_cover.gemspec +2 -1
- data/lib/deep_cover/analyser.rb +1 -2
- data/lib/deep_cover/analyser/base.rb +20 -6
- data/lib/deep_cover/analyser/covered_code_source.rb +0 -12
- data/lib/deep_cover/analyser/node.rb +11 -1
- data/lib/deep_cover/analyser/optionally_covered.rb +14 -0
- data/lib/deep_cover/auto_run.rb +36 -32
- data/lib/deep_cover/backports.rb +9 -0
- data/lib/deep_cover/base.rb +8 -1
- data/lib/deep_cover/cli/debugger.rb +6 -4
- data/lib/deep_cover/cli/deep_cover.rb +37 -6
- data/lib/deep_cover/cli/instrumented_clone_reporter.rb +50 -32
- data/lib/deep_cover/config.rb +16 -7
- data/lib/deep_cover/coverage.rb +8 -9
- data/lib/deep_cover/covered_code.rb +17 -18
- data/lib/deep_cover/node/base.rb +28 -4
- data/lib/deep_cover/node/branch.rb +10 -7
- data/lib/deep_cover/node/def.rb +2 -2
- data/lib/deep_cover/node/empty_body.rb +1 -1
- data/lib/deep_cover/node/mixin/can_augment_children.rb +1 -2
- data/lib/deep_cover/node/mixin/execution_location.rb +9 -6
- data/lib/deep_cover/node/mixin/has_child.rb +16 -17
- data/lib/deep_cover/node/mixin/has_tracker.rb +2 -6
- data/lib/deep_cover/node/mixin/rewriting.rb +9 -8
- data/lib/deep_cover/node/send.rb +57 -48
- data/lib/deep_cover/node/{boolean.rb → short_circuit.rb} +0 -0
- data/lib/deep_cover/reporter/istanbul.rb +2 -3
- data/lib/deep_cover/tools.rb +2 -1
- data/lib/deep_cover/tools/dasherize.rb +8 -0
- data/lib/deep_cover/tools/dump_covered_code.rb +12 -6
- data/lib/deep_cover/tools/format_char_cover.rb +2 -3
- data/lib/deep_cover/tools/slice.rb +7 -0
- data/lib/deep_cover/version.rb +1 -1
- metadata +7 -18
@@ -13,19 +13,20 @@ module DeepCover
|
|
13
13
|
def rewrite_child(child, name=nil)
|
14
14
|
end
|
15
15
|
|
16
|
+
# Replaces all the '%{local}' or '%{some_tracker}' in rewriting rules
|
16
17
|
def resolve_rewrite(rule, context)
|
17
|
-
rule
|
18
|
+
return if rule == nil
|
18
19
|
sources = context.tracker_sources
|
19
|
-
rule
|
20
|
+
rule % {local: covered_code.local_var, node: '%{node}', **sources}
|
20
21
|
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
# Returns an array of [range, rule], where rule is a string containing '%{node}'
|
24
|
+
# Rules must be ordered inner-most first
|
25
|
+
def rewriting_rules
|
25
26
|
[
|
26
|
-
|
27
|
-
|
28
|
-
]
|
27
|
+
resolve_rewrite(rewrite, self),
|
28
|
+
resolve_rewrite(parent.rewrite_child(self), parent),
|
29
|
+
].compact.map{|rule| [expression, rule]}
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
data/lib/deep_cover/node/send.rb
CHANGED
@@ -1,75 +1,84 @@
|
|
1
1
|
require_relative 'literals'
|
2
|
+
require_relative 'branch'
|
2
3
|
|
3
4
|
module DeepCover
|
4
5
|
class Node
|
5
|
-
class MethodName < Node
|
6
|
-
has_child name: Symbol
|
7
|
-
|
8
|
-
def initialize(name, parent: raise, **kwargs)
|
9
|
-
super(parent, **kwargs, parent: parent, base_children: [name])
|
10
|
-
end
|
11
|
-
|
12
|
-
def loc_hash
|
13
|
-
# Expression is used in the rewriting
|
14
|
-
# if selector_end is present, then this won't be needed
|
15
|
-
{expression: parent.loc_hash[:selector_begin]}
|
16
|
-
end
|
17
|
-
|
18
|
-
def executable?
|
19
|
-
false
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
6
|
class Send < Node
|
24
7
|
check_completion
|
25
8
|
has_child receiver: [Node, nil]
|
26
|
-
has_child
|
27
|
-
has_extra_children arguments: Node
|
9
|
+
has_child message: Symbol
|
10
|
+
has_extra_children arguments: Node
|
28
11
|
executed_loc_keys :dot, :selector_begin, :selector_end, :operator
|
29
12
|
|
30
|
-
def method_name
|
31
|
-
method_name_wrapper.name
|
32
|
-
end
|
33
|
-
|
34
13
|
def loc_hash
|
35
|
-
|
36
|
-
|
37
|
-
selector = base[:selector]
|
14
|
+
hash = super.dup
|
15
|
+
selector = hash.delete(:selector)
|
38
16
|
|
39
|
-
|
17
|
+
# Special case for foo[bar]=baz, but not for foo.[]= bar, baz: we split selector into begin and end
|
18
|
+
if base_node.location.dot == nil && [:[], :[]=].include?(message)
|
40
19
|
hash[:selector_begin] = selector.resize(1)
|
41
20
|
hash[:selector_end] = Parser::Source::Range.new(selector.source_buffer, selector.end_pos - 1, selector.end_pos)
|
42
21
|
else
|
43
|
-
hash
|
22
|
+
hash.delete(:dot) if type == :safe_send # Hack. API to get a Parser::AST::Send::Map without the dot is crappy.
|
23
|
+
hash[:selector_begin] = selector
|
44
24
|
end
|
45
25
|
|
46
26
|
hash
|
47
27
|
end
|
48
28
|
|
29
|
+
# Rules must be ordered inner-most first
|
30
|
+
def rewriting_rules
|
31
|
+
rules = super
|
32
|
+
if need_parentheses?
|
33
|
+
range = arguments.last.expression.with(begin_pos: loc_hash[:selector_begin].end_pos)
|
34
|
+
rules.unshift [range, '(%{node})']
|
35
|
+
end
|
36
|
+
rules
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
49
41
|
# Only need to add them to deal with ambiguous cases where a method is hidden by a local. Ex:
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
def
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
return if self.loc_hash[:begin]
|
61
|
-
true
|
42
|
+
# foo 42, 'hello' #=> Works
|
43
|
+
# foo (42), 'hello' #=> Simplification of what DeepCover would generate, still works
|
44
|
+
# foo = 1; foo 42, 'hello' #=> works
|
45
|
+
# foo = 1; foo (42), 'hello' #=> syntax error.
|
46
|
+
# foo = 1; foo((42), 'hello') #=> works
|
47
|
+
def need_parentheses?
|
48
|
+
true unless
|
49
|
+
arguments.empty? || # No issue when no arguments
|
50
|
+
receiver || # No ambiguity if there is a receiver
|
51
|
+
loc_hash[:begin] # Ok if has parentheses
|
62
52
|
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Csend < Node
|
56
|
+
include Branch
|
57
|
+
has_tracker :conditional
|
58
|
+
has_child receiver: Node,
|
59
|
+
rewrite: '(%{local}=%{node};%{conditional_tracker} if %{local} != nil;%{local})'
|
60
|
+
|
61
|
+
has_child actual_send: {safe_send: Send},
|
62
|
+
flow_entry_count: :conditional_tracker_hits
|
63
|
+
|
64
|
+
def initialize(base_node, base_children: base_node.children, **)
|
65
|
+
send_without_receiver = base_node.updated(:safe_send, [nil, *base_node.children.drop(1)])
|
66
|
+
base_children = [base_children.first, send_without_receiver]
|
67
|
+
super
|
68
|
+
end
|
69
|
+
|
70
|
+
executed_loc_keys :dot
|
71
|
+
|
72
|
+
alias_method :execution_count, :flow_entry_count
|
63
73
|
|
64
|
-
def
|
65
|
-
|
66
|
-
"%{node}("
|
74
|
+
def message
|
75
|
+
actual_send.message
|
67
76
|
end
|
68
77
|
|
69
|
-
def
|
70
|
-
|
71
|
-
|
72
|
-
|
78
|
+
def branches
|
79
|
+
[ actual_send,
|
80
|
+
TrivialBranch.new(receiver, actual_send)
|
81
|
+
]
|
73
82
|
end
|
74
83
|
end
|
75
84
|
|
File without changes
|
@@ -46,12 +46,11 @@ module DeepCover
|
|
46
46
|
|
47
47
|
def convert_branch(node, branches = node.branches)
|
48
48
|
# Currently, nyc seems to outputs the same location over and over...
|
49
|
-
loc = convert_range(node.expression)
|
50
49
|
{
|
51
|
-
loc:
|
50
|
+
loc: convert_range(node.expression),
|
52
51
|
type: node.type,
|
53
52
|
line: node.expression.line,
|
54
|
-
locations: branches.map{|n|
|
53
|
+
locations: branches.map{|n| convert_range(n.expression || node.expression)}
|
55
54
|
}
|
56
55
|
end
|
57
56
|
|
data/lib/deep_cover/tools.rb
CHANGED
@@ -3,8 +3,9 @@ module DeepCover
|
|
3
3
|
|
4
4
|
require_relative 'tools/require_relative_dir'
|
5
5
|
extend Tools::RequireRelativeDir
|
6
|
-
|
6
|
+
require_relative 'tools/silence_warnings'
|
7
7
|
extend Tools::SilenceWarnings
|
8
|
+
require_relative_dir 'tools'
|
8
9
|
|
9
10
|
# The functions defined in the submodules of Tools can be accessed
|
10
11
|
# either by extending the desired module, or all of them by extending
|
@@ -1,20 +1,27 @@
|
|
1
|
-
require 'with_progress'
|
2
|
-
|
3
1
|
module DeepCover
|
2
|
+
silence_warnings do
|
3
|
+
require 'with_progress'
|
4
|
+
end
|
4
5
|
module Tools::DumpCoveredCode
|
5
|
-
def
|
6
|
+
def dump_covered_code_and_save(source_path, dest_path: Dir.mktmpdir)
|
6
7
|
coverage = Coverage.new(tracker_global: '$_sc')
|
8
|
+
dump_covered_code(source_path, coverage: coverage, dest_path: dest_path)
|
9
|
+
coverage.save(dest_path)
|
10
|
+
end
|
11
|
+
|
12
|
+
def dump_covered_code(source_path, coverage: raise, dest_path: Dir.mktmpdir, root_path: source_path)
|
7
13
|
source_path = File.join(File.expand_path(source_path), '')
|
8
14
|
dest_path = File.join(File.expand_path(dest_path), '')
|
15
|
+
root_path = Pathname.new(root_path)
|
9
16
|
skipped = []
|
10
17
|
Dir.glob("#{source_path}**/*.rb").each.with_progress(title: 'Rewriting') do |path|
|
18
|
+
new_path = Pathname(path.gsub(source_path, dest_path))
|
11
19
|
begin
|
12
|
-
covered_code = coverage.covered_code(path)
|
20
|
+
covered_code = coverage.covered_code(path, name: new_path.relative_path_from(root_path))
|
13
21
|
rescue Parser::SyntaxError
|
14
22
|
skipped << path
|
15
23
|
next
|
16
24
|
end
|
17
|
-
new_path = Pathname(path.gsub(source_path, dest_path))
|
18
25
|
new_path.dirname.mkpath
|
19
26
|
new_path.write(covered_code.covered_source)
|
20
27
|
end
|
@@ -25,7 +32,6 @@ module DeepCover
|
|
25
32
|
('...' if skipped.size > 3),
|
26
33
|
].compact.join("\n")
|
27
34
|
end
|
28
|
-
coverage.save(dest_path)
|
29
35
|
dest_path
|
30
36
|
end
|
31
37
|
end
|
@@ -2,9 +2,8 @@ module DeepCover
|
|
2
2
|
module Tools::FormatCharCover
|
3
3
|
COLOR = {'x' => :red, ' ' => :green, '-' => :faint}
|
4
4
|
WHITESPACE_MAP = Hash.new{|_, v| v}.merge!(' ' => '·', "\t" => '→ ')
|
5
|
-
def format_char_cover(covered_code, show_whitespace: false)
|
6
|
-
bc = covered_code.char_cover
|
7
|
-
|
5
|
+
def format_char_cover(covered_code, show_whitespace: false, **options)
|
6
|
+
bc = covered_code.char_cover(**options)
|
8
7
|
covered_code.buffer.source_lines.map.with_index do |line, line_index|
|
9
8
|
next line if line.strip =~ /^#[ >]/
|
10
9
|
line.chars.map.with_index do |c, c_index|
|
data/lib/deep_cover/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deep-cover
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc-André Lafortune
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-11-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: parser
|
@@ -81,20 +81,6 @@ dependencies:
|
|
81
81
|
- - ">="
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '0'
|
84
|
-
- !ruby/object:Gem::Dependency
|
85
|
-
name: ruby-progressbar
|
86
|
-
requirement: !ruby/object:Gem::Requirement
|
87
|
-
requirements:
|
88
|
-
- - "<"
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
version: 1.9.0
|
91
|
-
type: :runtime
|
92
|
-
prerelease: false
|
93
|
-
version_requirements: !ruby/object:Gem::Requirement
|
94
|
-
requirements:
|
95
|
-
- - "<"
|
96
|
-
- !ruby/object:Gem::Version
|
97
|
-
version: 1.9.0
|
98
84
|
- !ruby/object:Gem::Dependency
|
99
85
|
name: with_progress
|
100
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -228,6 +214,7 @@ files:
|
|
228
214
|
- lib/deep_cover/analyser/function.rb
|
229
215
|
- lib/deep_cover/analyser/ignore_uncovered.rb
|
230
216
|
- lib/deep_cover/analyser/node.rb
|
217
|
+
- lib/deep_cover/analyser/optionally_covered.rb
|
231
218
|
- lib/deep_cover/analyser/per_char.rb
|
232
219
|
- lib/deep_cover/analyser/per_line.rb
|
233
220
|
- lib/deep_cover/analyser/statement.rb
|
@@ -254,7 +241,6 @@ files:
|
|
254
241
|
- lib/deep_cover/node/base.rb
|
255
242
|
- lib/deep_cover/node/begin.rb
|
256
243
|
- lib/deep_cover/node/block.rb
|
257
|
-
- lib/deep_cover/node/boolean.rb
|
258
244
|
- lib/deep_cover/node/branch.rb
|
259
245
|
- lib/deep_cover/node/case.rb
|
260
246
|
- lib/deep_cover/node/collections.rb
|
@@ -281,6 +267,7 @@ files:
|
|
281
267
|
- lib/deep_cover/node/module.rb
|
282
268
|
- lib/deep_cover/node/root.rb
|
283
269
|
- lib/deep_cover/node/send.rb
|
270
|
+
- lib/deep_cover/node/short_circuit.rb
|
284
271
|
- lib/deep_cover/node/splat.rb
|
285
272
|
- lib/deep_cover/node/variables.rb
|
286
273
|
- lib/deep_cover/parser_ext/range.rb
|
@@ -289,6 +276,7 @@ files:
|
|
289
276
|
- lib/deep_cover/tools.rb
|
290
277
|
- lib/deep_cover/tools/builtin_coverage.rb
|
291
278
|
- lib/deep_cover/tools/camelize.rb
|
279
|
+
- lib/deep_cover/tools/dasherize.rb
|
292
280
|
- lib/deep_cover/tools/dump_covered_code.rb
|
293
281
|
- lib/deep_cover/tools/execute_sample.rb
|
294
282
|
- lib/deep_cover/tools/format.rb
|
@@ -298,6 +286,7 @@ files:
|
|
298
286
|
- lib/deep_cover/tools/our_coverage.rb
|
299
287
|
- lib/deep_cover/tools/require_relative_dir.rb
|
300
288
|
- lib/deep_cover/tools/silence_warnings.rb
|
289
|
+
- lib/deep_cover/tools/slice.rb
|
301
290
|
- lib/deep_cover/version.rb
|
302
291
|
homepage: http://github.com
|
303
292
|
licenses:
|
@@ -311,7 +300,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
311
300
|
requirements:
|
312
301
|
- - ">="
|
313
302
|
- !ruby/object:Gem::Version
|
314
|
-
version:
|
303
|
+
version: 2.0.0
|
315
304
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
316
305
|
requirements:
|
317
306
|
- - ">="
|