deep-cover 0.5.2 → 0.5.3

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.
Files changed (84) hide show
  1. checksums.yaml +5 -5
  2. data/.deep_cover.rb +8 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +15 -1
  5. data/.travis.yml +1 -0
  6. data/README.md +30 -1
  7. data/Rakefile +10 -1
  8. data/bin/cov +1 -1
  9. data/deep_cover.gemspec +4 -5
  10. data/exe/deep-cover +5 -3
  11. data/lib/deep_cover.rb +1 -1
  12. data/lib/deep_cover/analyser/node.rb +1 -1
  13. data/lib/deep_cover/analyser/ruby25_like_branch.rb +209 -0
  14. data/lib/deep_cover/auto_run.rb +19 -19
  15. data/lib/deep_cover/autoload_tracker.rb +181 -44
  16. data/lib/deep_cover/backports.rb +3 -1
  17. data/lib/deep_cover/base.rb +13 -8
  18. data/lib/deep_cover/basics.rb +1 -1
  19. data/lib/deep_cover/cli/debugger.rb +2 -2
  20. data/lib/deep_cover/cli/instrumented_clone_reporter.rb +21 -8
  21. data/lib/deep_cover/cli/runner.rb +126 -0
  22. data/lib/deep_cover/config_setter.rb +1 -0
  23. data/lib/deep_cover/core_ext/autoload_overrides.rb +82 -14
  24. data/lib/deep_cover/core_ext/coverage_replacement.rb +34 -5
  25. data/lib/deep_cover/core_ext/exec_callbacks.rb +27 -0
  26. data/lib/deep_cover/core_ext/load_overrides.rb +4 -6
  27. data/lib/deep_cover/core_ext/require_overrides.rb +1 -3
  28. data/lib/deep_cover/coverage.rb +105 -2
  29. data/lib/deep_cover/coverage/analysis.rb +30 -28
  30. data/lib/deep_cover/coverage/persistence.rb +60 -70
  31. data/lib/deep_cover/covered_code.rb +16 -49
  32. data/lib/deep_cover/custom_requirer.rb +112 -51
  33. data/lib/deep_cover/load.rb +10 -6
  34. data/lib/deep_cover/memoize.rb +1 -3
  35. data/lib/deep_cover/module_override.rb +7 -0
  36. data/lib/deep_cover/node/assignments.rb +2 -1
  37. data/lib/deep_cover/node/base.rb +6 -6
  38. data/lib/deep_cover/node/block.rb +10 -8
  39. data/lib/deep_cover/node/case.rb +3 -3
  40. data/lib/deep_cover/node/collections.rb +8 -0
  41. data/lib/deep_cover/node/if.rb +19 -3
  42. data/lib/deep_cover/node/literals.rb +28 -7
  43. data/lib/deep_cover/node/mixin/can_augment_children.rb +4 -4
  44. data/lib/deep_cover/node/mixin/child_can_be_empty.rb +1 -1
  45. data/lib/deep_cover/node/mixin/filters.rb +6 -2
  46. data/lib/deep_cover/node/mixin/has_child.rb +8 -8
  47. data/lib/deep_cover/node/mixin/has_child_handler.rb +3 -3
  48. data/lib/deep_cover/node/mixin/has_tracker.rb +7 -3
  49. data/lib/deep_cover/node/root.rb +1 -1
  50. data/lib/deep_cover/node/send.rb +53 -7
  51. data/lib/deep_cover/node/short_circuit.rb +11 -3
  52. data/lib/deep_cover/parser_ext/range.rb +11 -27
  53. data/lib/deep_cover/problem_with_diagnostic.rb +1 -1
  54. data/lib/deep_cover/reporter.rb +0 -1
  55. data/lib/deep_cover/reporter/base.rb +68 -0
  56. data/lib/deep_cover/reporter/html.rb +1 -1
  57. data/lib/deep_cover/reporter/html/index.rb +4 -8
  58. data/lib/deep_cover/reporter/html/site.rb +10 -18
  59. data/lib/deep_cover/reporter/html/source.rb +3 -3
  60. data/lib/deep_cover/reporter/html/template/source.html.erb +1 -1
  61. data/lib/deep_cover/reporter/istanbul.rb +86 -56
  62. data/lib/deep_cover/reporter/text.rb +5 -13
  63. data/lib/deep_cover/reporter/{util/tree.rb → tree/util.rb} +19 -21
  64. data/lib/deep_cover/tools/blank.rb +25 -0
  65. data/lib/deep_cover/tools/builtin_coverage.rb +8 -8
  66. data/lib/deep_cover/tools/dump_covered_code.rb +2 -9
  67. data/lib/deep_cover/tools/execute_sample.rb +17 -6
  68. data/lib/deep_cover/tools/format_generated_code.rb +1 -1
  69. data/lib/deep_cover/tools/indent_string.rb +26 -0
  70. data/lib/deep_cover/tools/our_coverage.rb +2 -2
  71. data/lib/deep_cover/tools/strip_heredoc.rb +18 -0
  72. data/lib/deep_cover/tracker_bucket.rb +50 -0
  73. data/lib/deep_cover/tracker_hits_per_path.rb +35 -0
  74. data/lib/deep_cover/tracker_storage.rb +76 -0
  75. data/lib/deep_cover/tracker_storage_per_path.rb +34 -0
  76. data/lib/deep_cover/version.rb +1 -1
  77. data/lib/deep_cover_entry.rb +3 -0
  78. metadata +30 -37
  79. data/bin/gemcov +0 -8
  80. data/bin/selfcov +0 -21
  81. data/lib/deep_cover/cli/deep_cover.rb +0 -126
  82. data/lib/deep_cover/coverage/base.rb +0 -81
  83. data/lib/deep_cover/coverage/istanbul.rb +0 -34
  84. data/lib/deep_cover/tools/transform_keys.rb +0 -9
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeepCover
4
+ bootstrap
5
+
6
+ # Should be seen as a hash like {path => tracker_storage, ...}
7
+ # Make it easier to separate some concerns, as well as marshalling
8
+ #
9
+ class TrackerStoragePerPath
10
+ extend Forwardable
11
+ def_delegators :@index, :each, :each_key, :map, :transform_values
12
+
13
+ attr_reader :bucket
14
+
15
+ def initialize(bucket)
16
+ @bucket = bucket
17
+ @index = {}
18
+ end
19
+
20
+ def [](path)
21
+ @index[path] ||= @bucket.create_storage
22
+ end
23
+
24
+ def tracker_hits_per_path
25
+ TrackerHitsPerPath.new(@index.transform_values(&:tracker_hits))
26
+ end
27
+
28
+ def tracker_hits_per_path=(tracker_hits_per_path)
29
+ tracker_hits_per_path.each do |path, tracker_hits|
30
+ self[path].tracker_hits = tracker_hits
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DeepCover
4
- VERSION = '0.5.2'
4
+ VERSION = '0.5.3'
5
5
  end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This empty file is just a hack so we can self-cover our exe/deep-cover
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deep-cover
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc-André Lafortune
@@ -9,52 +9,52 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2018-02-15 00:00:00.000000000 Z
12
+ date: 2018-05-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: parser
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ">="
18
+ - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: '0'
20
+ version: 2.5.0
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - ">="
25
+ - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: '0'
27
+ version: 2.5.0
28
28
  - !ruby/object:Gem::Dependency
29
- name: parser_tree_rewriter
29
+ name: backports
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: '0'
34
+ version: 3.11.0
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
- version: '0'
41
+ version: 3.11.0
42
42
  - !ruby/object:Gem::Dependency
43
- name: backports
43
+ name: binding_of_caller
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - ">="
47
47
  - !ruby/object:Gem::Version
48
- version: 3.11.0
48
+ version: '0'
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - ">="
54
54
  - !ruby/object:Gem::Version
55
- version: 3.11.0
55
+ version: '0'
56
56
  - !ruby/object:Gem::Dependency
57
- name: binding_of_caller
57
+ name: bundler
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - ">="
@@ -151,20 +151,6 @@ dependencies:
151
151
  - - ">="
152
152
  - !ruby/object:Gem::Version
153
153
  version: '0'
154
- - !ruby/object:Gem::Dependency
155
- name: activesupport
156
- requirement: !ruby/object:Gem::Requirement
157
- requirements:
158
- - - "~>"
159
- - !ruby/object:Gem::Version
160
- version: '4.0'
161
- type: :development
162
- prerelease: false
163
- version_requirements: !ruby/object:Gem::Requirement
164
- requirements:
165
- - - "~>"
166
- - !ruby/object:Gem::Version
167
- version: '4.0'
168
154
  - !ruby/object:Gem::Dependency
169
155
  name: bundler
170
156
  requirement: !ruby/object:Gem::Requirement
@@ -227,14 +213,14 @@ dependencies:
227
213
  requirements:
228
214
  - - '='
229
215
  - !ruby/object:Gem::Version
230
- version: 0.52.1
216
+ version: 0.53.0
231
217
  type: :development
232
218
  prerelease: false
233
219
  version_requirements: !ruby/object:Gem::Requirement
234
220
  requirements:
235
221
  - - '='
236
222
  - !ruby/object:Gem::Version
237
- version: 0.52.1
223
+ version: 0.53.0
238
224
  description: expression and branch coverage for Ruby.
239
225
  email:
240
226
  - github@marc-andre.ca
@@ -244,6 +230,7 @@ executables:
244
230
  extensions: []
245
231
  extra_rdoc_files: []
246
232
  files:
233
+ - ".deep_cover.rb"
247
234
  - ".gitignore"
248
235
  - ".rspec"
249
236
  - ".rspec_all"
@@ -258,8 +245,6 @@ files:
258
245
  - Rakefile
259
246
  - bin/console
260
247
  - bin/cov
261
- - bin/gemcov
262
- - bin/selfcov
263
248
  - bin/setup
264
249
  - bin/test_gems
265
250
  - bin/testall
@@ -276,6 +261,7 @@ files:
276
261
  - lib/deep_cover/analyser/node.rb
277
262
  - lib/deep_cover/analyser/per_char.rb
278
263
  - lib/deep_cover/analyser/per_line.rb
264
+ - lib/deep_cover/analyser/ruby25_like_branch.rb
279
265
  - lib/deep_cover/analyser/statement.rb
280
266
  - lib/deep_cover/analyser/stats.rb
281
267
  - lib/deep_cover/analyser/subset.rb
@@ -286,19 +272,18 @@ files:
286
272
  - lib/deep_cover/basics.rb
287
273
  - lib/deep_cover/builtin_takeover.rb
288
274
  - lib/deep_cover/cli/debugger.rb
289
- - lib/deep_cover/cli/deep_cover.rb
290
275
  - lib/deep_cover/cli/exec.rb
291
276
  - lib/deep_cover/cli/instrumented_clone_reporter.rb
277
+ - lib/deep_cover/cli/runner.rb
292
278
  - lib/deep_cover/config.rb
293
279
  - lib/deep_cover/config_setter.rb
294
280
  - lib/deep_cover/core_ext/autoload_overrides.rb
295
281
  - lib/deep_cover/core_ext/coverage_replacement.rb
282
+ - lib/deep_cover/core_ext/exec_callbacks.rb
296
283
  - lib/deep_cover/core_ext/load_overrides.rb
297
284
  - lib/deep_cover/core_ext/require_overrides.rb
298
285
  - lib/deep_cover/coverage.rb
299
286
  - lib/deep_cover/coverage/analysis.rb
300
- - lib/deep_cover/coverage/base.rb
301
- - lib/deep_cover/coverage/istanbul.rb
302
287
  - lib/deep_cover/coverage/persistence.rb
303
288
  - lib/deep_cover/covered_code.rb
304
289
  - lib/deep_cover/custom_requirer.rb
@@ -345,6 +330,7 @@ files:
345
330
  - lib/deep_cover/parser_ext/range.rb
346
331
  - lib/deep_cover/problem_with_diagnostic.rb
347
332
  - lib/deep_cover/reporter.rb
333
+ - lib/deep_cover/reporter/base.rb
348
334
  - lib/deep_cover/reporter/html.rb
349
335
  - lib/deep_cover/reporter/html/base.rb
350
336
  - lib/deep_cover/reporter/html/index.rb
@@ -363,8 +349,9 @@ files:
363
349
  - lib/deep_cover/reporter/html/template/source.html.erb
364
350
  - lib/deep_cover/reporter/istanbul.rb
365
351
  - lib/deep_cover/reporter/text.rb
366
- - lib/deep_cover/reporter/util/tree.rb
352
+ - lib/deep_cover/reporter/tree/util.rb
367
353
  - lib/deep_cover/tools.rb
354
+ - lib/deep_cover/tools/blank.rb
368
355
  - lib/deep_cover/tools/builtin_coverage.rb
369
356
  - lib/deep_cover/tools/camelize.rb
370
357
  - lib/deep_cover/tools/content_tag.rb
@@ -374,6 +361,7 @@ files:
374
361
  - lib/deep_cover/tools/format.rb
375
362
  - lib/deep_cover/tools/format_char_cover.rb
376
363
  - lib/deep_cover/tools/format_generated_code.rb
364
+ - lib/deep_cover/tools/indent_string.rb
377
365
  - lib/deep_cover/tools/merge.rb
378
366
  - lib/deep_cover/tools/number_lines.rb
379
367
  - lib/deep_cover/tools/our_coverage.rb
@@ -382,9 +370,14 @@ files:
382
370
  - lib/deep_cover/tools/require_relative_dir.rb
383
371
  - lib/deep_cover/tools/silence_warnings.rb
384
372
  - lib/deep_cover/tools/slice.rb
385
- - lib/deep_cover/tools/transform_keys.rb
373
+ - lib/deep_cover/tools/strip_heredoc.rb
386
374
  - lib/deep_cover/tools/truncate_backtrace.rb
375
+ - lib/deep_cover/tracker_bucket.rb
376
+ - lib/deep_cover/tracker_hits_per_path.rb
377
+ - lib/deep_cover/tracker_storage.rb
378
+ - lib/deep_cover/tracker_storage_per_path.rb
387
379
  - lib/deep_cover/version.rb
380
+ - lib/deep_cover_entry.rb
388
381
  homepage: https://github.com/deep-cover/deep-cover
389
382
  licenses:
390
383
  - MIT
@@ -405,7 +398,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
405
398
  version: '0'
406
399
  requirements: []
407
400
  rubyforge_project:
408
- rubygems_version: 2.6.14
401
+ rubygems_version: 2.7.7
409
402
  signing_key:
410
403
  specification_version: 4
411
404
  summary: In depth coverage of your Ruby code.
data/bin/gemcov DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env ruby
2
- module DeepCover
3
- require 'bundler/setup'
4
- require 'deep_cover'
5
- require 'deep_cover/cli/instrumented_clone_reporter'
6
-
7
- CLI::InstrumentedCloneReporter.new(ARGV[0] || '~/inky-rb').run
8
- end
data/bin/selfcov DELETED
@@ -1,21 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'bundler/setup'
3
- require 'pry'
4
-
5
- covered_path = ARGV[0]
6
- if covered_path
7
- $LOAD_PATH.unshift(covered_path)
8
- end
9
- require 'deep_cover'
10
-
11
- if covered_path.nil?
12
- covered_path = DeepCover::Tools.dump_covered_code_and_save('./lib', dest_path: '../covered_deep_cover')
13
- puts 'Covered code generation done. Output in', covered_path
14
- exec 'bin/selfcov', covered_path
15
- else
16
- coverage = DeepCover::Coverage.load(covered_path)
17
- require 'rspec'
18
- error = RSpec::Core::Runner::run(Dir.glob('./spec/*_spec.rb'))
19
- puts 'Lines not covered:', coverage.report
20
- binding.pry
21
- end
@@ -1,126 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DeepCover
4
- require 'slop'
5
- require_relative '../basics'
6
-
7
- module CLI
8
- end
9
-
10
- module CLI::SlopExtension
11
- attr_accessor :stopped
12
- attr_reader :ignored
13
-
14
- def try_process(*)
15
- @ignored ||= 0
16
- return if stopped
17
- o = super
18
- @ignored += 1 unless o
19
- o
20
- end
21
- end
22
- Slop::Parser.prepend CLI::SlopExtension
23
-
24
- module CLI::DeepCover
25
- extend self
26
-
27
- def show_version
28
- require_relative '../version'
29
- require 'parser'
30
- puts "deep-cover v#{DeepCover::VERSION}; parser v#{Parser::VERSION}"
31
- end
32
-
33
- def show_help
34
- puts menu
35
- end
36
-
37
- class OptionParser < Struct.new(:delegate)
38
- def method_missing(method, *args, &block) # rubocop:disable Style/MethodMissing
39
- options = args.last
40
- if options.is_a?(Hash) && options.has_key?(:default)
41
- args[-2] += " [#{options[:default]}]"
42
- end
43
- delegate.public_send(method, *args, &block)
44
- end
45
- end
46
-
47
- def parse
48
- Slop.parse do |o|
49
- yield OptionParser.new(o)
50
- end
51
- end
52
-
53
- def menu
54
- @menu ||= parse do |o|
55
- o.banner = ['usage: deep-cover [options] exec <command ...>',
56
- ' or deep-cover [options] [path/to/app/or/gem]',
57
- ].join("\n")
58
- o.separator ''
59
- o.string '-o', '--output', 'output folder', default: DEFAULTS[:output]
60
- o.string '--reporter', 'reporter', default: DEFAULTS[:reporter]
61
- o.bool '--open', 'open the output coverage', default: CLI_DEFAULTS[:open]
62
-
63
- o.separator 'Coverage options'
64
- @ignore_uncovered_map = OPTIONALLY_COVERED.map do |option|
65
- default = DEFAULTS[:ignore_uncovered].include?(option)
66
- o.bool "--ignore-#{dasherize(option)}", '', default: default
67
- [:"ignore_#{option}", option]
68
- end.to_h
69
-
70
- o.separator "\nWhen not using ’exec’:"
71
- o.string '-c', '--command', 'command to run tests', default: CLI_DEFAULTS[:command]
72
- o.bool '--bundle', 'run bundle before the tests', default: CLI_DEFAULTS[:bundle]
73
- o.bool '--process', 'turn off to only redo the reporting', default: CLI_DEFAULTS[:process]
74
-
75
- o.separator "\nFor testing purposes:"
76
- o.bool '--profile', 'use profiler' unless RUBY_PLATFORM == 'java'
77
- o.string '-e', '--expression', 'test ruby expression instead of a covering a path'
78
- o.bool '-d', '--debug', 'enter debugging after cover'
79
-
80
- o.separator "\nOther available commands:"
81
- o.on('--version', 'print the version') do
82
- show_version
83
- exit
84
- end
85
- o.boolean('-h', '--help')
86
-
87
- o.boolean('exec', '', help: false) do
88
- o.parser.stopped = true if o.parser.ignored == 0
89
- end
90
- end
91
- end
92
-
93
- def convert_options(options)
94
- iu = options[:ignore_uncovered] = []
95
- @ignore_uncovered_map.each do |cli_option, option|
96
- iu << option if options.delete(cli_option)
97
- end
98
- options[:output] = false if ['false', 'f', ''].include?(options[:output])
99
- options
100
- end
101
-
102
- def go
103
- options = convert_options(menu.to_h)
104
- if options[:help]
105
- show_help
106
- elsif options[:expression]
107
- require_relative 'debugger'
108
- CLI::Debugger.new(options[:expression], **options).show
109
- elsif menu.parser.stopped
110
- require_relative 'exec'
111
- CLI::Exec.new(menu.arguments, **options).run
112
- else
113
- require_relative 'instrumented_clone_reporter'
114
- path = menu.arguments.first || '.'
115
- CLI::InstrumentedCloneReporter.new(path, **options).run
116
- end
117
- end
118
-
119
- private
120
-
121
- # Poor man's dasherize. 'an_example' => 'an-example'
122
- def dasherize(string)
123
- string.to_s.tr('_', '-')
124
- end
125
- end
126
- end
@@ -1,81 +0,0 @@
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, DEFAULTS[:reporter]).to_sym)
38
- when :html
39
- msg = if (output = options.fetch(:output, DEFAULTS[:output]))
40
- Reporter::HTML.report(self, **options)
41
- "HTML generated: open #{output}/index.html"
42
- else
43
- 'No HTML generated'
44
- end
45
- Reporter::Text.report(self, **options) + "\n\n" + msg
46
- when :istanbul
47
- if Reporter::Istanbul.available?
48
- report_istanbul(**options)
49
- else
50
- warn 'nyc not available. Please install `nyc` using `yarn global add nyc` or `npm i nyc -g`'
51
- end
52
- when :text
53
- Reporter::Text.report(self, **options)
54
- else
55
- raise ArgumentError, "Unknown reporter: #{reporter}"
56
- end
57
- end
58
-
59
- def self.load(dest_path, dirname = 'deep_cover', with_trackers: true)
60
- Persistence.new(dest_path, dirname).load(with_trackers: with_trackers)
61
- end
62
-
63
- def self.saved?(dest_path, dirname = 'deep_cover')
64
- Persistence.new(dest_path, dirname).saved?
65
- end
66
-
67
- def save(dest_path, dirname = 'deep_cover')
68
- Persistence.new(dest_path, dirname).save(self)
69
- self
70
- end
71
-
72
- def save_trackers(dest_path, dirname = 'deep_cover')
73
- Persistence.new(dest_path, dirname).save_trackers(tracker_global)
74
- self
75
- end
76
-
77
- def tracker_global
78
- @options.fetch(:tracker_global, DEFAULTS[:tracker_global])
79
- end
80
- end
81
- end