Class: DeepCover::CoveredCode
- Inherits:
-
Object
- Object
- DeepCover::CoveredCode
- Defined in:
- lib/deep_cover/covered_code.rb
Constant Summary collapse
- DEFAULT_TRACKER_GLOBAL =
'$_cov'- @@counter =
0- @@globals =
rubocop:disable Security/Eval
Hash.new { |h, global| h[global] = eval("#{global} ||= {}") }
Instance Attribute Summary collapse
-
#buffer ⇒ Object
Returns the value of attribute buffer.
-
#covered_source ⇒ Object
Returns the value of attribute covered_source.
-
#local_var ⇒ Object
Returns the value of attribute local_var.
-
#name ⇒ Object
Returns the value of attribute name.
-
#tracker_global ⇒ Object
Returns the value of attribute tracker_global.
Instance Method Summary collapse
-
#allocate_trackers(nb_needed) ⇒ Object
Returns a range of tracker ids.
- #char_cover(**options) ⇒ Object
- #cover ⇒ Object
- #covered_ast ⇒ Object
- #each_node(*args, &block) ⇒ Object
- #execute_code(binding: DeepCover::GLOBAL_BINDING.dup) ⇒ Object
- #freeze ⇒ Object
- #has_executed? ⇒ Boolean
-
#initialize(path: nil, source: nil, lineno: 1, tracker_global: DEFAULT_TRACKER_GLOBAL, local_var: '_temp', name: nil) ⇒ CoveredCode
constructor
A new instance of CoveredCode.
- #instrument_source ⇒ Object
- #line_coverage(**options) ⇒ Object
- #lineno ⇒ Object
- #nb ⇒ Object
- #nb_lines ⇒ Object
- #path ⇒ Object
- #root ⇒ Object
- #to_istanbul(**options) ⇒ Object
- #tracker_hits(tracker_id) ⇒ Object
- #tracker_source(tracker_id) ⇒ Object
- #trackers_setup_source ⇒ Object
Constructor Details
#initialize(path: nil, source: nil, lineno: 1, tracker_global: DEFAULT_TRACKER_GLOBAL, local_var: '_temp', name: nil) ⇒ CoveredCode
Returns a new instance of CoveredCode.
11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/deep_cover/covered_code.rb', line 11 def initialize(path: nil, source: nil, lineno: 1, tracker_global: DEFAULT_TRACKER_GLOBAL, local_var: '_temp', name: nil) raise 'Must provide either path or source' unless path || source @buffer = ::Parser::Source::Buffer.new(path, lineno) @buffer.source = source ||= File.read(path) @tracker_count = 0 @tracker_global = tracker_global @local_var = local_var @name = name || (source ? '(source)' : File.basename(path)) @covered_source = instrument_source end |
Instance Attribute Details
#buffer ⇒ Object
Returns the value of attribute buffer.
7 8 9 |
# File 'lib/deep_cover/covered_code.rb', line 7 def buffer @buffer end |
#covered_source ⇒ Object
Returns the value of attribute covered_source.
7 8 9 |
# File 'lib/deep_cover/covered_code.rb', line 7 def covered_source @covered_source end |
#local_var ⇒ Object
Returns the value of attribute local_var.
7 8 9 |
# File 'lib/deep_cover/covered_code.rb', line 7 def local_var @local_var end |
#name ⇒ Object
Returns the value of attribute name.
7 8 9 |
# File 'lib/deep_cover/covered_code.rb', line 7 def name @name end |
#tracker_global ⇒ Object
Returns the value of attribute tracker_global.
7 8 9 |
# File 'lib/deep_cover/covered_code.rb', line 7 def tracker_global @tracker_global end |
Instance Method Details
#allocate_trackers(nb_needed) ⇒ Object
Returns a range of tracker ids
72 73 74 75 76 |
# File 'lib/deep_cover/covered_code.rb', line 72 def allocate_trackers(nb_needed) prev = @tracker_count @tracker_count += nb_needed if nb_needed > 0 # Avoid error if frozen and called with 0. prev...@tracker_count end |
#char_cover(**options) ⇒ Object
62 63 64 65 |
# File 'lib/deep_cover/covered_code.rb', line 62 def char_cover(**) must_have_executed Analyser::PerChar.new(self, **).results end |
#cover ⇒ Object
47 48 49 50 |
# File 'lib/deep_cover/covered_code.rb', line 47 def cover must_have_executed global[nb] end |
#covered_ast ⇒ Object
90 91 92 |
# File 'lib/deep_cover/covered_code.rb', line 90 def covered_ast root.main end |
#each_node(*args, &block) ⇒ Object
101 102 103 |
# File 'lib/deep_cover/covered_code.rb', line 101 def each_node(*args, &block) covered_ast.each_node(*args, &block) end |
#execute_code(binding: DeepCover::GLOBAL_BINDING.dup) ⇒ Object
40 41 42 43 44 45 |
# File 'lib/deep_cover/covered_code.rb', line 40 def execute_code(binding: DeepCover::GLOBAL_BINDING.dup) return if has_executed? global[nb] = Array.new(@tracker_count, 0) eval(@covered_source, binding, @buffer.name || '<raw_code>', lineno) # rubocop:disable Security/Eval self end |
#freeze ⇒ Object
127 128 129 130 131 132 133 134 |
# File 'lib/deep_cover/covered_code.rb', line 127 def freeze unless frozen? # Guard against reentrance must_have_executed super root.each_node(&:freeze) end self end |
#has_executed? ⇒ Boolean
123 124 125 |
# File 'lib/deep_cover/covered_code.rb', line 123 def has_executed? global[nb] != nil end |
#instrument_source ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/deep_cover/covered_code.rb', line 105 def instrument_source rewriter = ::Parser::Source::Rewriter.new(@buffer) covered_ast.each_node(:postorder) do |node| node.rewriting_rules.each do |range, rule| prefix, _node, suffix = rule.partition('%{node}') unless prefix.empty? prefix = yield prefix, node, range.begin, :prefix if block_given? rewriter.insert_before_multi range, prefix end unless suffix.empty? suffix = yield suffix, node, range.end, :suffix if block_given? rewriter.insert_after_multi range, suffix end end end rewriter.process end |
#line_coverage(**options) ⇒ Object
52 53 54 55 |
# File 'lib/deep_cover/covered_code.rb', line 52 def line_coverage(**) must_have_executed Analyser::PerLine.new(self, **).results end |
#lineno ⇒ Object
27 28 29 |
# File 'lib/deep_cover/covered_code.rb', line 27 def lineno @buffer.first_line end |
#nb ⇒ Object
67 68 69 |
# File 'lib/deep_cover/covered_code.rb', line 67 def nb @nb ||= (@@counter += 1) end |
#nb_lines ⇒ Object
31 32 33 34 35 36 37 38 |
# File 'lib/deep_cover/covered_code.rb', line 31 def nb_lines lines = buffer.source_lines if lines.empty? 0 else lines.size - (lines.last.empty? ? 1 : 0) end end |
#path ⇒ Object
23 24 25 |
# File 'lib/deep_cover/covered_code.rb', line 23 def path @buffer.name || "(source: '#{@buffer.source[0..20]}...')" end |
#root ⇒ Object
94 95 96 97 98 99 |
# File 'lib/deep_cover/covered_code.rb', line 94 def root @root ||= begin ast = DeepCover.parser.parse(@buffer) Node::Root.new(ast, self) end end |
#to_istanbul(**options) ⇒ Object
57 58 59 60 |
# File 'lib/deep_cover/covered_code.rb', line 57 def to_istanbul(**) must_have_executed Reporter::Istanbul.new(self, **).convert end |
#tracker_hits(tracker_id) ⇒ Object
86 87 88 |
# File 'lib/deep_cover/covered_code.rb', line 86 def tracker_hits(tracker_id) cover.fetch(tracker_id) end |
#tracker_source(tracker_id) ⇒ Object
78 79 80 |
# File 'lib/deep_cover/covered_code.rb', line 78 def tracker_source(tracker_id) "#{tracker_global}[#{nb}][#{tracker_id}]+=1" end |
#trackers_setup_source ⇒ Object
82 83 84 |
# File 'lib/deep_cover/covered_code.rb', line 82 def trackers_setup_source "(#{tracker_global}||={})[#{nb}]||=Array.new(#{@tracker_count},0)" end |