Skip to content

Instantly share code, notes, and snippets.

@fronx
Last active December 21, 2015 14:19
Show Gist options
  • Save fronx/6319301 to your computer and use it in GitHub Desktop.
Save fronx/6319301 to your computer and use it in GitHub Desktop.
require 'ripper'
class TestParser < Ripper::SexpBuilder
def self.from_file(filename)
TestParser.new(File.read(filename))
end
def parse
@methods = []
@calls = []
super
end
def on_def(*args)
# [:def, [:@ident, "db", [35, 8]], [:params, nil, nil, nil, nil, nil], [:bodystmt, [:stmts_add, [:stmts_new], [:var_ref, [:@ivar, "@con", [36, 6]]]], nil, nil, nil]]
super.tap do |(_def, (_ident, name, _coords), *other)|
@methods << name
end
end
def on_call(*args)
# [[:call, [:var_ref, [:@ident, "db", [66, 10]]], :".", [:@ident, "rename_job!", [66, 13]]]]
super.tap do |(_call, (_var_ref, (_ident, name, _coords)), _dot, (_ident2, method_name, (line, column)))|
if String === name && String === method_name
@calls << [ name, method_name, line, column ]
end
end
end
def methods
@methods ? @methods : parse && @methods
end
def calls
@calls ? @calls : parse && @calls
end
def defines_method?(m)
methods.include?(m)
end
def method_calls_on(ident)
calls.select { |(an_ident, method_name, line)| an_ident == ident }
end
end
# filter a list of files based on methods they define somewhere:
filenames.select do |filename|
TestParser.from_file(filename).defines_method?('foo')
end
# compare method calls to a list of methods and make the test fail if there is a call to a non-existing method:
defined_methods = my_object.public_methods(true).map(&:to_s)
TestParser.from_file(filename).
method_calls_on('a_name_i_always_use_for_that_kind_of_object').select do |_, method_name, _, _|
!defined_methods.include?(method_name)
end.should == []
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment