deep-cover 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
- - ">="
|