1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
#!/usr/local/bin/ruby -w
$TESTING = true
$: << 'lib'
require 'test/unit'
require 'ruby2ruby'
require 'pt_testcase'
class TestRuby2Ruby < Test::Unit::TestCase
def setup
@processor = Ruby2Ruby.new
end
def test_proc_to_ruby
block = proc { puts "something" }
assert_equal %Q|proc {\n puts("something")\n}|, block.to_ruby
end
def test_lit_regexp_slash
inn = s(:lit, /blah\/blah/)
out = '/blah\/blah/'
assert_equal out, @processor.process(inn)
r = eval(out)
assert_equal(/blah\/blah/, r)
end
def util_thingy(type)
s(type,
'blah"blah',
s(:call, s(:lit, 1), :+, s(:array, s(:lit, 1))),
s(:str, 'blah"blah/blah'))
end
def test_dregx_slash
inn = util_thingy(:dregx)
out = "/blah\\\"blah#\{(1 + 1)}blah\\\"blah\\/blah/"
assert_equal out, @processor.process(inn)
r = eval(out)
assert_equal(/blah\"blah2blah\"blah\/blah/, r)
end
def test_dstr_quote
inn = util_thingy(:dstr)
out = "\"blah\\\"blah#\{(1 + 1)}blah\\\"blah/blah\""
assert_equal out, @processor.process(inn)
r = eval(out)
assert_equal "blah\"blah2blah\"blah/blah", r
end
def test_dsym_quote
inn = util_thingy(:dsym)
out = ":\"blah\\\"blah#\{(1 + 1)}blah\\\"blah/blah\""
assert_equal out, @processor.process(inn)
r = eval(out)
assert_equal :"blah\"blah2blah\"blah/blah", r
end
def test_proc_to_sexp
p = proc { 1 + 1 }
s = [:proc, nil, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]]
assert_equal s, p.to_sexp
end
def test_unbound_method_to_ruby
r = "proc { ||\n p = proc { (1 + 1) }\n s = [:proc, nil, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]]\n assert_equal(s, p.to_sexp)\n}"
m = self.class.instance_method(:test_proc_to_sexp)
assert_equal r, m.to_ruby
end
eval ParseTreeTestCase.testcases.map { |node, data|
next if node == "vcall" # HACK
"def test_#{node}
pt = #{data['ParseTree'].inspect}
rb = #{(data['Ruby2Ruby'] || data['Ruby']).inspect}
assert_not_nil pt, \"ParseTree for #{node} undefined\"
assert_not_nil rb, \"Ruby for #{node} undefined\"
assert_equal rb, @processor.process(pt)
end"
}.join("\n")
end
##
# Converts a +target+ using a +processor+ and converts +target+ name
# in the source adding +gen+ to allow easy renaming.
def morph_and_eval(processor, target, gen, n)
begin
old_name = target.name
new_name = target.name.sub(/\d*$/, gen.to_s)
ruby = processor.translate(target).sub(old_name, new_name)
eval ruby
target.constants.each do |constant|
eval "#{new_name}::#{constant} = #{old_name}::#{constant}"
end
rescue SyntaxError => e
warn "Self-Translation Generation #{n} failed:"
warn "#{e.class}: #{e.message}"
warn ""
warn ruby
warn ""
rescue => e
warn "Self-Translation Generation #{n} failed:"
warn "#{e.class}: #{e.message}"
warn ""
warn ruby
warn ""
else
begin
yield if block_given?
rescue
# probably already handled
end
end
end
####################
# impl
# old new
#
# t old 0 1
# e
# s
# t new 2 3
# Self-Translation: 1st Generation - morph Ruby2Ruby using Ruby2Ruby
morph_and_eval Ruby2Ruby, Ruby2Ruby, 2, 1 do
class TestRuby2Ruby1 < TestRuby2Ruby
def setup
@processor = Ruby2Ruby2.new
end
end
end
# Self-Translation: 2nd Generation - morph TestRuby2Ruby using Ruby2Ruby
morph_and_eval Ruby2Ruby, TestRuby2Ruby, 2, 2 do
# Self-Translation: 3rd Generation - test Ruby2Ruby2 with TestRuby2Ruby1
class TestRuby2Ruby3 < TestRuby2Ruby2
def setup
@processor = Ruby2Ruby2.new
end
end
end
# Self-Translation: 4th (and final) Generation - fully circular
morph_and_eval(Ruby2Ruby2, Ruby2Ruby2, 3, 4) do
class TestRuby2Ruby4 < TestRuby2Ruby3
def setup
@processor = Ruby2Ruby3.new
end
end
end rescue nil # for Ruby2Ruby2 at the top
|