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 =
/(.?CALL|.VAR|.ASGN|DEFN)/.freeze
- DOGFOOD =
Deviate from the standard policy above, because all the files are already loaded, so we skip NODE_FCALL.
/(^V?CALL|.VAR|.ASGN|DEFN)/.freeze
- IGNORE =
Ruby trace points don’t trigger for argument execution. Constants are loaded when the file loads, so they are less interesting.
/(ARGS|CDECL)/.freeze
Instance Attribute Summary collapse
Attributes inherited from Wrapper
#output
Instance Method Summary
collapse
Methods inherited from Wrapper
#expand_path, #mark, #relative_path, #to_h
Constructor Details
#initialize(output, executable: EXECUTABLE, ignore: IGNORE) ⇒ Source
Returns a new instance of Source.
40
41
42
43
44
45
46
47
48
49
50
|
# File 'lib/covered/source.rb', line 40
def initialize(output, executable: EXECUTABLE, ignore: IGNORE)
super(output)
@paths = {}
@mutex = Mutex.new
@executable = executable
@ignore = ignore
@annotations = {}
end
|
Instance Attribute Details
#paths ⇒ Object
Returns the value of attribute paths.
64
65
66
|
# File 'lib/covered/source.rb', line 64
def paths
@paths
end
|
Instance Method Details
#disable ⇒ Object
58
59
60
61
62
|
# File 'lib/covered/source.rb', line 58
def disable
Eval::disable(self)
super
end
|
#each(&block) ⇒ Object
117
118
119
120
121
122
123
124
125
|
# File 'lib/covered/source.rb', line 117
def each(&block)
@output.each do |coverage|
if top = parse(coverage.path)
self.expand(top, coverage)
end
yield coverage.freeze
end
end
|
#enable ⇒ Object
52
53
54
55
56
|
# File 'lib/covered/source.rb', line 52
def enable
super
Eval::enable(self)
end
|
#executable?(node) ⇒ Boolean
74
75
76
|
# File 'lib/covered/source.rb', line 74
def executable?(node)
node.type == :send
end
|
#expand(node, coverage, level = 0) ⇒ Object
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
# File 'lib/covered/source.rb', line 82
def expand(node, coverage, level = 0)
if node.is_a? Parser::AST::Node
if ignore?(node)
coverage.annotate(node.location.line, "ignoring #{node.type}")
else
if executable?(node)
coverage.counts[node.location.line] ||= 0
else
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
78
79
80
|
# File 'lib/covered/source.rb', line 78
def ignore?(node)
node.nil? or node.type == :arg
end
|
#intercept_eval(string, binding = nil, filename = nil, lineno = 1) ⇒ Object
66
67
68
69
70
71
72
|
# File 'lib/covered/source.rb', line 66
def intercept_eval(string, binding = nil, filename = nil, lineno = 1)
return unless filename
@mutex.synchronize do
@paths[filename] = string
end
end
|
#parse(path) ⇒ Object
105
106
107
108
109
110
111
112
113
114
115
|
# File 'lib/covered/source.rb', line 105
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
|