module TestProf::RSpecStamp::Parser
def parse(code)
def parse(code) sexp = Ripper.sexp(code) return unless sexp # sexp has the following format: # [:program, # [ # [ # :command, # [:@ident, "it", [1, 0]], # [:args_add_block, [ ... ]] # ] # ] # ] # # or # # [:program, # [ # [ # :vcall, # [:@ident, "it", [1, 0]] # ] # ] # ] res = Result.new fcall = sexp[1][0][1] args_block = sexp[1][0][2] if fcall.first == :fcall fcall = fcall[1] elsif fcall.first == :var_ref res.fname = [parse_const(fcall), sexp[1][0][3][1]].join(".") args_block = sexp[1][0][4] end res.fname ||= fcall[1] return res if args_block.nil? args_block = args_block[1] if args_block.first == :arg_paren args = args_block[1] if args.first.first == :string_literal res.desc = parse_literal(args.shift) elsif args.first.first == :var_ref || args.first.first == :const_path_ref res.desc_const = parse_const(args.shift) end parse_arg(res, args.shift) until args.empty? res end
def parse_arg(res, arg)
def parse_arg(res, arg) if arg.first == :symbol_literal res.add_tag parse_literal(arg) elsif arg.first == :bare_assoc_hash parse_hash(res, arg[1]) end end
def parse_const(expr)
[:@const, "Guest", [1, 23]]],
[:@const, "User", [1, 17]]],
[:const_path_ref, [:const_path_ref, [:var_ref,
or
[:var_ref, [:@const, "User", [1, 9]]]
Expr of the form:
def parse_const(expr) if expr.first == :var_ref expr[1][1] elsif expr.first == :@const expr[1] elsif expr.first == :const_path_ref expr[1..-1].map(&method(:parse_const)).join("::") end end
def parse_hash(res, hash_arg)
def parse_hash(res, hash_arg) hash_arg.each do |(_, label, val)| res.add_htag label[1][0..-2].to_sym, parse_value(val) end end
def parse_literal(expr)
Expr of the form:
def parse_literal(expr) val = expr[1][1][1] val = val.to_sym if expr[0] == :symbol_literal || expr[0] == :assoc_new val end
def parse_value(expr)
string - [:string_literal, [:string_content, [...]]]
bool - [:var_ref, [:@kw, "true", [1, 24]]]
Expr of the form:
def parse_value(expr) case expr.first when :var_ref expr[1][1] == "true" when :@int expr[1].to_i when :@float expr[1].to_f else parse_literal(expr) end end