Class: DeepCover::ExpressionDebugger

Inherits:
Object
  • Object
show all
Includes:
Tools
Defined in:
lib/deep_cover/expression_debugger.rb

Defined Under Namespace

Modules: ColorAST

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source, filename: '(source)', lineno: 1, debug: false, **options) ⇒ ExpressionDebugger

Returns a new instance of ExpressionDebugger.


24
25
26
27
28
29
30
# File 'lib/deep_cover/expression_debugger.rb', line 24

def initialize(source, filename: '(source)', lineno: 1, debug: false, **options)
  @source = source
  @filename = filename
  @lineno = lineno
  @debug = debug
  @options = options
end

Instance Attribute Details

#optionsObject (readonly)

Returns the value of attribute options


23
24
25
# File 'lib/deep_cover/expression_debugger.rb', line 23

def options
  @options
end

Instance Method Details

#covered_codeObject


91
92
93
# File 'lib/deep_cover/expression_debugger.rb', line 91

def covered_code
  @covered_code ||= CoveredCode.new(source: @source, path: @filename, lineno: @lineno)
end

#executeObject


95
96
97
98
99
100
101
# File 'lib/deep_cover/expression_debugger.rb', line 95

def execute
  execute_sample(covered_code)
# output { trace_counts }  # Keep for low-level debugging purposes
rescue Exception => e
  output { "Can't `execute_sample`:#{e.class}: #{e}\n#{e.backtrace.join("\n")}" }
  @failed = true
end

#finishObject


87
88
89
# File 'lib/deep_cover/expression_debugger.rb', line 87

def finish
  exit(!@failed)
end

#outputObject


116
117
118
119
120
# File 'lib/deep_cover/expression_debugger.rb', line 116

def output
  Tools.dont_profile do
    puts yield
  end
end

#pryObject


80
81
82
83
84
85
# File 'lib/deep_cover/expression_debugger.rb', line 80

def pry
  a = covered_code.covered_ast
  b = a.children.first
  ::DeepCover.load_pry
  binding.pry
end

#showObject


32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/deep_cover/expression_debugger.rb', line 32

def show
  Tools.profile(options[:profile]) do
    execute
    covered_code.freeze # Our output relies on the counts, so better freeze. See [#13]
    if @debug
      show_line_coverage
      show_instrumented_code
      show_ast
    end
    show_char_coverage
  end
  pry if @debug
  finish
end

#show_astObject


68
69
70
71
72
# File 'lib/deep_cover/expression_debugger.rb', line 68

def show_ast
  output { "\nParsed code:\n" }
  Node.prepend ColorAST
  output { covered_code.covered_ast }
end

#show_char_coverageObject


74
75
76
77
78
# File 'lib/deep_cover/expression_debugger.rb', line 74

def show_char_coverage
  output { "\nNode coverage:\n" }

  output { format_char_cover(covered_code, show_whitespace: !!ENV['W'], **options) }
end

#show_instrumented_codeObject


63
64
65
66
# File 'lib/deep_cover/expression_debugger.rb', line 63

def show_instrumented_code
  output { "\nInstrumented code:\n" }
  output { format_generated_code(covered_code) }
end

#show_line_coverageObject


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/deep_cover/expression_debugger.rb', line 47

def show_line_coverage
  output { "Line Coverage: Builtin | DeepCover | DeepCover Strict:\n" }
  begin
    builtin_line_coverage = builtin_coverage(@source, @filename, @lineno)
    our_line_coverage = our_coverage(@source, @filename, @lineno, **options)
    our_strict_line_coverage = our_coverage(@source, @filename, @lineno, allow_partial: false, **options)
    output do
      lines = format(builtin_line_coverage, our_line_coverage, our_strict_line_coverage, source: @source)
      number_lines(lines, lineno: @lineno)
    end
  rescue Exception => e
    output { "Can't run coverage: #{e.class}: #{e}\n#{e.backtrace.join("\n")}" }
    @failed = true
  end
end

#trace_countsObject


103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/deep_cover/expression_debugger.rb', line 103

def trace_counts
  all = []
  trace = TracePoint.new(:call) do |tr|
    if %i[flow_entry_count flow_completion_count execution_count].include? tr.method_id
      node = tr.self
      str = "#{node.type} #{(node.value if node.respond_to?(:value))} #{tr.method_id}"
      all << str unless all.last == str
    end
  end
  trace.enable { covered_code.freeze }
  all
end