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 =
/NODE_(.?CALL|.VAR|.ASGN|DEFN)/.freeze
- DOGFOOD =
Deviate from the standard policy above, because all the files are already loaded, so we skip NODE_FCALL.
/NODE_([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.
/NODE_(ARGS|CDECL)/.freeze
Instance Attribute Summary collapse
-
#paths ⇒ Object
readonly
Returns the value of attribute paths.
Attributes inherited from Wrapper
Instance Method Summary collapse
- #disable ⇒ Object
- #each(&block) ⇒ Object
- #enable ⇒ Object
- #executable?(node) ⇒ Boolean
- #expand(node, counts) ⇒ Object
- #ignore?(node) ⇒ Boolean
-
#initialize(output, executable: EXECUTABLE, ignore: IGNORE) ⇒ Source
constructor
A new instance of Source.
- #intercept_eval(string, binding = nil, filename = nil, lineno = 1) ⇒ Object
- #parse(path) ⇒ Object
Methods inherited from Wrapper
Constructor Details
#initialize(output, executable: EXECUTABLE, ignore: IGNORE) ⇒ Source
Returns a new instance of Source.
38 39 40 41 42 43 44 45 46 |
# File 'lib/covered/source.rb', line 38 def initialize(output, executable: EXECUTABLE, ignore: IGNORE) super(output) @paths = {} @mutex = Mutex.new @executable = executable @ignore = ignore end |
Instance Attribute Details
#paths ⇒ Object (readonly)
Returns the value of attribute paths.
60 61 62 |
# File 'lib/covered/source.rb', line 60 def paths @paths end |
Instance Method Details
#disable ⇒ Object
54 55 56 57 58 |
# File 'lib/covered/source.rb', line 54 def disable Eval::disable(self) super end |
#each(&block) ⇒ Object
104 105 106 107 108 109 110 111 112 113 |
# File 'lib/covered/source.rb', line 104 def each(&block) @output.each do |coverage| # This is a little bit inefficient, perhaps add a cache layer? if top = parse(coverage.path) (top, coverage.counts) end yield coverage.freeze end end |
#enable ⇒ Object
48 49 50 51 52 |
# File 'lib/covered/source.rb', line 48 def enable super Eval::enable(self) end |
#executable?(node) ⇒ Boolean
71 72 73 |
# File 'lib/covered/source.rb', line 71 def executable?(node) node.type =~ @executable end |
#expand(node, counts) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/covered/source.rb', line 80 def (node, counts) # puts "#{node.first_lineno}: #{node.inspect}" counts[node.first_lineno] ||= 0 if executable?(node) node.children.each do |child| next if child.nil? or ignore?(child) (child, counts) end end |
#ignore?(node) ⇒ Boolean
75 76 77 78 |
# File 'lib/covered/source.rb', line 75 def ignore?(node) # NODE_ARGS Ruby doesn't report execution of arguments in :line tracepoint. node.type =~ @ignore end |
#intercept_eval(string, binding = nil, filename = nil, lineno = 1) ⇒ Object
62 63 64 65 66 67 68 69 |
# File 'lib/covered/source.rb', line 62 def intercept_eval(string, binding = nil, filename = nil, lineno = 1) return unless filename # TODO replace with Concurrent::Map @mutex.synchronize do @paths[filename] = string end end |
#parse(path) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/covered/source.rb', line 92 def parse(path) # puts "Parse #{path}" if source = @paths[path] RubyVM::AST.parse(source) elsif File.exist?(path) RubyVM::AST.parse_file(path) else warn "Couldn't parse #{path}, file doesn't exist?" end end |