deep-cover 0.1.16 → 0.2.0
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 +2 -0
- data/.rubocop.yml +3 -8
- data/.travis.yml +4 -4
- data/CHANGELOG.md +10 -0
- data/Gemfile +3 -1
- data/README.md +9 -4
- data/Rakefile +6 -3
- data/deep_cover.gemspec +2 -2
- data/lib/deep_cover.rb +10 -0
- data/lib/deep_cover/analyser.rb +1 -2
- data/lib/deep_cover/analyser/base.rb +32 -0
- data/lib/deep_cover/analyser/branch.rb +19 -4
- data/lib/deep_cover/analyser/node.rb +52 -0
- data/lib/deep_cover/analyser/per_char.rb +18 -1
- data/lib/deep_cover/analyser/stats.rb +54 -0
- data/lib/deep_cover/backports.rb +1 -0
- data/lib/deep_cover/base.rb +17 -1
- data/lib/deep_cover/builtin_takeover.rb +5 -0
- data/lib/deep_cover/cli/deep_cover.rb +2 -1
- data/lib/deep_cover/cli/instrumented_clone_reporter.rb +12 -10
- data/lib/deep_cover/config.rb +22 -8
- data/lib/deep_cover/core_ext/coverage_replacement.rb +22 -18
- data/lib/deep_cover/coverage.rb +3 -203
- data/lib/deep_cover/coverage/analysis.rb +36 -0
- data/lib/deep_cover/coverage/base.rb +91 -0
- data/lib/deep_cover/coverage/istanbul.rb +34 -0
- data/lib/deep_cover/coverage/persistence.rb +93 -0
- data/lib/deep_cover/covered_code.rb +12 -22
- data/lib/deep_cover/custom_requirer.rb +6 -2
- data/lib/deep_cover/node/base.rb +1 -1
- data/lib/deep_cover/node/case.rb +13 -2
- data/lib/deep_cover/node/exceptions.rb +2 -2
- data/lib/deep_cover/node/if.rb +21 -2
- data/lib/deep_cover/node/mixin/flow_accounting.rb +1 -0
- data/lib/deep_cover/node/send.rb +9 -2
- data/lib/deep_cover/node/short_circuit.rb +10 -0
- data/lib/deep_cover/parser_ext/range.rb +4 -4
- data/lib/deep_cover/reporter/html.rb +15 -0
- data/lib/deep_cover/reporter/html/base.rb +14 -0
- data/lib/deep_cover/reporter/html/index.rb +78 -0
- data/lib/deep_cover/reporter/html/site.rb +78 -0
- data/lib/deep_cover/reporter/html/source.rb +136 -0
- 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 +338 -0
- data/lib/deep_cover/reporter/html/template/assets/jquery-3.2.1.min.js +4 -0
- data/lib/deep_cover/reporter/html/template/assets/jquery-3.2.1.min.map +1 -0
- data/lib/deep_cover/reporter/html/template/assets/jstree.css +1108 -0
- data/lib/deep_cover/reporter/html/template/assets/jstree.js +8424 -0
- data/lib/deep_cover/reporter/html/template/assets/jstreetable.js +1069 -0
- data/lib/deep_cover/reporter/html/template/assets/throbber.gif +0 -0
- data/lib/deep_cover/reporter/html/template/index.html.erb +75 -0
- data/lib/deep_cover/reporter/html/template/source.html.erb +35 -0
- data/lib/deep_cover/reporter/html/tree.rb +55 -0
- data/lib/deep_cover/tools/content_tag.rb +11 -0
- data/lib/deep_cover/tools/covered.rb +9 -0
- data/lib/deep_cover/tools/merge.rb +16 -0
- data/lib/deep_cover/tools/render_template.rb +13 -0
- data/lib/deep_cover/tools/transform_keys.rb +9 -0
- data/lib/deep_cover/version.rb +1 -1
- metadata +33 -7
- data/lib/deep_cover/analyser/ignore_uncovered.rb +0 -21
- data/lib/deep_cover/analyser/optionally_covered.rb +0 -19
@@ -40,11 +40,12 @@ module DeepCover
|
|
40
40
|
o.separator ''
|
41
41
|
o.string '-o', '--output', 'output folder', default: './coverage'
|
42
42
|
o.string '-c', '--command', 'command to run tests', default: 'bundle exec rake'
|
43
|
+
o.string '--reporter', 'reporter', default: 'html'
|
43
44
|
o.bool '--bundle', 'run bundle before the tests', default: true
|
44
45
|
o.bool '--process', 'turn off to only redo the reporting', default: true
|
45
46
|
o.bool '--open', 'open the output coverage', default: false
|
46
47
|
o.separator 'Coverage options'
|
47
|
-
@ignore_uncovered_map = Analyser.optionally_covered.map do |option|
|
48
|
+
@ignore_uncovered_map = Analyser::Node.optionally_covered.map do |option|
|
48
49
|
default = Config::DEFAULTS[:ignore_uncovered].include?(option)
|
49
50
|
o.bool "--ignore-#{Tools.dasherize(option)}", '', default: default
|
50
51
|
[:"ignore_#{option}", option]
|
@@ -106,23 +106,25 @@ module DeepCover
|
|
106
106
|
|
107
107
|
def patch_gemfile
|
108
108
|
gemfile = @dest_root.join('Gemfile')
|
109
|
+
deps = Bundler::Definition.build(gemfile, nil, nil).dependencies
|
110
|
+
|
111
|
+
return if deps.find { |e| e.name == 'deep-cover' }
|
112
|
+
|
109
113
|
content = File.read(gemfile)
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
].join("\n"))
|
118
|
-
end
|
114
|
+
puts "Patching Gemfile #{gemfile}"
|
115
|
+
File.write(gemfile, [
|
116
|
+
'# This file was modified by DeepCover',
|
117
|
+
content,
|
118
|
+
"gem 'deep-cover', path: '#{File.expand_path(__dir__ + '/../../../')}'",
|
119
|
+
'',
|
120
|
+
].join("\n"))
|
119
121
|
end
|
120
122
|
|
121
123
|
def patch_rubocop
|
122
124
|
path = @dest_root.join('.rubocop.yml')
|
123
125
|
return unless path.exist?
|
124
126
|
puts 'Patching .rubocop.yml'
|
125
|
-
config = YAML.
|
127
|
+
config = YAML.load(path.read.gsub(/(?<!\w)lib(?!\w)/, 'lib_original'))
|
126
128
|
((config['AllCops'] ||= {})['Exclude'] ||= []) << 'lib/**/*' << 'app/**/*'
|
127
129
|
path.write("# This file was modified by DeepCover\n" + YAML.dump(config))
|
128
130
|
end
|
data/lib/deep_cover/config.rb
CHANGED
@@ -14,38 +14,52 @@ module DeepCover
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def to_hash
|
17
|
-
|
17
|
+
@options.dup
|
18
18
|
end
|
19
19
|
alias_method :to_h, :to_hash
|
20
20
|
|
21
21
|
def ignore_uncovered(*keywords)
|
22
|
-
|
23
|
-
|
22
|
+
if keywords.empty?
|
23
|
+
@options[:ignore_uncovered]
|
24
|
+
else
|
25
|
+
check_uncovered(keywords)
|
26
|
+
change(:ignore_uncovered, @options[:ignore_uncovered] | keywords)
|
27
|
+
end
|
24
28
|
end
|
25
29
|
|
26
30
|
def detect_uncovered(*keywords)
|
27
|
-
|
28
|
-
|
31
|
+
if keywords.empty?
|
32
|
+
Analyser::Node.optionally_covered - @options[:ignore_uncovered]
|
33
|
+
else
|
34
|
+
check_uncovered(keywords)
|
35
|
+
change(:ignore_uncovered, @options[:ignore_uncovered] - keywords)
|
36
|
+
end
|
29
37
|
end
|
30
38
|
|
31
39
|
def paths(paths = nil)
|
32
40
|
if paths
|
33
|
-
change(:paths, Array(paths).dup
|
41
|
+
change(:paths, Array(paths).dup)
|
34
42
|
else
|
35
43
|
@options[:paths]
|
36
44
|
end
|
37
45
|
end
|
38
46
|
|
47
|
+
def reset
|
48
|
+
DEFAULTS.each do |key, value|
|
49
|
+
change(key, value)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
39
53
|
private
|
40
54
|
|
41
55
|
def check_uncovered(keywords)
|
42
|
-
unknown = keywords - Analyser.optionally_covered
|
56
|
+
unknown = keywords - Analyser::Node.optionally_covered
|
43
57
|
raise ArgumentError, "unknown options: #{unknown.join(', ')}" unless unknown.empty?
|
44
58
|
end
|
45
59
|
|
46
60
|
def change(option, value)
|
47
61
|
if @options[option] != value
|
48
|
-
@options[option] = value
|
62
|
+
@options[option] = value.freeze
|
49
63
|
@notify.config_changed(option) if @notify.respond_to? :config_changed
|
50
64
|
end
|
51
65
|
self
|
@@ -2,27 +2,31 @@
|
|
2
2
|
|
3
3
|
# This is a complete replacement for the builtin Coverage module of Ruby
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
module DeepCover
|
6
|
+
module CoverageReplacement
|
7
|
+
class << self
|
8
|
+
def running?
|
9
|
+
DeepCover.running?
|
10
|
+
end
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
12
|
+
def start
|
13
|
+
return if running?
|
14
|
+
DeepCover.start
|
15
|
+
nil
|
16
|
+
end
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
def result
|
19
|
+
r = peek_result
|
20
|
+
DeepCover.stop
|
21
|
+
r
|
22
|
+
end
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
24
|
+
def peek_result
|
25
|
+
raise 'coverage measurement is not enabled' unless running?
|
26
|
+
DeepCover.coverage.covered_codes.map do |covered_code|
|
27
|
+
[covered_code.path, covered_code.line_coverage(allow_partial: false)]
|
28
|
+
end.to_h
|
29
|
+
end
|
25
30
|
end
|
26
|
-
Hash[results]
|
27
31
|
end
|
28
32
|
end
|
data/lib/deep_cover/coverage.rb
CHANGED
@@ -1,208 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module DeepCover
|
4
|
-
require 'parser'
|
5
|
-
silence_warnings do
|
6
|
-
require 'parser/current'
|
7
|
-
end
|
8
4
|
require_relative 'covered_code'
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
class Coverage
|
13
|
-
include Enumerable
|
14
|
-
|
15
|
-
def initialize(**options)
|
16
|
-
@covered_codes = {}
|
17
|
-
@options = options
|
18
|
-
end
|
19
|
-
|
20
|
-
def covered_codes
|
21
|
-
@covered_codes.dup
|
22
|
-
end
|
23
|
-
|
24
|
-
def reset
|
25
|
-
@covered_codes = {}
|
26
|
-
end
|
27
|
-
|
28
|
-
def line_coverage(filename, **options)
|
29
|
-
covered_code(filename).line_coverage(**options)
|
30
|
-
end
|
31
|
-
|
32
|
-
def covered_code(path, **options)
|
33
|
-
raise 'path must be an absolute path' unless Pathname.new(path).absolute?
|
34
|
-
@covered_codes[path] ||= CoveredCode.new(path: path, **options, **@options)
|
35
|
-
end
|
36
|
-
|
37
|
-
def each
|
38
|
-
return to_enum unless block_given?
|
39
|
-
@covered_codes.each_value { |covered_code| yield covered_code }
|
40
|
-
self
|
41
|
-
end
|
42
|
-
|
43
|
-
def to_istanbul(**options)
|
44
|
-
map do |covered_code|
|
45
|
-
next {} unless covered_code.has_executed?
|
46
|
-
covered_code.to_istanbul(**options)
|
47
|
-
end.inject(:merge)
|
48
|
-
end
|
49
|
-
|
50
|
-
def output_istanbul(dir: '.', name: '.nyc_output', **options)
|
51
|
-
path = Pathname.new(dir).expand_path.join(name)
|
52
|
-
path.mkpath
|
53
|
-
path.each_child(&:delete)
|
54
|
-
path.join('deep_cover.json').write(JSON.pretty_generate(to_istanbul(**options)))
|
55
|
-
path
|
56
|
-
end
|
57
|
-
|
58
|
-
def report_istanbul(output: nil, **options)
|
59
|
-
dir = output_istanbul(**options).dirname
|
60
|
-
unless [nil, '', 'false'].include? output
|
61
|
-
output = File.expand_path(output)
|
62
|
-
html = "--reporter=html --report-dir='#{output}'"
|
63
|
-
if options[:open]
|
64
|
-
html += " && open '#{output}/index.html'"
|
65
|
-
else
|
66
|
-
msg = "\nHTML coverage written to: '#{output}/index.html'"
|
67
|
-
end
|
68
|
-
end
|
69
|
-
`cd #{dir} && nyc report --reporter=text #{html}` + msg.to_s
|
70
|
-
end
|
71
|
-
|
72
|
-
def basic_report
|
73
|
-
missing = map do |covered_code|
|
74
|
-
if covered_code.has_executed?
|
75
|
-
missed = covered_code.line_coverage.each_with_index.map do |line_cov, line_index|
|
76
|
-
line_index + 1 if line_cov == 0
|
77
|
-
end.compact
|
78
|
-
else
|
79
|
-
missed = ['all']
|
80
|
-
end
|
81
|
-
[covered_code.buffer.name, missed] unless missed.empty?
|
82
|
-
end.compact.to_h
|
83
|
-
missing.map do |path, lines|
|
84
|
-
"#{File.basename(path)}: #{lines.join(', ')}"
|
85
|
-
end.join("\n")
|
86
|
-
end
|
87
|
-
|
88
|
-
def report(**options)
|
89
|
-
if Reporter::Istanbul.available?
|
90
|
-
report_istanbul(**options)
|
91
|
-
else
|
92
|
-
warn 'nyc not available. Please install `nyc` using `yarn global add nyc` or `npm i nyc -g`'
|
93
|
-
basic_report
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def self.load(dest_path, dirname = 'deep_cover', with_trackers: true)
|
98
|
-
Persistence.new(dest_path, dirname).load(with_trackers: with_trackers)
|
99
|
-
end
|
100
|
-
|
101
|
-
def self.saved?(dest_path, dirname = 'deep_cover')
|
102
|
-
Persistence.new(dest_path, dirname).saved?
|
103
|
-
end
|
104
|
-
|
105
|
-
def save(dest_path, dirname = 'deep_cover')
|
106
|
-
Persistence.new(dest_path, dirname).save(self)
|
107
|
-
self
|
108
|
-
end
|
109
|
-
|
110
|
-
def save_trackers(dest_path, dirname = 'deep_cover')
|
111
|
-
Persistence.new(dest_path, dirname).save_trackers(tracker_global)
|
112
|
-
self
|
113
|
-
end
|
114
|
-
|
115
|
-
def tracker_global
|
116
|
-
@options.fetch(:tracker_global, CoveredCode::DEFAULT_TRACKER_GLOBAL)
|
117
|
-
end
|
118
|
-
|
119
|
-
class Persistence
|
120
|
-
# rubocop:disable Security/MarshalLoad
|
121
|
-
BASENAME = 'coverage.dc'
|
122
|
-
TRACKER_TEMPLATE = 'trackers%{unique}.dct'
|
123
|
-
|
124
|
-
attr_reader :dir_path
|
125
|
-
def initialize(dest_path, dirname)
|
126
|
-
@dir_path = Pathname(dest_path).join(dirname).expand_path
|
127
|
-
end
|
128
|
-
|
129
|
-
def load(with_trackers: true)
|
130
|
-
saved?
|
131
|
-
load_trackers if with_trackers
|
132
|
-
load_coverage
|
133
|
-
end
|
134
|
-
|
135
|
-
def save(coverage)
|
136
|
-
create_if_needed
|
137
|
-
delete_trackers
|
138
|
-
save_coverage(coverage)
|
139
|
-
end
|
140
|
-
|
141
|
-
def save_trackers(global)
|
142
|
-
saved?
|
143
|
-
trackers = eval(global) # rubocop:disable Security/Eval
|
144
|
-
# Some testing involves more than one process, some of which don't run any of our covered code.
|
145
|
-
# Don't save anything if that's the case
|
146
|
-
return if trackers.nil?
|
147
|
-
basename = format(TRACKER_TEMPLATE, unique: SecureRandom.urlsafe_base64)
|
148
|
-
dir_path.join(basename).binwrite(Marshal.dump(
|
149
|
-
version: DeepCover::VERSION,
|
150
|
-
global: global,
|
151
|
-
trackers: trackers,
|
152
|
-
))
|
153
|
-
end
|
154
|
-
|
155
|
-
def saved?
|
156
|
-
raise "Can't find folder '#{dir_path}'" unless dir_path.exist?
|
157
|
-
self
|
158
|
-
end
|
159
|
-
|
160
|
-
private
|
161
|
-
|
162
|
-
def create_if_needed
|
163
|
-
dir_path.mkpath
|
164
|
-
end
|
165
|
-
|
166
|
-
def save_coverage(coverage)
|
167
|
-
dir_path.join(BASENAME).binwrite(Marshal.dump(
|
168
|
-
version: DeepCover::VERSION,
|
169
|
-
coverage: coverage,
|
170
|
-
))
|
171
|
-
end
|
172
|
-
|
173
|
-
def load_coverage
|
174
|
-
Marshal.load(dir_path.join(BASENAME).binread).tap do |version: raise, coverage: raise|
|
175
|
-
raise "dump version mismatch: #{version}, currently #{DeepCover::VERSION}" unless version == DeepCover::VERSION
|
176
|
-
return coverage
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
def load_trackers
|
181
|
-
tracker_files.each do |full_path|
|
182
|
-
Marshal.load(full_path.binread).tap do |version: raise, global: raise, trackers: raise|
|
183
|
-
raise "dump version mismatch: #{version}, currently #{DeepCover::VERSION}" unless version == DeepCover::VERSION
|
184
|
-
merge_trackers(eval("#{global} ||= {}"), trackers) # rubocop:disable Security/Eval
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
def merge_trackers(hash, to_merge)
|
190
|
-
hash.merge!(to_merge) do |_key, current, to_add|
|
191
|
-
unless current.empty? || current.size == to_add.size
|
192
|
-
warn "Merging trackers of different sizes: #{current.size} vs #{to_add.size}"
|
193
|
-
end
|
194
|
-
to_add.zip(current).map { |a, b| a + b }
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
def tracker_files
|
199
|
-
basename = format(TRACKER_TEMPLATE, unique: '*')
|
200
|
-
Pathname.glob(dir_path.join(basename))
|
201
|
-
end
|
202
|
-
|
203
|
-
def delete_trackers
|
204
|
-
tracker_files.each(&:delete)
|
205
|
-
end
|
206
|
-
end
|
207
|
-
end
|
5
|
+
Coverage = Class.new
|
6
|
+
require_relative_dir 'coverage'
|
7
|
+
Coverage.include Coverage::Istanbul
|
208
8
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DeepCover
|
4
|
+
class Coverage::Analysis < Struct.new(:covered_codes, :options)
|
5
|
+
include Memoize
|
6
|
+
memoize :analyser_map, :stat_map
|
7
|
+
|
8
|
+
def analyser_map
|
9
|
+
covered_codes.map do |covered_code|
|
10
|
+
[covered_code, compute_analysers(covered_code)]
|
11
|
+
end.to_h
|
12
|
+
end
|
13
|
+
|
14
|
+
def stat_map
|
15
|
+
analyser_map.transform_values { |a| a.transform_values(&:stats) }
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def compute_analysers(covered_code)
|
21
|
+
base = Analyser::Node.new(covered_code, **options)
|
22
|
+
{node: base}.merge!(
|
23
|
+
{
|
24
|
+
per_char: Analyser::PerChar,
|
25
|
+
branch: Analyser::Branch,
|
26
|
+
}.transform_values { |klass| klass.new(base, **options) }
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Coverage
|
32
|
+
def analysis(**options)
|
33
|
+
Analysis.new(covered_codes, options)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DeepCover
|
4
|
+
# A collection of CoveredCode
|
5
|
+
class Coverage
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def initialize(**options)
|
9
|
+
@covered_code_index = {}
|
10
|
+
@options = options
|
11
|
+
end
|
12
|
+
|
13
|
+
def covered_codes
|
14
|
+
@covered_code_index.values
|
15
|
+
end
|
16
|
+
|
17
|
+
def reset
|
18
|
+
@covered_code_index = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def line_coverage(filename, **options)
|
22
|
+
covered_code(filename).line_coverage(**options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def covered_code(path, **options)
|
26
|
+
raise 'path must be an absolute path' unless Pathname.new(path).absolute?
|
27
|
+
@covered_code_index[path] ||= CoveredCode.new(path: path, **options, **@options)
|
28
|
+
end
|
29
|
+
|
30
|
+
def each
|
31
|
+
return to_enum unless block_given?
|
32
|
+
@covered_code_index.each_value { |covered_code| yield covered_code }
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def report(**options)
|
37
|
+
case (reporter = options.fetch(:reporter, :html).to_sym)
|
38
|
+
when :html
|
39
|
+
Reporter::HTML.report(self, **options)
|
40
|
+
when :istanbul
|
41
|
+
if Reporter::Istanbul.available?
|
42
|
+
report_istanbul(**options)
|
43
|
+
else
|
44
|
+
warn 'nyc not available. Please install `nyc` using `yarn global add nyc` or `npm i nyc -g`'
|
45
|
+
end
|
46
|
+
when :text
|
47
|
+
basic_report
|
48
|
+
else
|
49
|
+
raise ArgumentError, "Unknown reporter: #{reporter}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def basic_report
|
54
|
+
missing = map do |covered_code|
|
55
|
+
if covered_code.has_executed?
|
56
|
+
missed = covered_code.line_coverage.each_with_index.map do |line_cov, line_index|
|
57
|
+
line_index + 1 if line_cov == 0
|
58
|
+
end.compact
|
59
|
+
else
|
60
|
+
missed = ['all']
|
61
|
+
end
|
62
|
+
[covered_code.buffer.name, missed] unless missed.empty?
|
63
|
+
end.compact.to_h
|
64
|
+
missing.map do |path, lines|
|
65
|
+
"#{File.basename(path)}: #{lines.join(', ')}"
|
66
|
+
end.join("\n")
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.load(dest_path, dirname = 'deep_cover', with_trackers: true)
|
70
|
+
Persistence.new(dest_path, dirname).load(with_trackers: with_trackers)
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.saved?(dest_path, dirname = 'deep_cover')
|
74
|
+
Persistence.new(dest_path, dirname).saved?
|
75
|
+
end
|
76
|
+
|
77
|
+
def save(dest_path, dirname = 'deep_cover')
|
78
|
+
Persistence.new(dest_path, dirname).save(self)
|
79
|
+
self
|
80
|
+
end
|
81
|
+
|
82
|
+
def save_trackers(dest_path, dirname = 'deep_cover')
|
83
|
+
Persistence.new(dest_path, dirname).save_trackers(tracker_global)
|
84
|
+
self
|
85
|
+
end
|
86
|
+
|
87
|
+
def tracker_global
|
88
|
+
@options.fetch(:tracker_global, CoveredCode::DEFAULT_TRACKER_GLOBAL)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|