deep-cover-core 0.7.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|