deep-cover 0.6.2 → 0.6.3.pre
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/.gitignore +3 -1
- data/.rspec +2 -1
- data/.rspec_all +2 -1
- data/.rubocop.yml +8 -9
- data/Gemfile +2 -0
- data/Rakefile +32 -6
- data/bin/cov +3 -3
- data/deep_cover.gemspec +3 -16
- data/exe/deep-cover +5 -0
- data/lib/deep_cover/cli/debugger.rb +1 -1
- data/lib/deep_cover/cli/exec.rb +1 -1
- data/lib/deep_cover/cli/instrumented_clone_reporter.rb +5 -3
- data/lib/deep_cover/cli/runner.rb +2 -2
- data/lib/deep_cover/{tools/dump_covered_code.rb → dump_covered_code.rb} +2 -0
- metadata +10 -203
- data/lib/deep-cover.rb +0 -3
- data/lib/deep_cover.rb +0 -22
- data/lib/deep_cover/analyser.rb +0 -23
- data/lib/deep_cover/analyser/base.rb +0 -104
- data/lib/deep_cover/analyser/branch.rb +0 -41
- data/lib/deep_cover/analyser/covered_code_source.rb +0 -21
- data/lib/deep_cover/analyser/function.rb +0 -14
- data/lib/deep_cover/analyser/node.rb +0 -54
- data/lib/deep_cover/analyser/per_char.rb +0 -38
- data/lib/deep_cover/analyser/per_line.rb +0 -41
- data/lib/deep_cover/analyser/ruby25_like_branch.rb +0 -211
- data/lib/deep_cover/analyser/statement.rb +0 -33
- data/lib/deep_cover/analyser/stats.rb +0 -54
- data/lib/deep_cover/analyser/subset.rb +0 -27
- data/lib/deep_cover/auto_run.rb +0 -71
- data/lib/deep_cover/autoload_tracker.rb +0 -215
- data/lib/deep_cover/backports.rb +0 -22
- data/lib/deep_cover/base.rb +0 -117
- data/lib/deep_cover/basics.rb +0 -22
- data/lib/deep_cover/builtin_takeover.rb +0 -10
- data/lib/deep_cover/config.rb +0 -104
- data/lib/deep_cover/config_setter.rb +0 -33
- data/lib/deep_cover/core_ext/autoload_overrides.rb +0 -112
- data/lib/deep_cover/core_ext/coverage_replacement.rb +0 -61
- data/lib/deep_cover/core_ext/exec_callbacks.rb +0 -27
- data/lib/deep_cover/core_ext/instruction_sequence_load_iseq.rb +0 -32
- data/lib/deep_cover/core_ext/load_overrides.rb +0 -19
- data/lib/deep_cover/core_ext/require_overrides.rb +0 -28
- data/lib/deep_cover/coverage.rb +0 -125
- data/lib/deep_cover/coverage/analysis.rb +0 -42
- data/lib/deep_cover/coverage/persistence.rb +0 -84
- data/lib/deep_cover/covered_code.rb +0 -145
- data/lib/deep_cover/custom_requirer.rb +0 -187
- data/lib/deep_cover/flag_comment_associator.rb +0 -68
- data/lib/deep_cover/load.rb +0 -66
- data/lib/deep_cover/memoize.rb +0 -48
- data/lib/deep_cover/module_override.rb +0 -39
- data/lib/deep_cover/node.rb +0 -23
- data/lib/deep_cover/node/arguments.rb +0 -51
- data/lib/deep_cover/node/assignments.rb +0 -273
- data/lib/deep_cover/node/base.rb +0 -155
- data/lib/deep_cover/node/begin.rb +0 -27
- data/lib/deep_cover/node/block.rb +0 -61
- data/lib/deep_cover/node/branch.rb +0 -32
- data/lib/deep_cover/node/case.rb +0 -113
- data/lib/deep_cover/node/collections.rb +0 -31
- data/lib/deep_cover/node/const.rb +0 -12
- data/lib/deep_cover/node/def.rb +0 -40
- data/lib/deep_cover/node/empty_body.rb +0 -32
- data/lib/deep_cover/node/exceptions.rb +0 -79
- data/lib/deep_cover/node/if.rb +0 -73
- data/lib/deep_cover/node/keywords.rb +0 -86
- data/lib/deep_cover/node/literals.rb +0 -100
- data/lib/deep_cover/node/loops.rb +0 -74
- data/lib/deep_cover/node/mixin/can_augment_children.rb +0 -65
- data/lib/deep_cover/node/mixin/check_completion.rb +0 -18
- data/lib/deep_cover/node/mixin/child_can_be_empty.rb +0 -27
- data/lib/deep_cover/node/mixin/executed_after_children.rb +0 -15
- data/lib/deep_cover/node/mixin/execution_location.rb +0 -66
- data/lib/deep_cover/node/mixin/filters.rb +0 -47
- data/lib/deep_cover/node/mixin/flow_accounting.rb +0 -71
- data/lib/deep_cover/node/mixin/has_child.rb +0 -145
- data/lib/deep_cover/node/mixin/has_child_handler.rb +0 -75
- data/lib/deep_cover/node/mixin/has_tracker.rb +0 -46
- data/lib/deep_cover/node/mixin/is_statement.rb +0 -20
- data/lib/deep_cover/node/mixin/rewriting.rb +0 -35
- data/lib/deep_cover/node/mixin/wrapper.rb +0 -15
- data/lib/deep_cover/node/module.rb +0 -66
- data/lib/deep_cover/node/root.rb +0 -20
- data/lib/deep_cover/node/send.rb +0 -161
- data/lib/deep_cover/node/short_circuit.rb +0 -42
- data/lib/deep_cover/node/splat.rb +0 -15
- data/lib/deep_cover/node/variables.rb +0 -16
- data/lib/deep_cover/parser_ext/range.rb +0 -21
- data/lib/deep_cover/problem_with_diagnostic.rb +0 -63
- data/lib/deep_cover/reporter.rb +0 -10
- data/lib/deep_cover/reporter/base.rb +0 -68
- data/lib/deep_cover/reporter/html.rb +0 -15
- data/lib/deep_cover/reporter/html/base.rb +0 -14
- data/lib/deep_cover/reporter/html/index.rb +0 -59
- data/lib/deep_cover/reporter/html/site.rb +0 -70
- data/lib/deep_cover/reporter/html/source.rb +0 -136
- data/lib/deep_cover/reporter/html/template/assets/32px.png +0 -0
- data/lib/deep_cover/reporter/html/template/assets/40px.png +0 -0
- data/lib/deep_cover/reporter/html/template/assets/deep_cover.css.sass +0 -336
- data/lib/deep_cover/reporter/html/template/assets/jquery-3.2.1.min.js +0 -4
- data/lib/deep_cover/reporter/html/template/assets/jquery-3.2.1.min.map +0 -1
- data/lib/deep_cover/reporter/html/template/assets/jstree.css +0 -1108
- data/lib/deep_cover/reporter/html/template/assets/jstree.js +0 -8424
- data/lib/deep_cover/reporter/html/template/assets/jstreetable.js +0 -1069
- data/lib/deep_cover/reporter/html/template/assets/throbber.gif +0 -0
- data/lib/deep_cover/reporter/html/template/index.html.erb +0 -75
- data/lib/deep_cover/reporter/html/template/source.html.erb +0 -35
- data/lib/deep_cover/reporter/istanbul.rb +0 -184
- data/lib/deep_cover/reporter/text.rb +0 -58
- data/lib/deep_cover/reporter/tree/util.rb +0 -86
- data/lib/deep_cover/tools.rb +0 -22
- data/lib/deep_cover/tools/blank.rb +0 -25
- data/lib/deep_cover/tools/builtin_coverage.rb +0 -55
- data/lib/deep_cover/tools/camelize.rb +0 -13
- data/lib/deep_cover/tools/content_tag.rb +0 -11
- data/lib/deep_cover/tools/covered.rb +0 -9
- data/lib/deep_cover/tools/execute_sample.rb +0 -34
- data/lib/deep_cover/tools/format.rb +0 -18
- data/lib/deep_cover/tools/format_char_cover.rb +0 -19
- data/lib/deep_cover/tools/format_generated_code.rb +0 -27
- data/lib/deep_cover/tools/indent_string.rb +0 -26
- data/lib/deep_cover/tools/merge.rb +0 -16
- data/lib/deep_cover/tools/number_lines.rb +0 -22
- data/lib/deep_cover/tools/our_coverage.rb +0 -11
- data/lib/deep_cover/tools/profiling.rb +0 -68
- data/lib/deep_cover/tools/render_template.rb +0 -13
- data/lib/deep_cover/tools/require_relative_dir.rb +0 -12
- data/lib/deep_cover/tools/scan_match_datas.rb +0 -10
- data/lib/deep_cover/tools/silence_warnings.rb +0 -18
- data/lib/deep_cover/tools/slice.rb +0 -9
- data/lib/deep_cover/tools/strip_heredoc.rb +0 -18
- data/lib/deep_cover/tools/truncate_backtrace.rb +0 -32
- data/lib/deep_cover/tracker_bucket.rb +0 -50
- data/lib/deep_cover/tracker_hits_per_path.rb +0 -35
- data/lib/deep_cover/tracker_storage.rb +0 -76
- data/lib/deep_cover/tracker_storage_per_path.rb +0 -34
- data/lib/deep_cover/version.rb +0 -5
Binary file
|
@@ -1,75 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<html>
|
3
|
-
<head>
|
4
|
-
<script src="assets/jquery-3.2.1.min.js"></script>
|
5
|
-
<script src="assets/jstree.js"></script>
|
6
|
-
<script src="assets/jstreetable.js"></script>
|
7
|
-
<script src="https://use.fontawesome.com/81e98abb93.js"></script>
|
8
|
-
<link href="assets/jstree.css" rel="stylesheet">
|
9
|
-
<link href="assets/deep_cover.css" rel="stylesheet">
|
10
|
-
|
11
|
-
<script>
|
12
|
-
window.DeepCover = {
|
13
|
-
index: <%= stats_to_data.to_json %>,
|
14
|
-
columns: <%= columns.to_json %>
|
15
|
-
};
|
16
|
-
var numColumns = {
|
17
|
-
width: 100,
|
18
|
-
sort: function(a, b) {
|
19
|
-
return (a.executed + a.ignored > b.executed + b.ignored ? 1 : -1);
|
20
|
-
},
|
21
|
-
format: function(stats) {
|
22
|
-
var ok = stats.executed + stats.ignored;
|
23
|
-
return '' + ok + '/' + (ok + stats.not_executed);
|
24
|
-
}
|
25
|
-
};
|
26
|
-
var percentColumns = {
|
27
|
-
width: 60,
|
28
|
-
format: function(percent) {
|
29
|
-
var decile = Math.floor(percent / 10);
|
30
|
-
return '<span class="percent-' + decile + '0">' + percent + '</span>';
|
31
|
-
}
|
32
|
-
}
|
33
|
-
for(var i = 1; i < DeepCover.columns.length;) {
|
34
|
-
$.extend(DeepCover.columns[i++], numColumns);
|
35
|
-
$.extend(DeepCover.columns[i++], percentColumns);
|
36
|
-
}
|
37
|
-
</script>
|
38
|
-
|
39
|
-
<script>
|
40
|
-
$(function() {
|
41
|
-
$(".tree").jstree({
|
42
|
-
plugins: ["table","sort"],
|
43
|
-
core: {
|
44
|
-
data: DeepCover.index
|
45
|
-
},
|
46
|
-
// configure tree table
|
47
|
-
table: {
|
48
|
-
columns: DeepCover.columns,
|
49
|
-
resizable: true,
|
50
|
-
width: "100%",
|
51
|
-
height: "100%"
|
52
|
-
}
|
53
|
-
});
|
54
|
-
});
|
55
|
-
</script>
|
56
|
-
</head>
|
57
|
-
<body class="index">
|
58
|
-
<header>
|
59
|
-
<div class="content">
|
60
|
-
<div class="info"><span class="deep-cover"><span class="deep">Deep</span>Cover</span>
|
61
|
-
<span class="version">v<%= DeepCover::VERSION %></span>
|
62
|
-
</div>
|
63
|
-
</div>
|
64
|
-
</header>
|
65
|
-
<main>
|
66
|
-
<div class="tree"></div>
|
67
|
-
</main>
|
68
|
-
<footer>
|
69
|
-
<div class="details">
|
70
|
-
<span class="date"><%= Time.now %></span>
|
71
|
-
<span class="setup"><%= setup %></span>
|
72
|
-
</div>
|
73
|
-
</footer>
|
74
|
-
</body>
|
75
|
-
</html>
|
@@ -1,35 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<html>
|
3
|
-
<head>
|
4
|
-
<base href="<%= root_path %>"/>
|
5
|
-
<script src="assets/jquery-3.2.1.min.js"></script>
|
6
|
-
<script src="https://use.fontawesome.com/81e98abb93.js"></script>
|
7
|
-
<link rel="stylesheet" href="assets/deep_cover.css" type="text/css"/>
|
8
|
-
</head>
|
9
|
-
<body class="source">
|
10
|
-
<div class="overlay">
|
11
|
-
<div class="center">
|
12
|
-
<div class="stats"><%= stats %></div>
|
13
|
-
</div>
|
14
|
-
</div>
|
15
|
-
<header>
|
16
|
-
<div class="content">
|
17
|
-
<div class="info"><span class="deep-cover"><span class="deep">Deep</span>Cover</span>
|
18
|
-
<span class="version">v<%= DeepCover::VERSION %></span>
|
19
|
-
</div>
|
20
|
-
<div class="nav">
|
21
|
-
<a href="index.html" aria-label="Home"><i class="fa fa-home" aria-hidden="true"></i></a>
|
22
|
-
<span class="path"><%= partial_path %><span>
|
23
|
-
</div>
|
24
|
-
</div>
|
25
|
-
</header>
|
26
|
-
<main class="source"><%= format_source %></main>
|
27
|
-
<script>
|
28
|
-
$(function() {
|
29
|
-
$('.stats .branch').click(function() {
|
30
|
-
$('body').toggleClass('show-forks')
|
31
|
-
});
|
32
|
-
});
|
33
|
-
</script>
|
34
|
-
</body>
|
35
|
-
</html>
|
@@ -1,184 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'json'
|
4
|
-
|
5
|
-
module DeepCover
|
6
|
-
module Reporter
|
7
|
-
class Istanbul < Base
|
8
|
-
module Converters
|
9
|
-
def convert_range(range)
|
10
|
-
{start: {
|
11
|
-
line: range.line,
|
12
|
-
column: range.column,
|
13
|
-
},
|
14
|
-
end: {
|
15
|
-
line: range.last_line,
|
16
|
-
column: range.last_column - 1, # Our ranges are exclusive, Istanbul's are inclusive
|
17
|
-
},
|
18
|
-
}
|
19
|
-
end
|
20
|
-
|
21
|
-
# [:a, :b, :c] => {'1': :a, '2': :b, '3': :c}
|
22
|
-
def convert_list(list)
|
23
|
-
list.map.with_index { |val, i| [i.succ.to_s, val] }.to_h
|
24
|
-
end
|
25
|
-
|
26
|
-
def convert_def(node)
|
27
|
-
ends_at = node.signature.loc_hash[:end] || node.loc_hash[:name]
|
28
|
-
decl = node.loc_hash[:keyword].with(end_pos: ends_at.end_pos)
|
29
|
-
_convert_function(node, node.method_name, decl)
|
30
|
-
end
|
31
|
-
|
32
|
-
def convert_block(node)
|
33
|
-
decl = node.loc_hash[:begin]
|
34
|
-
if (args = node.args.expression)
|
35
|
-
decl = decl.join(args)
|
36
|
-
end
|
37
|
-
_convert_function(node, '(block)', decl)
|
38
|
-
end
|
39
|
-
|
40
|
-
def convert_function(node)
|
41
|
-
if node.is_a?(Node::Block)
|
42
|
-
convert_block(node)
|
43
|
-
else
|
44
|
-
convert_def(node)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def convert_branch(node, branches = node.branches)
|
49
|
-
# Currently, nyc seems to outputs the same location over and over...
|
50
|
-
{
|
51
|
-
loc: convert_range(node.expression),
|
52
|
-
type: node.type,
|
53
|
-
line: node.expression.line,
|
54
|
-
locations: branches.map { |n| convert_range(n.expression || node.expression) },
|
55
|
-
}
|
56
|
-
end
|
57
|
-
|
58
|
-
private
|
59
|
-
|
60
|
-
def _convert_function(node, name, decl)
|
61
|
-
loc = node.body ? node.body.expression : decl.end
|
62
|
-
{
|
63
|
-
name: name,
|
64
|
-
line: node.expression.line,
|
65
|
-
decl: convert_range(decl),
|
66
|
-
loc: convert_range(loc),
|
67
|
-
}
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
class CoveredCodeConverter < Struct.new(:covered_code, :options)
|
72
|
-
include Converters
|
73
|
-
|
74
|
-
def node_analyser
|
75
|
-
@node_analyser ||= Analyser::Node.new(covered_code, **options)
|
76
|
-
end
|
77
|
-
|
78
|
-
def node_runs
|
79
|
-
@node_runs ||= node_analyser.results
|
80
|
-
end
|
81
|
-
|
82
|
-
def functions
|
83
|
-
@functions ||= Analyser::Function.new(node_analyser, **options).results
|
84
|
-
end
|
85
|
-
|
86
|
-
def statements
|
87
|
-
@statements ||= Analyser::Statement.new(node_analyser, **options).results
|
88
|
-
end
|
89
|
-
|
90
|
-
def branches
|
91
|
-
@branches ||= Analyser::Branch.new(node_analyser, **options).results
|
92
|
-
end
|
93
|
-
|
94
|
-
def branch_map
|
95
|
-
branches.map do |node, branches_runs|
|
96
|
-
convert_branch(node, branches_runs.keys)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
# Istanbul doesn't understand how to ignore a branch...
|
101
|
-
def zero_to_something(values)
|
102
|
-
values.map { |v| v || 1 }
|
103
|
-
end
|
104
|
-
|
105
|
-
def branch_runs
|
106
|
-
branches.values.map { |r| zero_to_something(r.values) }
|
107
|
-
end
|
108
|
-
|
109
|
-
def statement_map
|
110
|
-
statements.keys.map { |range| convert_range(range) }
|
111
|
-
end
|
112
|
-
|
113
|
-
def statement_runs
|
114
|
-
statements.values
|
115
|
-
end
|
116
|
-
|
117
|
-
def function_map
|
118
|
-
functions.keys.map { |n| convert_function(n) }
|
119
|
-
end
|
120
|
-
|
121
|
-
def function_runs
|
122
|
-
functions.values
|
123
|
-
end
|
124
|
-
|
125
|
-
def data
|
126
|
-
{
|
127
|
-
statementMap: statement_map,
|
128
|
-
s: statement_runs,
|
129
|
-
fnMap: function_map,
|
130
|
-
f: function_runs,
|
131
|
-
branchMap: branch_map,
|
132
|
-
b: branch_runs,
|
133
|
-
}
|
134
|
-
end
|
135
|
-
|
136
|
-
def convert
|
137
|
-
{
|
138
|
-
path: covered_code.path,
|
139
|
-
**data.transform_values { |l| convert_list(l) },
|
140
|
-
}
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
def convert
|
145
|
-
each.to_a.to_h.transform_values do |covered_code|
|
146
|
-
CoveredCodeConverter.new(covered_code, **@options).convert
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
def save(dir: '.', name: '.nyc_output')
|
151
|
-
path = Pathname.new(dir).expand_path.join(name)
|
152
|
-
path.mkpath
|
153
|
-
path.each_child(&:delete)
|
154
|
-
path.join('deep_cover.json').write(JSON.pretty_generate(convert))
|
155
|
-
path
|
156
|
-
end
|
157
|
-
|
158
|
-
def report
|
159
|
-
output = @options[:output]
|
160
|
-
dir = save.dirname
|
161
|
-
unless [nil, false, '', 'false'].include? output
|
162
|
-
output = File.expand_path(output)
|
163
|
-
html = "--reporter=html --report-dir='#{output}'"
|
164
|
-
if @options[:open]
|
165
|
-
html += " && open '#{output}/index.html'"
|
166
|
-
else
|
167
|
-
msg = "\nHTML coverage written to: '#{output}/index.html'"
|
168
|
-
end
|
169
|
-
end
|
170
|
-
`cd #{dir} && nyc report --reporter=text #{html}` + msg.to_s
|
171
|
-
end
|
172
|
-
|
173
|
-
class << self
|
174
|
-
def report(coverage, **options)
|
175
|
-
new(coverage, options).report
|
176
|
-
end
|
177
|
-
|
178
|
-
def available?
|
179
|
-
`nyc --version` >= '11.' rescue false
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DeepCover
|
4
|
-
require_relative 'base'
|
5
|
-
|
6
|
-
module Reporter
|
7
|
-
class Text < Base
|
8
|
-
INDENT = ' '
|
9
|
-
def report
|
10
|
-
formatted_headings = headings.map.with_index { |h, i| {value: h, alignment: :center} }
|
11
|
-
columns = rows.transpose
|
12
|
-
(1...columns.size).step(2) { |i| columns[i] = formatted_stats(columns[i]) }
|
13
|
-
table = Terminal::Table.new(
|
14
|
-
headings: formatted_headings,
|
15
|
-
rows: columns.transpose,
|
16
|
-
style: {border_bottom: false, border_top: false, alignment: :right},
|
17
|
-
)
|
18
|
-
table.align_column 0, :left
|
19
|
-
table.render + "\n\nOverall: #{analysis.overall}%"
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.report(coverage, **options)
|
23
|
-
Text.new(coverage, **options).report
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def formatted_stats(data)
|
29
|
-
columns = data.transpose
|
30
|
-
columns[1..1] = [] if columns[1].none?
|
31
|
-
Terminal::Table.new(
|
32
|
-
rows: columns.transpose,
|
33
|
-
style: {border_x: '', border_bottom: false, border_top: false, alignment: :right}
|
34
|
-
).render.gsub(' | ', ' ').gsub(/ ?\| ?/, '').split("\n")
|
35
|
-
end
|
36
|
-
|
37
|
-
def rows
|
38
|
-
populate_stats.map do |full_path, partial_path, data, children|
|
39
|
-
[partial_path, *transform_data(data)]
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def headings
|
44
|
-
Coverage::Analysis.template.values.flat_map do |analyser|
|
45
|
-
[analyser.human_name, '%']
|
46
|
-
end.unshift('Path')
|
47
|
-
end
|
48
|
-
|
49
|
-
# {per_char: Stat, ...} => ['1 [+2] / 3', '100 %', ...]
|
50
|
-
def transform_data(data)
|
51
|
-
data.flat_map do |type, stat|
|
52
|
-
ignored = "[+#{stat.ignored}]" if stat.ignored > 0
|
53
|
-
[[stat.executed, ignored, '/', stat.potentially_executable], format('%.2f', stat.percent_covered)]
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,86 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DeepCover
|
4
|
-
module Reporter
|
5
|
-
class Tree
|
6
|
-
# Utility functions to deal with trees
|
7
|
-
module Util
|
8
|
-
extend self
|
9
|
-
|
10
|
-
def populate_from_map(tree:, map:, merge:)
|
11
|
-
return to_enum(__method__, tree: tree, map: map, merge: merge) unless block_given?
|
12
|
-
final_results, _final_data = populate(tree) do |full_path, partial_path, children|
|
13
|
-
if children.empty?
|
14
|
-
data = map.fetch(full_path)
|
15
|
-
else
|
16
|
-
child_results, child_data = children.transpose
|
17
|
-
data = merge.call(child_data)
|
18
|
-
end
|
19
|
-
result = yield full_path, partial_path, data, child_results || []
|
20
|
-
[result, data]
|
21
|
-
end.transpose
|
22
|
-
final_results
|
23
|
-
end
|
24
|
-
|
25
|
-
def paths_to_tree(paths)
|
26
|
-
twigs = paths.map do |path|
|
27
|
-
partials = path_to_partial_paths(path)
|
28
|
-
list_to_twig(partials)
|
29
|
-
end
|
30
|
-
tree = deep_merge(twigs)
|
31
|
-
simplify(tree)
|
32
|
-
end
|
33
|
-
|
34
|
-
# 'some/example/path' => %w[some example path]
|
35
|
-
def path_to_partial_paths(path)
|
36
|
-
path.to_s.split('/')
|
37
|
-
end
|
38
|
-
|
39
|
-
# A twig is a tree with only single branches
|
40
|
-
# [a, b, c] =>
|
41
|
-
# {a: {b: {c: {} } } }
|
42
|
-
def list_to_twig(items)
|
43
|
-
result = {}
|
44
|
-
items.inject(result) do |parent, value|
|
45
|
-
parent[value] = {}
|
46
|
-
end
|
47
|
-
result
|
48
|
-
end
|
49
|
-
|
50
|
-
# [{a: {b: {c: {} } } }
|
51
|
-
# {a: {b: {d: {} } } }]
|
52
|
-
# => {a: {b: {c: {}, d: {} }}}
|
53
|
-
def deep_merge(trees)
|
54
|
-
trees.inject({}) do |result, h|
|
55
|
-
result.merge(h) { |k, val, val_b| deep_merge([val, val_b]) }
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
# {a: {b: {c: {}, d: {} }}}
|
60
|
-
# => {a/b: {c: {}, d: {} }}
|
61
|
-
def simplify(tree)
|
62
|
-
tree.map do |key, sub_tree|
|
63
|
-
sub_tree = simplify(sub_tree)
|
64
|
-
if sub_tree.size == 1
|
65
|
-
key2, sub_tree = sub_tree.first
|
66
|
-
key = "#{key}/#{key2}"
|
67
|
-
end
|
68
|
-
[key, sub_tree]
|
69
|
-
end.to_h
|
70
|
-
end
|
71
|
-
|
72
|
-
# {a: {b: {}}} => [ra, rb]
|
73
|
-
# where rb = yield('a/b', 'b', [])
|
74
|
-
# and ra = yield('a', 'a', [rb])
|
75
|
-
def populate(tree, dir = '', &block)
|
76
|
-
return to_enum(__method__, tree, dir) unless block_given?
|
77
|
-
tree.map do |path, children_hash|
|
78
|
-
full_path = [dir, path].join
|
79
|
-
children = populate(children_hash, "#{full_path}/", &block)
|
80
|
-
yield full_path, path, children
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
data/lib/deep_cover/tools.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DeepCover
|
4
|
-
module Tools
|
5
|
-
end
|
6
|
-
|
7
|
-
require_relative 'tools/require_relative_dir'
|
8
|
-
extend Tools::RequireRelativeDir
|
9
|
-
require_relative 'tools/silence_warnings'
|
10
|
-
extend Tools::SilenceWarnings
|
11
|
-
require_relative_dir 'tools'
|
12
|
-
|
13
|
-
# The functions defined in the submodules of Tools can be accessed
|
14
|
-
# either by extending the desired module, or all of them by extending
|
15
|
-
# Tools, or by calling them directly Tool.my_function.
|
16
|
-
module Tools
|
17
|
-
constants.each do |module_name|
|
18
|
-
include const_get(module_name)
|
19
|
-
end
|
20
|
-
extend self
|
21
|
-
end
|
22
|
-
end
|