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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 26469b9b1a015b36a11d432d22d871647ba060fc272c4edd274175d7163dcceb
4
- data.tar.gz: 51917845e6fdcc9e073e776fc13cade71a82d7f0806a01d36e1b653c52ee8b5f
3
+ metadata.gz: 51497f0cad911b1a78dac991b6b89f800c5cc1b0c7b99e8502816d02842ca239
4
+ data.tar.gz: 932a187d2d0669c5e21a82f81b1f7337db27d077d4ab07a9b92596721731862e
5
5
  SHA512:
6
- metadata.gz: fd179008eefe481fdcd29f5857228fda6cf1b364b027694309ca40e664a548be13ba404d168d3d1f34e7749b7d037f9d70a4cfaa11450615ccec4d7aa615a6c2
7
- data.tar.gz: bc452e18b3ec005229d4c889c5396cffa2ddadb1daa9cd4132f9e66b126be6d2a305b76d54718e1fcea5c8f548ef4e6e518620a221c8712298bc318f4068b1ea
6
+ metadata.gz: dbdc66591ef576cd5f3ad7dc0898b1746d3b1f3a5670490ea67a49a7773d200ae717029aa40b5b41359b8c67dff889aa118e7a5ef9e02e224f3c2a31cabc8372
7
+ data.tar.gz: e52c1575a8b86dd3ea5c908407a8efcbfa1ab3a0618d0b621384d1cb004143dba4e54a0464ac98030a59a8ba62f27119cbae6ef65e8cd51c07546cbd39970ae7
@@ -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
- spec.add_development_dependency 'rubocop', '0.53.0' # About every single release breaks something
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
@@ -30,8 +30,7 @@ module DeepCover
30
30
 
31
31
  def worst_branch_runs(fork)
32
32
  fork.branches.map { |jump| branch_runs(jump) }
33
- .sort_by { |runs| runs == 0 ? -2 : runs || -1 }
34
- .first
33
+ .min_by { |runs| runs == 0 ? -2 : runs || -1 }
35
34
  end
36
35
 
37
36
  def branch_runs(branch)
@@ -29,7 +29,7 @@ module DeepCover
29
29
 
30
30
  protected
31
31
 
32
- def convert(node, **) # rubocop:disable Naming/UncommunicativeMethodParamName [#5436]
32
+ def convert(node, **)
33
33
  Analyser::CoveredCodeSource.new(node)
34
34
  end
35
35
 
@@ -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]).wrap_rwhitespace_and_comments.end }
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[:end].begin
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.wrap_rwhitespace_and_comments(whitespaces: /\A[ \t\r\f]+/)
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.wrap_rwhitespace_and_comments.end
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 || end_loc, second_clause_fallback || end_loc]
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[:end].begin
172
+ wrap_rwhitespace_and_comments_if_ruby25(body.loc_hash[:begin]).end
157
173
  end
158
- elsif body.is_a?(Node::Begin) && !node.body.expressions.empty?
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 Ruby makes the
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.with(end_pos: possible_elsif.root_if_node.loc_hash[:end].begin_pos)
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
- def wrap_require(requested_path, absolute_path_found) # &block
49
- entries = entries_for_target(requested_path, absolute_path_found)
50
-
51
- begin
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
- ensure
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
- entries.each do |entry|
62
- mod = entry.mod_if_available
63
- next unless mod
64
- # Putting the autoloads back back since we couldn't complete the require
65
- mod.autoload_without_deep_cover(entry.name, entry.interceptor_path)
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
- # This is only used on MRI, so ObjectSpace is alright.
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
- path = mod.autoload?(name)
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
@@ -8,15 +8,7 @@ module DeepCover
8
8
 
9
9
  def start
10
10
  return if running?
11
- if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
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
- def autoload(name, path)
88
- mod = binding.of_caller(1).eval('Module.nesting').first || Object
89
- autoload_path = DeepCover.autoload_tracker.autoload_path_for(mod, name, path)
90
- mod.autoload_without_deep_cover(name, autoload_path)
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
- raise 'no measuring target is specified' if targets.empty?
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 # rubocop:disable Lint/UselessAssignment
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
- return path_with_ext if File.exist?(path_with_ext)
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 # rubocop:disable Lint/UselessAssignment
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
@@ -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 less, autoload doesn't work for gems which are not already on the `$LOAD_PATH`.
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::REWRITE_SUFFIX)
52
+ rewrite_for_completion.gsub('%{node}', Csend::REWRITE_SUFFIX_IN_BLOCK)
53
53
  else
54
54
  rewrite_for_completion
55
55
  end
@@ -67,6 +67,10 @@ module DeepCover
67
67
  def has_else?
68
68
  !!base_node.loc.to_hash[:else]
69
69
  end
70
+
71
+ def modifier?
72
+ loc_hash[:keyword] && root_if_node.loc_hash[:end].nil?
73
+ end
70
74
  end
71
75
  end
72
76
  end
@@ -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
- # t
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}=%{local}'
112
- REWRITE_SUFFIX = '%{node};%{local};else;nil;end)'
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, **) # rubocop:disable Naming/UncommunicativeMethodParamName [#5436]
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
- REWRITE_SUFFIX unless has_block?
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 # rubocop:disable Lint/UselessAssignment
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 zero_to_something(values)
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| zero_to_something(r.values) }
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 # rubocop:disable Lint/UselessAssignment
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
- if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
20
- # Executes the source as if it was in the specified file while
21
- # builtin coverage information is still captured
22
- def run_with_line_coverage(source, filename = nil, lineno = 1)
23
- source = shift_source(source, lineno)
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
- # Executes the source as if it was in the specified file while
38
- # builtin coverage information is still captured
39
- def run_with_line_coverage(source, filename = nil, lineno = 1)
40
- source = shift_source(source, lineno)
41
- RubyVM::InstructionSequence.compile(source, filename).eval
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
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- top_level_module = Thread.current['_deep_cover_top_level_module'] || Object # rubocop:disable Lint/UselessAssignment
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.0'
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.0
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-11-20 00:00:00.000000000 Z
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.53.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.53.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.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.