deep-cover-core 0.7.0 → 0.7.1
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/deep_cover_core.gemspec +4 -2
- data/lib/deep_cover/analyser/branch.rb +1 -2
- data/lib/deep_cover/analyser/node.rb +1 -1
- data/lib/deep_cover/analyser/ruby25_like_branch.rb +45 -20
- data/lib/deep_cover/autoload_tracker.rb +31 -18
- data/lib/deep_cover/base.rb +1 -9
- data/lib/deep_cover/core_ext/autoload_overrides.rb +21 -4
- data/lib/deep_cover/core_ext/coverage_replacement.rb +4 -1
- data/lib/deep_cover/core_ext/exec_callbacks.rb +1 -1
- data/lib/deep_cover/custom_requirer.rb +7 -1
- data/lib/deep_cover/global_variables.rb +1 -1
- data/lib/deep_cover/load.rb +3 -2
- data/lib/deep_cover/node/block.rb +1 -1
- data/lib/deep_cover/node/if.rb +4 -0
- data/lib/deep_cover/node/send.rb +7 -9
- data/lib/deep_cover/parser_ext/range.rb +12 -0
- data/lib/deep_cover/persistence.rb +1 -1
- data/lib/deep_cover/reporter/istanbul.rb +2 -2
- data/lib/deep_cover/tools/after_tests.rb +1 -1
- data/lib/deep_cover/tools/builtin_coverage.rb +16 -23
- data/lib/deep_cover/version.rb +2 -2
- metadata +5 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 51497f0cad911b1a78dac991b6b89f800c5cc1b0c7b99e8502816d02842ca239
|
4
|
+
data.tar.gz: 932a187d2d0669c5e21a82f81b1f7337db27d077d4ab07a9b92596721731862e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dbdc66591ef576cd5f3ad7dc0898b1746d3b1f3a5670490ea67a49a7773d200ae717029aa40b5b41359b8c67dff889aa118e7a5ef9e02e224f3c2a31cabc8372
|
7
|
+
data.tar.gz: e52c1575a8b86dd3ea5c908407a8efcbfa1ab3a0618d0b621384d1cb004143dba4e54a0464ac98030a59a8ba62f27119cbae6ef65e8cd51c07546cbd39970ae7
|
data/deep_cover_core.gemspec
CHANGED
@@ -39,8 +39,10 @@ Gem::Specification.new do |spec|
|
|
39
39
|
|
40
40
|
### Dev dependencies
|
41
41
|
spec.add_development_dependency 'bundler', '~> 1.15'
|
42
|
-
spec.add_development_dependency 'psych', '>= 2.0'
|
43
42
|
spec.add_development_dependency 'rake', '~> 12.0'
|
44
43
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
45
|
-
|
44
|
+
|
45
|
+
# About every single release breaks something
|
46
|
+
# Ruby 2.1 is no longer supported
|
47
|
+
spec.add_development_dependency 'rubocop', '0.61.1' if RUBY_VERSION >= '2.2.0'
|
46
48
|
end
|
@@ -55,11 +55,11 @@ module DeepCover
|
|
55
55
|
cond_info = [:case, *node_loc_infos]
|
56
56
|
|
57
57
|
sub_keys = [:when] * (branches.size - 1) + [:else]
|
58
|
-
empty_fallbacks = whens.map { |w| (w.loc_hash[:begin] || w.loc_hash[:expression]).
|
58
|
+
empty_fallbacks = whens.map { |w| wrap_rwhitespace_and_comments_if_ruby25(w.loc_hash[:begin] || w.loc_hash[:expression]).end }
|
59
59
|
empty_fallbacks.map!(&:begin)
|
60
60
|
|
61
61
|
if loc_hash[:else]
|
62
|
-
empty_fallbacks << loc_hash[:
|
62
|
+
empty_fallbacks << wrap_rwhitespace_and_comments_if_ruby25(loc_hash[:else]).end
|
63
63
|
else
|
64
64
|
# DeepCover manually inserts a `else` for Case when there isn't one for tracker purposes.
|
65
65
|
# The normal behavior of ruby25's branch coverage when there is no else is to return the loc of the node
|
@@ -86,7 +86,7 @@ module DeepCover
|
|
86
86
|
|
87
87
|
def handle_csend
|
88
88
|
# csend wraps the comment but not the newlines
|
89
|
-
node_range = node.expression
|
89
|
+
node_range = wrap_rwhitespace_and_comments_if_ruby25(node.expression, whitespaces: /\A[ \t\r\f]+/)
|
90
90
|
cond_info = [:"&.", *node_loc_infos(node_range)]
|
91
91
|
false_branch, true_branch = branches
|
92
92
|
[cond_info, {[:then, *node_loc_infos(node_range)] => true_branch.execution_count,
|
@@ -105,22 +105,19 @@ module DeepCover
|
|
105
105
|
if style == :ternary
|
106
106
|
empty_fallback_locs = [nil, nil]
|
107
107
|
else
|
108
|
+
first_clause_fallback = wrap_rwhitespace_and_comments_if_ruby25(loc_hash[:begin]) if loc_hash[:begin]
|
109
|
+
first_clause_fallback ||= wrap_rwhitespace_and_comments_if_ruby25(condition.expression)
|
110
|
+
# Ruby26 wraps the comments but only on the same line
|
111
|
+
# No need for condition since Ruby25 wraps all of them
|
112
|
+
first_clause_fallback = first_clause_fallback.wrap_final_comment.end
|
108
113
|
else_loc = loc_hash[:else]
|
109
|
-
|
110
|
-
first_clause_fallback = loc_hash[:begin]
|
111
|
-
if first_clause_fallback
|
112
|
-
first_clause_fallback = first_clause_fallback.wrap_rwhitespace_and_comments.end
|
113
|
-
elsif else_loc
|
114
|
-
first_clause_fallback = else_loc.begin
|
115
|
-
end
|
116
|
-
|
117
114
|
if else_loc
|
118
|
-
second_clause_fallback = else_loc.
|
115
|
+
second_clause_fallback = wrap_rwhitespace_and_comments_if_ruby25(else_loc).end
|
116
|
+
elsif !modifier?
|
117
|
+
second_clause_fallback = root_if_node.loc_hash[:end].begin
|
119
118
|
end
|
120
|
-
end_loc = root_if_node.loc_hash[:end]
|
121
|
-
end_loc = end_loc.begin if end_loc
|
122
119
|
|
123
|
-
empty_fallback_locs = [first_clause_fallback
|
120
|
+
empty_fallback_locs = [first_clause_fallback, second_clause_fallback]
|
124
121
|
end
|
125
122
|
# loc can be nil if the clause can't be empty, such as ternary and modifer if/unless
|
126
123
|
|
@@ -131,6 +128,25 @@ module DeepCover
|
|
131
128
|
|
132
129
|
branches_locs = branches
|
133
130
|
execution_counts = branches_locs.map(&:execution_count)
|
131
|
+
if modifier?
|
132
|
+
branches_locs = branches_locs.map do |branch|
|
133
|
+
if branch.is_a?(Node::Kwbegin)
|
134
|
+
if branch.instructions.empty?
|
135
|
+
wrap_rwhitespace_and_comments_if_ruby25(branch.loc_hash[:begin]).end
|
136
|
+
elsif branch.instructions.first.is_a?(Node::Ensure)
|
137
|
+
# Kernel.binding.pry
|
138
|
+
end_pos = wrap_rwhitespace_and_comments_if_ruby25(branch.instructions.last.expression).end_pos
|
139
|
+
wrap_rwhitespace_and_comments_if_ruby25(branch.loc_hash[:begin]).end.with(end_pos: end_pos)
|
140
|
+
else
|
141
|
+
end_pos = branch.instructions.last.expression.end_pos
|
142
|
+
branch.loc_hash[:begin].wrap_rwhitespace_and_comments.end.with(end_pos: end_pos)
|
143
|
+
end
|
144
|
+
else
|
145
|
+
branch
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
134
150
|
branches_locs[1] = extend_elsif_range(branches_locs[1])
|
135
151
|
|
136
152
|
clauses_infos = infos_for_branches(branches_locs, sub_keys, empty_fallback_locs, execution_counts: execution_counts, node_range: node_range)
|
@@ -153,11 +169,13 @@ module DeepCover
|
|
153
169
|
end_pos = body.instructions.last.expression.end_pos
|
154
170
|
body.instructions.first.expression.with(end_pos: end_pos)
|
155
171
|
else
|
156
|
-
body.loc_hash[:
|
172
|
+
wrap_rwhitespace_and_comments_if_ruby25(body.loc_hash[:begin]).end
|
157
173
|
end
|
158
|
-
elsif body.is_a?(Node::Begin) && !
|
174
|
+
elsif body.is_a?(Node::Begin) && !body.expressions.empty?
|
159
175
|
end_pos = body.expressions.last.expression.end_pos
|
160
176
|
body.expressions.first.expression.with(end_pos: end_pos)
|
177
|
+
elsif body.is_a?(Node::EmptyBody)
|
178
|
+
wrap_rwhitespace_and_comments_if_ruby25(condition.loc_hash[:expression]).end
|
161
179
|
else
|
162
180
|
body
|
163
181
|
end
|
@@ -167,13 +185,12 @@ module DeepCover
|
|
167
185
|
|
168
186
|
protected
|
169
187
|
|
170
|
-
# If the actual else clause (final one) of an if...elsif...end is empty, then
|
171
|
-
# node reach the `end` in its branch coverage output
|
188
|
+
# If the actual else clause (final one) of an if...elsif...end is empty, then Ruby25 wraps the final whitespace
|
172
189
|
def extend_elsif_range(possible_elsif = node)
|
173
190
|
return possible_elsif unless possible_elsif.is_a?(Node::If) && possible_elsif.style == :elsif
|
174
191
|
deepest_if = possible_elsif.deepest_elsif_node
|
175
192
|
if deepest_if.false_branch.is_a?(Node::EmptyBody)
|
176
|
-
return possible_elsif.expression
|
193
|
+
return wrap_rwhitespace_and_comments_if_ruby25(possible_elsif.expression)
|
177
194
|
end
|
178
195
|
possible_elsif
|
179
196
|
end
|
@@ -206,6 +223,14 @@ module DeepCover
|
|
206
223
|
@loc_index += 1
|
207
224
|
[@loc_index, source_range.line, source_range.column, source_range.last_line, source_range.last_column]
|
208
225
|
end
|
226
|
+
|
227
|
+
def wrap_rwhitespace_and_comments_if_ruby25(expression, whitespaces: /\A\s+/)
|
228
|
+
if RUBY_VERSION.start_with?('2.5')
|
229
|
+
expression.wrap_rwhitespace_and_comments(whitespaces: whitespaces)
|
230
|
+
else
|
231
|
+
expression
|
232
|
+
end
|
233
|
+
end
|
209
234
|
end
|
210
235
|
end
|
211
236
|
end
|
@@ -45,34 +45,44 @@ module DeepCover
|
|
45
45
|
autoloads && !autoloads.empty?
|
46
46
|
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
entries.each do |entry|
|
53
|
-
mod = entry.mod_if_available
|
54
|
-
next unless mod
|
55
|
-
mod.autoload_without_deep_cover(entry.name, already_loaded_feature)
|
56
|
-
end
|
57
|
-
|
48
|
+
if RUBY_PLATFORM == 'java'
|
49
|
+
# JRuby dislikes that we change the autoload as it is executing an autoload
|
50
|
+
# Things seems to work when we do nothing special
|
51
|
+
def wrap_require(requested_path, absolute_path_found) # &block
|
58
52
|
yield
|
59
|
-
|
53
|
+
end
|
54
|
+
else
|
55
|
+
def wrap_require(requested_path, absolute_path_found) # &block
|
60
56
|
entries = entries_for_target(requested_path, absolute_path_found)
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
57
|
+
|
58
|
+
begin
|
59
|
+
entries.each do |entry|
|
60
|
+
mod = entry.mod_if_available
|
61
|
+
next unless mod
|
62
|
+
mod.autoload_without_deep_cover(entry.name, already_loaded_feature)
|
63
|
+
end
|
64
|
+
|
65
|
+
yield
|
66
|
+
ensure
|
67
|
+
entries = entries_for_target(requested_path, absolute_path_found)
|
68
|
+
entries.each do |entry|
|
69
|
+
mod = entry.mod_if_available
|
70
|
+
next unless mod
|
71
|
+
# Putting the autoloads back back since we couldn't complete the require
|
72
|
+
mod.autoload_without_deep_cover(entry.name, entry.interceptor_path)
|
73
|
+
end
|
66
74
|
end
|
67
75
|
end
|
68
76
|
end
|
69
77
|
|
70
|
-
#
|
78
|
+
# In JRuby, ObjectSpace.each_object is allowed for Module and Class, so we are good.
|
71
79
|
def initialize_autoloaded_paths(mods = ObjectSpace.each_object(Module)) # &do_autoload_block
|
72
80
|
mods.each do |mod|
|
73
81
|
# Module's constants are shared with Object. But if you set autoloads directly on Module, they
|
74
82
|
# appear on multiple classes. So just skip, Object will take care of those.
|
75
83
|
next if mod == Module
|
84
|
+
# This happens with JRuby
|
85
|
+
next unless mod.respond_to?(:constants)
|
76
86
|
|
77
87
|
if mod.frozen?
|
78
88
|
if mod.constants.any? { |name| mod.autoload?(name) }
|
@@ -82,7 +92,10 @@ module DeepCover
|
|
82
92
|
end
|
83
93
|
|
84
94
|
mod.constants.each do |name|
|
85
|
-
|
95
|
+
# JRuby can talk about deprecated constants here
|
96
|
+
path = Tools.silence_warnings do
|
97
|
+
mod.autoload?(name)
|
98
|
+
end
|
86
99
|
next unless path
|
87
100
|
interceptor_path = setup_interceptor_for(mod, name, path)
|
88
101
|
yield mod, name, interceptor_path
|
data/lib/deep_cover/base.rb
CHANGED
@@ -8,15 +8,7 @@ module DeepCover
|
|
8
8
|
|
9
9
|
def start
|
10
10
|
return if running?
|
11
|
-
if
|
12
|
-
# Autoload is not supported in JRuby. We currently need to use binding_of_caller
|
13
|
-
# and that is not available in JRuby. An extension may be able to replace this requirement.
|
14
|
-
# require_relative 'core_ext/autoload_overrides'
|
15
|
-
# AutoloadOverride.active = true
|
16
|
-
require_relative 'core_ext/load_overrides'
|
17
|
-
require_relative 'core_ext/require_overrides'
|
18
|
-
LoadOverride.active = RequireOverride.active = true
|
19
|
-
elsif RUBY_VERSION >= '2.3.0'
|
11
|
+
if RUBY_VERSION >= '2.3.0' && RUBY_PLATFORM != 'java'
|
20
12
|
require_relative 'core_ext/instruction_sequence_load_iseq'
|
21
13
|
else
|
22
14
|
require_relative 'core_ext/autoload_overrides'
|
@@ -84,10 +84,27 @@ module DeepCover
|
|
84
84
|
load_all
|
85
85
|
|
86
86
|
module KernelAutoloadOverride
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
87
|
+
if RUBY_PLATFORM == 'java'
|
88
|
+
# JRuby has different semantics for Kernel.autoload and Kernel#autoload
|
89
|
+
def autoload(name, path)
|
90
|
+
if Kernel.equal?(self)
|
91
|
+
# Yeah, this is weird
|
92
|
+
# https://github.com/jruby/jruby/issues/5466
|
93
|
+
mod = Object.singleton_class
|
94
|
+
elsif self.is_a?(Module)
|
95
|
+
mod = self
|
96
|
+
else
|
97
|
+
mod = self.class
|
98
|
+
end
|
99
|
+
autoload_path = DeepCover.autoload_tracker.autoload_path_for(mod, name, path)
|
100
|
+
mod.autoload_without_deep_cover(name, autoload_path)
|
101
|
+
end
|
102
|
+
else
|
103
|
+
def autoload(name, path)
|
104
|
+
mod = binding.of_caller(1).eval('Module.nesting').first || Object
|
105
|
+
autoload_path = DeepCover.autoload_tracker.autoload_path_for(mod, name, path)
|
106
|
+
mod.autoload_without_deep_cover(name, autoload_path)
|
107
|
+
end
|
91
108
|
end
|
92
109
|
|
93
110
|
extend ModuleOverride
|
@@ -20,7 +20,10 @@ module DeepCover
|
|
20
20
|
else
|
21
21
|
targets = targets.to_hash.slice(*ALL_COVERAGES.keys).select { |_, v| v }
|
22
22
|
targets = targets.map { |k, v| [k, !!v] }.to_h
|
23
|
-
|
23
|
+
if targets.empty?
|
24
|
+
raise 'no measuring target is specified' if RUBY_VERSION.start_with?('2.5')
|
25
|
+
targets = OLD_COVERAGE_SENTINEL
|
26
|
+
end
|
24
27
|
end
|
25
28
|
|
26
29
|
if DeepCover.running?
|
@@ -5,7 +5,7 @@
|
|
5
5
|
# THERE MUST NOT BE ANY USE/REQUIRE OF DEPENDENCIES OF DeepCover HERE
|
6
6
|
# See deep-cover/core_gem/lib/deep_cover/setup/clone_mode_entry_template.rb for explanation of
|
7
7
|
# clone mode and of this top_level_module stuff.
|
8
|
-
top_level_module = Thread.current['_deep_cover_top_level_module'] || Object
|
8
|
+
top_level_module = Thread.current['_deep_cover_top_level_module'] || Object
|
9
9
|
|
10
10
|
# Adds a functionality to add callbacks before an `exec`
|
11
11
|
|
@@ -43,7 +43,11 @@ module DeepCover
|
|
43
43
|
|
44
44
|
if path == abs_path
|
45
45
|
paths_with_ext.each do |path_with_ext|
|
46
|
-
|
46
|
+
next unless File.exist?(path_with_ext)
|
47
|
+
|
48
|
+
# https://github.com/jruby/jruby/issues/5465
|
49
|
+
path_with_ext = File.realpath(path_with_ext) if RUBY_PLATFORM == 'java' && JRUBY_VERSION >= '9.2.5'
|
50
|
+
return path_with_ext
|
47
51
|
end
|
48
52
|
else
|
49
53
|
possible_paths = paths_with_load_paths(paths_with_ext)
|
@@ -74,6 +78,7 @@ module DeepCover
|
|
74
78
|
# Exceptions raised by the required code bubble up as normal, except for
|
75
79
|
# SyntaxError, which is turned into a :cover_failed which calls the fallback_block.
|
76
80
|
def require(path) # &fallback_block
|
81
|
+
raise 'Should receive the fallback_block' unless block_given?
|
77
82
|
path = path.to_s
|
78
83
|
|
79
84
|
found_path = resolve_path(path)
|
@@ -109,6 +114,7 @@ module DeepCover
|
|
109
114
|
# Same yield/return behavior as CustomRequirer#require, except that it
|
110
115
|
# cannot return false #load doesn't care about a file already being executed.
|
111
116
|
def load(path) # &fallback_block
|
117
|
+
raise 'Should receive the fallback_block' unless block_given?
|
112
118
|
path = path.to_s
|
113
119
|
|
114
120
|
found_path = resolve_path(path, try_extensions: false)
|
@@ -5,7 +5,7 @@
|
|
5
5
|
# THERE MUST NOT BE ANY USE/REQUIRE OF DEPENDENCIES OF DeepCover HERE
|
6
6
|
# See deep-cover/core_gem/lib/deep_cover/setup/clone_mode_entry_template.rb for explanation of
|
7
7
|
# clone mode and of this top_level_module stuff.
|
8
|
-
top_level_module = Thread.current['_deep_cover_top_level_module'] || Object
|
8
|
+
top_level_module = Thread.current['_deep_cover_top_level_module'] || Object
|
9
9
|
|
10
10
|
module top_level_module::DeepCover # rubocop:disable Naming/ClassAndModuleCamelCase
|
11
11
|
module GlobalVariables
|
data/lib/deep_cover/load.rb
CHANGED
@@ -21,8 +21,9 @@ module DeepCover
|
|
21
21
|
Object.autoload :Forwardable, 'forwardable'
|
22
22
|
Object.autoload :YAML, 'yaml'
|
23
23
|
|
24
|
-
# In ruby 2.2 and
|
24
|
+
# In ruby 2.2 and in JRuby, autoload doesn't work for gems which are not already on the `$LOAD_PATH`.
|
25
25
|
# The fix is to just require right away for those rubies
|
26
|
+
# JRuby issue asking for this to be changed: https://github.com/jruby/jruby/issues/5403
|
26
27
|
#
|
27
28
|
# Low-level: autoload not working for gems not on the `$LOAD_PATH` is because those rubies don't
|
28
29
|
# call the regular `#require` when triggering an autoload, and the gem system monkey-patches `#require`
|
@@ -32,7 +33,7 @@ module DeepCover
|
|
32
33
|
Term: 'term/ansicolor',
|
33
34
|
Terminal: 'terminal-table',
|
34
35
|
}.each do |const, require_path|
|
35
|
-
if RUBY_VERSION < '2.3'
|
36
|
+
if RUBY_VERSION < '2.3' || RUBY_PLATFORM == 'java'
|
36
37
|
require require_path
|
37
38
|
else
|
38
39
|
Object.autoload const, require_path
|
@@ -49,7 +49,7 @@ module DeepCover
|
|
49
49
|
alias_method :rewrite_for_completion, :rewrite
|
50
50
|
def rewrite
|
51
51
|
if call.is_a?(Csend)
|
52
|
-
rewrite_for_completion.gsub('%{node}', Csend::
|
52
|
+
rewrite_for_completion.gsub('%{node}', Csend::REWRITE_SUFFIX_IN_BLOCK)
|
53
53
|
else
|
54
54
|
rewrite_for_completion
|
55
55
|
end
|
data/lib/deep_cover/node/if.rb
CHANGED
data/lib/deep_cover/node/send.rb
CHANGED
@@ -77,7 +77,7 @@ module DeepCover
|
|
77
77
|
|
78
78
|
def rewrite
|
79
79
|
# All the rest of the rewriting logic is in Csend
|
80
|
-
'%{node};%{completion_tracker};' unless has_block?
|
80
|
+
'%{node});%{completion_tracker};' unless has_block?
|
81
81
|
end
|
82
82
|
|
83
83
|
def flow_completion_count
|
@@ -98,23 +98,21 @@ module DeepCover
|
|
98
98
|
# temp = *receiver*;
|
99
99
|
# if nil != temp
|
100
100
|
# TRACK_my_NOT_NIL
|
101
|
-
# temp = temp&.*actual_send*{block}
|
101
|
+
# temp = (temp&.*actual_send*{block})
|
102
102
|
# TRACK_actual_send_COMPLETION
|
103
|
-
#
|
104
|
-
# else
|
105
|
-
# nil
|
103
|
+
# temp
|
106
104
|
# end
|
107
105
|
# This is split across the children and the CsendInnerSend
|
108
106
|
include Branch
|
109
107
|
has_tracker :not_nil
|
110
108
|
has_child receiver: Node,
|
111
|
-
rewrite: '(%{local}=%{node};if nil != %{local};%{not_nil_tracker};%{local}
|
112
|
-
|
109
|
+
rewrite: '(%{local}=%{node};if nil != %{local};%{not_nil_tracker};%{local}=(%{local}'
|
110
|
+
REWRITE_SUFFIX_IN_BLOCK = '%{node});%{local};end)'
|
113
111
|
|
114
112
|
has_child actual_send: {safe_send: CsendInnerSend},
|
115
113
|
flow_entry_count: :not_nil_tracker_hits
|
116
114
|
|
117
|
-
def initialize(base_node, base_children: base_node.children, **)
|
115
|
+
def initialize(base_node, base_children: base_node.children, **)
|
118
116
|
send_without_receiver = base_node.updated(:safe_send, [nil, *base_node.children.drop(1)])
|
119
117
|
base_children = [base_children.first, send_without_receiver]
|
120
118
|
super
|
@@ -130,7 +128,7 @@ module DeepCover
|
|
130
128
|
end
|
131
129
|
|
132
130
|
def rewrite
|
133
|
-
|
131
|
+
'%{node};%{local};end)' unless has_block?
|
134
132
|
end
|
135
133
|
|
136
134
|
def execution_count
|
@@ -18,4 +18,16 @@ class Parser::Source::Range
|
|
18
18
|
end
|
19
19
|
current
|
20
20
|
end
|
21
|
+
|
22
|
+
# Only wraps anything if there is a comment to wrap on the last line
|
23
|
+
# Will wrap the whitespace before the comment
|
24
|
+
def wrap_final_comment
|
25
|
+
current = wrap_rwhitespace(whitespaces: /\A[ \t\r\f]+/)
|
26
|
+
if @source_buffer.slice(current.end_pos) != '#'
|
27
|
+
# No comment, do nothing
|
28
|
+
return self
|
29
|
+
end
|
30
|
+
comment = @source_buffer.slice(current.end_pos..-1)[/\A[^\n]+/] || ''
|
31
|
+
current.adjust(end_pos: comment.size)
|
32
|
+
end
|
21
33
|
end
|
@@ -5,7 +5,7 @@
|
|
5
5
|
# THERE MUST NOT BE ANY USE/REQUIRE OF DEPENDENCIES OF DeepCover HERE
|
6
6
|
# See deep-cover/core_gem/lib/deep_cover/setup/clone_mode_entry_template.rb for explanation of
|
7
7
|
# clone mode and of this top_level_module stuff.
|
8
|
-
top_level_module = Thread.current['_deep_cover_top_level_module'] || Object
|
8
|
+
top_level_module = Thread.current['_deep_cover_top_level_module'] || Object
|
9
9
|
|
10
10
|
module top_level_module::DeepCover # rubocop:disable Naming/ClassAndModuleCamelCase
|
11
11
|
require 'securerandom'
|
@@ -98,12 +98,12 @@ module DeepCover
|
|
98
98
|
end
|
99
99
|
|
100
100
|
# Istanbul doesn't understand how to ignore a branch...
|
101
|
-
def
|
101
|
+
def nil_to_something(values)
|
102
102
|
values.map { |v| v || 1 }
|
103
103
|
end
|
104
104
|
|
105
105
|
def branch_runs
|
106
|
-
branches.values.map { |r|
|
106
|
+
branches.values.map { |r| nil_to_something(r.values) }
|
107
107
|
end
|
108
108
|
|
109
109
|
def statement_map
|
@@ -5,7 +5,7 @@
|
|
5
5
|
# THERE MUST NOT BE ANY USE/REQUIRE OF DEPENDENCIES OF DeepCover HERE
|
6
6
|
# See deep-cover/core_gem/lib/deep_cover/setup/clone_mode_entry_template.rb for explanation of
|
7
7
|
# clone mode and of this top_level_module stuff.
|
8
|
-
top_level_module = Thread.current['_deep_cover_top_level_module'] || Object
|
8
|
+
top_level_module = Thread.current['_deep_cover_top_level_module'] || Object
|
9
9
|
|
10
10
|
module top_level_module::DeepCover # rubocop:disable Naming/ClassAndModuleCamelCase
|
11
11
|
module Tools
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'tempfile'
|
4
|
+
|
3
5
|
module DeepCover
|
4
6
|
module Tools::BuiltinCoverage
|
5
7
|
def builtin_coverage(source, filename, lineno)
|
@@ -8,7 +10,7 @@ module DeepCover
|
|
8
10
|
::Coverage.start
|
9
11
|
begin
|
10
12
|
Tools.silence_warnings do
|
11
|
-
execute_sample -> { run_with_line_coverage(source, filename, lineno) }
|
13
|
+
execute_sample -> { filename = run_with_line_coverage(source, filename, lineno) }
|
12
14
|
end
|
13
15
|
ensure
|
14
16
|
result = ::Coverage.result
|
@@ -16,30 +18,21 @@ module DeepCover
|
|
16
18
|
unshift_coverage(result.fetch(filename), lineno)
|
17
19
|
end
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
Object.to_java.getRuntime.executeScript(source, filename)
|
25
|
-
end
|
26
|
-
else
|
27
|
-
# In ruby 2.0 and 2.1, using 2, 3 or 4 as lineno with RubyVM::InstructionSequence.compile
|
28
|
-
# will cause the coverage result to be truncated.
|
29
|
-
# 1: [1,2,nil,1]
|
30
|
-
# 2: [nil,1,2,nil]
|
31
|
-
# 3: [nil,nil,1,2]
|
32
|
-
# 4: [nil,nil,nil,1]
|
33
|
-
# 5: [nil,nil,nil,nil,1,2,nil,1]
|
34
|
-
# Using 1 and 5 or more do not seem to show this issue.
|
35
|
-
# The workaround is to create the fake lines manually and always use the default lineno
|
21
|
+
def run_with_line_coverage(source, filename = '<code>', lineno = 1)
|
22
|
+
source = shift_source(source, lineno)
|
23
|
+
f = Tempfile.new(['ruby', '.rb'])
|
24
|
+
f.write(source)
|
25
|
+
f.close
|
36
26
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
27
|
+
begin
|
28
|
+
require f.path
|
29
|
+
rescue StandardError => e
|
30
|
+
tempfile_matcher = Regexp.new("\\A#{Regexp.escape(f.path)}(?=:\\d)")
|
31
|
+
e.backtrace.each { |l| l.sub!(tempfile_matcher, filename) }
|
32
|
+
raise
|
42
33
|
end
|
34
|
+
$LOADED_FEATURES.delete(f.path)
|
35
|
+
f.path
|
43
36
|
end
|
44
37
|
|
45
38
|
private
|
data/lib/deep_cover/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
top_level_module = Thread.current['_deep_cover_top_level_module'] || Object
|
3
|
+
top_level_module = Thread.current['_deep_cover_top_level_module'] || Object
|
4
4
|
|
5
5
|
module top_level_module::DeepCover # rubocop:disable Naming/ClassAndModuleCamelCase
|
6
|
-
VERSION = '0.7.
|
6
|
+
VERSION = '0.7.1'
|
7
7
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deep-cover-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.1
|
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: 2018-
|
12
|
+
date: 2018-12-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: parser
|
@@ -109,20 +109,6 @@ dependencies:
|
|
109
109
|
- - "~>"
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
version: '1.15'
|
112
|
-
- !ruby/object:Gem::Dependency
|
113
|
-
name: psych
|
114
|
-
requirement: !ruby/object:Gem::Requirement
|
115
|
-
requirements:
|
116
|
-
- - ">="
|
117
|
-
- !ruby/object:Gem::Version
|
118
|
-
version: '2.0'
|
119
|
-
type: :development
|
120
|
-
prerelease: false
|
121
|
-
version_requirements: !ruby/object:Gem::Requirement
|
122
|
-
requirements:
|
123
|
-
- - ">="
|
124
|
-
- !ruby/object:Gem::Version
|
125
|
-
version: '2.0'
|
126
112
|
- !ruby/object:Gem::Dependency
|
127
113
|
name: rake
|
128
114
|
requirement: !ruby/object:Gem::Requirement
|
@@ -157,14 +143,14 @@ dependencies:
|
|
157
143
|
requirements:
|
158
144
|
- - '='
|
159
145
|
- !ruby/object:Gem::Version
|
160
|
-
version: 0.
|
146
|
+
version: 0.61.1
|
161
147
|
type: :development
|
162
148
|
prerelease: false
|
163
149
|
version_requirements: !ruby/object:Gem::Requirement
|
164
150
|
requirements:
|
165
151
|
- - '='
|
166
152
|
- !ruby/object:Gem::Version
|
167
|
-
version: 0.
|
153
|
+
version: 0.61.1
|
168
154
|
description: Core functionality for the DeepCover gem.
|
169
155
|
email:
|
170
156
|
- github@marc-andre.ca
|
@@ -325,7 +311,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
325
311
|
version: '0'
|
326
312
|
requirements: []
|
327
313
|
rubyforge_project:
|
328
|
-
rubygems_version: 2.7.
|
314
|
+
rubygems_version: 2.7.6
|
329
315
|
signing_key:
|
330
316
|
specification_version: 4
|
331
317
|
summary: In depth coverage of your Ruby code.
|