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 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.