Class: Covered::Source
Overview
The source map, loads the source file, parses the AST to generate which lines contain executable code.
Constant Summary
collapse
- EXECUTABLE =
{
send: true,
yield: true,
def: true,
if: true,
lvasgn: true,
ivasgn: true,
cvasgn: true,
gvasgn: true,
match_pattern: true
}
- IGNORE =
{
arg: true,
rescue: true
}
Instance Attribute Summary collapse
Attributes inherited from Wrapper
#output
Instance Method Summary
collapse
Methods inherited from Wrapper
#accept?, #expand_path, #flush, #mark, #relative_path, #to_h
Methods inherited from Base
#accept?, #expand_path, #flush, #mark, #relative_path
Constructor Details
#initialize(output) ⇒ Source
Returns a new instance of Source.
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
# File 'lib/covered/source.rb', line 29
def initialize(output)
super(output)
@paths = {}
@mutex = Mutex.new
@annotations = {}
begin
@trace = TracePoint.new(:script_compiled) do |trace|
instruction_sequence = trace.instruction_sequence
if instruction_sequence.first_lineno <= 1
if path = instruction_sequence.path and source = trace.eval_script
@mutex.synchronize do
@paths[path] = source
end
end
end
end
rescue
warn "Script coverage disabled: #{$!}"
@trace = nil
end
end
|
Instance Attribute Details
#paths ⇒ Object
Returns the value of attribute paths.
69
70
71
|
# File 'lib/covered/source.rb', line 69
def paths
@paths
end
|
Instance Method Details
#disable ⇒ Object
63
64
65
66
67
|
# File 'lib/covered/source.rb', line 63
def disable
@trace&.disable
super
end
|
#each(&block) ⇒ Object
141
142
143
144
145
146
147
148
149
|
# File 'lib/covered/source.rb', line 141
def each(&block)
@output.each do |coverage|
if top = parse(coverage.path)
self.expand(top, coverage)
end
yield coverage.freeze
end
end
|
#enable ⇒ Object
57
58
59
60
61
|
# File 'lib/covered/source.rb', line 57
def enable
super
@trace&.enable
end
|
#executable?(node) ⇒ Boolean
85
86
87
|
# File 'lib/covered/source.rb', line 85
def executable?(node)
EXECUTABLE[node.type]
end
|
#expand(node, coverage, level = 0) ⇒ Object
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
# File 'lib/covered/source.rb', line 99
def expand(node, coverage, level = 0)
if node.is_a? Parser::AST::Node
if ignore?(node)
else
if node.type == :send
coverage.counts[node.location.selector.line] ||= 0
elsif executable?(node)
coverage.counts[node.location.line] ||= 0
end
expand(node.children, coverage, level + 1)
end
elsif node.is_a? Array
node.each do |child|
expand(child, coverage, level)
end
else
return false
end
end
|
#ignore?(node) ⇒ Boolean
95
96
97
|
# File 'lib/covered/source.rb', line 95
def ignore?(node)
node.nil? || IGNORE[node.type]
end
|
#parse(path) ⇒ Object
129
130
131
132
133
134
135
136
137
138
139
|
# File 'lib/covered/source.rb', line 129
def parse(path)
if source = @paths[path]
Parser::CurrentRuby.parse(source)
elsif File.exist?(path)
Parser::CurrentRuby.parse_file(path)
else
warn "Couldn't parse #{path}, file doesn't exist?"
end
rescue
warn "Couldn't parse #{path}: #{$!}"
end
|