test/pt_testcase.rb in ParseTree-1.6.0 vs test/pt_testcase.rb in ParseTree-1.6.1

- old
+ new

@@ -34,39 +34,46 @@ super @processor = nil Unique.reset end + def self.add_test name, data, klass = self.name[4..-1] + name = name.to_s + klass = klass.to_s + if testcases.has_key? name then + if testcases[name].has_key? klass then + warn "testcase #{klass}##{name} already has data" + else + testcases[name][klass] = data + end + else + warn "testcase #{name} does not exist" + end + end + + def self.unsupported_tests *tests + tests.flatten.each do |name| + add_test name, :unsupported + end + end + @@testcase_order = %w(Ruby ParseTree) @@testcases = { "alias" => { "Ruby" => "class X\n alias :y :x\nend", "ParseTree" => [:class, :X, nil, [:scope, [:alias, [:lit, :y], [:lit, :x]]]], - "Ruby2Ruby" => "class X\n alias_method :y, :x\n \nend", # FIX dbl \n + "Ruby2Ruby" => "class X\n alias_method :y, :x\nend", # FIX dbl \n }, "and" => { "Ruby" => "(a and b)", "ParseTree" => [:and, [:vcall, :a], [:vcall, :b]], }, - "args" => { - "Ruby" => "def x(a, b = 42, \*c, &d)\n p(a, b, c, d)\nend", - "ParseTree" => [:defn, :x, - [:scope, - [:block, - [:args, :a, :b, "*c".intern, # s->e - [:block, [:lasgn, :b, [:lit, 42]]]], - [:block_arg, :d], - [:fcall, :p, - [:array, [:lvar, :a], [:lvar, :b], - [:lvar, :c], [:lvar, :d]]]]]] - }, - "argscat" => { "Ruby" => "a = b, c, *d", "ParseTree" => [:lasgn, :a, [:svalue, [:argscat, @@ -184,38 +191,50 @@ "cdecl" => { "Ruby" => "X = 42", "ParseTree" => [:cdecl, :X, [:lit, 42]], }, - "class" => { - "Ruby" => "class X < Array\n def blah\n puts(\"hello\")\n end\n \nend", + "class_plain" => { + "Ruby" => "class X\n puts((1 + 1))\n def blah\n puts(\"hello\")\n end\nend", "ParseTree" => [:class, :X, - [:const, :Array], + nil, [:scope, - [:defn, - :blah, - [:scope, - [:block, - [:args], - [:fcall, :puts, [:array, [:str, "hello"]]]]]]]], + [:block, + [:fcall, :puts, [:array, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]]], + [:defn, + :blah, + [:scope, + [:block, + [:args], + [:fcall, :puts, [:array, [:str, "hello"]]]]]]]]], }, - "class_obj" => { - "Ruby" => "class X\n def blah\n puts(\"hello\")\n end\n \nend", + "class_super_object" => { + "Ruby" => "class X < Object\nend", "ParseTree" => [:class, :X, - nil, - [:scope, - [:defn, - :blah, - [:scope, - [:block, - [:args], - [:fcall, :puts, [:array, [:str, "hello"]]]]]]]], + [:const, :Object], + [:scope]], }, + "class_super_array" => { + "Ruby" => "class X < Array\nend", + "ParseTree" => [:class, + :X, + [:const, :Array], + [:scope]], + }, + + "class_super_expr" => { + "Ruby" => "class X < expr\nend", + "ParseTree" => [:class, + :X, + [:vcall, :expr], + [:scope]], + }, + "colon2" => { "Ruby" => "X::Y", "ParseTree" => [:colon2, [:const, :X], :Y], }, @@ -254,12 +273,18 @@ [:return, [:lit, 2]], [:if, [:call, [:lit, 42], :<, [:array, [:lit, 0]]], [:return, [:lit, 3]], [:return, [:lit, 4]]]], + "Ruby2Ruby" => "if (42 == 0) then\n return 2\nelse\n if (42 < 0) then\n return 3\n else\n return 4\n end\nend", }, + "conditional5" => { + "Ruby" => "unless true then\n if false then\n return\n end\nend", + "ParseTree" => [:if, [:true], nil, [:if, [:false], [:return], nil]], + }, + "const" => { "Ruby" => "X", "ParseTree" => [:const, :X], }, @@ -274,11 +299,11 @@ [:scope, [:block, [:args], [:cvasgn, :@@blah, [:lit, 1]]]]] }, "cvdecl" => { - "Ruby" => "class X\n @@blah = 1\n \nend", + "Ruby" => "class X\n @@blah = 1\nend", "ParseTree" => [:class, :X, nil, [:scope, [:cvdecl, :@@blah, [:lit, 1]]]], }, "dasgn" => { @@ -296,28 +321,50 @@ "defined" => { "Ruby" => "defined? $x", "ParseTree" => [:defined, [:gvar, :$x]], }, + "defn_args" => { + "Ruby" => "def x(a, b = 42, \*c, &d)\n p(a, b, c, d)\nend", + "ParseTree" => [:defn, :x, + [:scope, + [:block, + [:args, :a, :b, "*c".intern, # s->e + [:block, [:lasgn, :b, [:lit, 42]]]], + [:block_arg, :d], + [:fcall, :p, + [:array, [:lvar, :a], [:lvar, :b], + [:lvar, :c], [:lvar, :d]]]]]] + }, + "defn_empty" => { "Ruby" => "def empty\n # do nothing\nend", "ParseTree" => [:defn, :empty, [:scope, [:block, [:args], [:nil]]]], }, "defn_is_something" => { "Ruby" => "def something?\n # do nothing\nend", "ParseTree" => [:defn, :something?, [:scope, [:block, [:args], [:nil]]]], }, +# TODO: +# add_test("defn_optargs", +# s(:defn, :x, +# s(:args, :a, "*args".intern), +# s(:scope, +# s(:block, +# s(:call, nil, :p, +# s(:arglist, s(:lvar, :a), s(:lvar, :args))))))) + "defn_or" => { - "Ruby" => "def |\n # do nothing\nend", - "ParseTree" => [:defn, :|, [:scope, [:block, [:args], [:nil]]]], + "Ruby" => "def |(o)\n # do nothing\nend", + "ParseTree" => [:defn, :|, [:scope, [:block, [:args, :o], [:nil]]]], }, "defn_zarray" => { # tests memory allocation for returns - "Ruby" => "def empty\n a = []\n return a\nend", - "ParseTree" => [:defn, :empty, + "Ruby" => "def zarray\n a = []\n return a\nend", + "ParseTree" => [:defn, :zarray, [:scope, [:block, [:args], [:lasgn, :a, [:zarray]], [:return, [:lvar, :a]]]]], }, @@ -389,27 +436,33 @@ [:lasgn, :t, [:lit, 5]], [:dxstr, 'touch ', [:lvar, :t]]], }, "ensure" => { - "Ruby" => "def bbegin\n begin\n (1 + 1)\n rescue SyntaxError => e1\n 2\n rescue Exception => e2\n 3\n else\n 4\n ensure\n 5\n end\nend", - "ParseTree" => [:defn, :bbegin, - [:scope, - [:block, - [:args], - [:begin, - [:ensure, - [:rescue, - [:call, [:lit, 1], :+, [:array, [:lit, 1]]], - [:resbody, - [:array, [:const, :SyntaxError]], - [:block, [:lasgn, :e1, [:gvar, :$!]], [:lit, 2]], - [:resbody, - [:array, [:const, :Exception]], - [:block, [:lasgn, :e2, [:gvar, :$!]], [:lit, 3]]]], - [:lit, 4]], - [:lit, 5]]]]]], + "Ruby" => "begin + (1 + 1) +rescue SyntaxError => e1 + 2 +rescue Exception => e2 + 3 +else + 4 +ensure + 5 +end", + "ParseTree" => [:begin, + [:ensure, + [:rescue, + [:call, [:lit, 1], :+, [:array, [:lit, 1]]], + [:resbody, + [:array, [:const, :SyntaxError]], + [:block, [:lasgn, :e1, [:gvar, :$!]], [:lit, 2]], + [:resbody, + [:array, [:const, :Exception]], + [:block, [:lasgn, :e2, [:gvar, :$!]], [:lit, 3]]]], + [:lit, 4]], + [:lit, 5]]], }, "false" => { "Ruby" => "false", "ParseTree" => [:false], @@ -650,11 +703,11 @@ "Ruby" => "\"blah\" =~ /x/", "ParseTree" => [:match3, [:lit, /x/], [:str, "blah"]], }, "module" => { - "Ruby" => "module X\n def y\n # do nothing\n end\n \nend", + "Ruby" => "module X\n def y\n # do nothing\n end\nend", "ParseTree" => [:module, :X, [:scope, [:defn, :y, [:scope, [:block, [:args], [:nil]]]]]], }, @@ -737,20 +790,25 @@ "Ruby" => "loop do\n if false then\n redo\n end\nend", "ParseTree" => [:iter, [:fcall, :loop], nil, [:if, [:false], [:redo], nil]], }, -# "rescue" => { # TODO: expression style rescues -# "Ruby" => "blah rescue nil", -# "ParseTree" => [:rescue, [:vcall, :blah], [:resbody, nil, [:nil]]], -# }, + "rescue" => { + "Ruby" => "blah rescue nil", + "ParseTree" => [:rescue, [:vcall, :blah], [:resbody, nil, [:nil]]], + }, - "rescue_block" => { + "rescue_block_nada" => { "Ruby" => "begin\n blah\nrescue\n # do nothing\nend\n", "ParseTree" => [:begin, [:rescue, [:vcall, :blah], [:resbody, nil]]] }, + "rescue_block_body" => { + "Ruby" => "begin\n blah\nrescue\n nil\nend\n", + "ParseTree" => [:begin, [:rescue, [:vcall, :blah], [:resbody, nil, [:nil]]]], + }, + "rescue_exceptions" => { "Ruby" => "begin\n blah\nrescue RuntimeError => r\n # do nothing\nend\n", "ParseTree" => [:begin, [:rescue, [:vcall, :blah], @@ -772,10 +830,11 @@ "splat" => { "Ruby" => "a(*b)", "ParseTree" => [:fcall, :a, [:splat, [:vcall, :b]]], }, + # TODO: all supers need to pass args "super" => { "Ruby" => "def x\n super(4)\nend", "ParseTree" => [:defn, :x, [:scope, [:block, @@ -821,39 +880,49 @@ [:undef, [:lit, :y]], [:undef, [:lit, :z]]], "Ruby2Ruby" => "undef :x\nundef :y\nundef :z\n", }, - "until" => { + "until_pre" => { "Ruby" => "until false do\n (1 + 1)\nend", "ParseTree" => [:until, [:false], [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true], }, + "until_post" => { + "Ruby" => "begin\n (1 + 1)\nend until false", + "ParseTree" => [:until, [:false], + [:call, [:lit, 1], :+, [:array, [:lit, 1]]], false], + }, + "valias" => { "Ruby" => "alias $y $x", "ParseTree" => [:valias, :$y, :$x], }, "vcall" => { "Ruby" => "method", "ParseTree" => [:vcall, :method], }, - "whiles" => { - "Ruby" => "def whiles\n while false do\n puts(\"false\")\n end\n begin\n puts(\"true\")\n end while false\nend", - "ParseTree" => [:defn, - :whiles, - [:scope, - [:block, - [:args], - [:while, [:false], - [:fcall, :puts, [:array, [:str, "false"]]], true], - [:while, [:false], - [:fcall, :puts, [:array, [:str, "true"]]], false]]]], + "while_pre" => { + "Ruby" => "while false do\n (1 + 1)\nend", + "ParseTree" => [:while, [:false], + [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true], }, + "while_pre_nil" => { + "Ruby" => "while false do\nend", + "ParseTree" => [:while, [:false], nil, true], + }, + + "while_post" => { + "Ruby" => "begin\n (1 + 1)\nend while false", + "ParseTree" => [:while, [:false], + [:call, [:lit, 1], :+, [:array, [:lit, 1]]], false], + }, + "xstr" => { "Ruby" => "`touch 5`", "ParseTree" => [:xstr, 'touch 5'], }, @@ -910,50 +979,56 @@ # end # flunk # end - def self.previous(key) - idx = @@testcase_order.index(key)-1 + def self.previous(key, extra=0) + idx = @@testcase_order.index(key)-1-extra case key when "RubyToRubyC" then idx -= 1 end @@testcase_order[idx] end - # lets us used unprocessed :self outside of tests, called when subclassed - def self.clone_same - @@testcases.each do |node, data| - data.each do |key, val| - if val == :same then - prev_key = self.previous(key) - data[key] = data[prev_key].deep_clone - end - end - end - end +# # lets us used unprocessed :self outside of tests, called when subclassed +# def self.clone_same +# @@testcases.each do |node, data| +# data.each do |key, val| +# if val == :same then +# prev_key = self.previous(key) +# data[key] = data[prev_key].deep_clone +# end +# end +# end +# end def self.inherited(c) - self.clone_same - output_name = c.name.to_s.sub(/^Test/, '') raise "Unknown class #{c}" unless @@testcase_order.include? output_name input_name = self.previous(output_name) @@testcases.each do |node, data| - next if data[input_name] == :skip + next if [:skip, :unsupported].include? data[input_name] next if data[output_name] == :skip c.send(:define_method, "test_#{node}".intern) do flunk "Processor is nil" if processor.nil? assert data.has_key?(input_name), "Unknown input data" + unless data.has_key?(output_name) then + $stderr.puts "add_test(#{node.inspect}, :same)" + end assert data.has_key?(output_name), "Unknown expected data" input = data[input_name].deep_clone - expected = data[output_name].deep_clone + expected = if data[output_name] == :same then + input + else + data[output_name] + end.deep_clone + case expected when :unsupported then assert_raises(UnsupportedNodeError) do processor.process(input) end @@ -962,10 +1037,11 @@ extra_input = [] _, expected, extra_expected = *expected if Array === expected and expected.first == :defx _, input, extra_input = *input if Array === input and input.first == :defx - assert_equal expected, processor.process(input) + debug = input.deep_clone + assert_equal expected, processor.process(input), "failed on input: #{debug.inspect}" extra_input.each do |input| processor.process(input) end extra = processor.extra_methods rescue [] assert_equal extra_expected, extra end end