1require 'test/unit'
2require_relative 'envutil'
3
4class TestEval < Test::Unit::TestCase
5
6  @ivar = 12
7  @@cvar = 13
8  $gvar__eval = 14
9  Const = 15
10
11  def ruby(*args)
12    args = ['-e', '$>.write($<.read)'] if args.empty?
13    ruby = EnvUtil.rubybin
14    f = IO.popen([ruby] + args, 'r+')
15    yield(f)
16  ensure
17    f.close unless !f || f.closed?
18  end
19
20  def test_eval_basic
21    assert_equal nil,   eval("nil")
22    assert_equal true,  eval("true")
23    assert_equal false, eval("false")
24    assert_equal self,  eval("self")
25    assert_equal 1,     eval("1")
26    assert_equal :sym,  eval(":sym")
27
28    assert_equal 11,    eval("11")
29    @ivar = 12
30    assert_equal 12,    eval("@ivar")
31    assert_equal 13,    eval("@@cvar")
32    assert_equal 14,    eval("$gvar__eval")
33    assert_equal 15,    eval("Const")
34
35    assert_equal 16,    eval("7 + 9")
36    assert_equal 17,    eval("17.to_i")
37    assert_equal "18",  eval(%q("18"))
38    assert_equal "19",  eval(%q("1#{9}"))
39
40    1.times {
41      assert_equal 12,  eval("@ivar")
42      assert_equal 13,  eval("@@cvar")
43      assert_equal 14,  eval("$gvar__eval")
44      assert_equal 15,  eval("Const")
45    }
46  end
47
48  def test_eval_binding_basic
49    assert_equal nil,   eval("nil", binding())
50    assert_equal true,  eval("true", binding())
51    assert_equal false, eval("false", binding())
52    assert_equal self,  eval("self", binding())
53    assert_equal 1,     eval("1", binding())
54    assert_equal :sym,  eval(":sym", binding())
55
56    assert_equal 11,    eval("11", binding())
57    @ivar = 12
58    assert_equal 12,    eval("@ivar", binding())
59    assert_equal 13,    eval("@@cvar", binding())
60    assert_equal 14,    eval("$gvar__eval", binding())
61    assert_equal 15,    eval("Const", binding())
62
63    assert_equal 16,    eval("7 + 9", binding())
64    assert_equal 17,    eval("17.to_i", binding())
65    assert_equal "18",  eval(%q("18"), binding())
66    assert_equal "19",  eval(%q("1#{9}"), binding())
67
68    1.times {
69      assert_equal 12,  eval("@ivar")
70      assert_equal 13,  eval("@@cvar")
71      assert_equal 14,  eval("$gvar__eval")
72      assert_equal 15,  eval("Const")
73    }
74  end
75
76  def test_module_eval_string_basic
77    c = self.class
78    assert_equal nil,   c.module_eval("nil")
79    assert_equal true,  c.module_eval("true")
80    assert_equal false, c.module_eval("false")
81    assert_equal c,     c.module_eval("self")
82    assert_equal :sym,  c.module_eval(":sym")
83    assert_equal 11,    c.module_eval("11")
84    @ivar = 12
85    assert_equal 12,    c.module_eval("@ivar")
86    assert_equal 13,    c.module_eval("@@cvar")
87    assert_equal 14,    c.module_eval("$gvar__eval")
88    assert_equal 15,    c.module_eval("Const")
89    assert_equal 16,    c.module_eval("7 + 9")
90    assert_equal 17,    c.module_eval("17.to_i")
91    assert_equal "18",  c.module_eval(%q("18"))
92    assert_equal "19",  c.module_eval(%q("1#{9}"))
93
94    @ivar = 12
95    1.times {
96      assert_equal 12,  c.module_eval("@ivar")
97      assert_equal 13,  c.module_eval("@@cvar")
98      assert_equal 14,  c.module_eval("$gvar__eval")
99      assert_equal 15,  c.module_eval("Const")
100    }
101  end
102
103  def test_module_eval_block_basic
104    c = self.class
105    assert_equal nil,   c.module_eval { nil }
106    assert_equal true,  c.module_eval { true }
107    assert_equal false, c.module_eval { false }
108    assert_equal c,     c.module_eval { self }
109    assert_equal :sym,  c.module_eval { :sym }
110    assert_equal 11,    c.module_eval { 11 }
111    @ivar = 12
112    assert_equal 12,    c.module_eval { @ivar }
113    assert_equal 13,    c.module_eval { @@cvar }
114    assert_equal 14,    c.module_eval { $gvar__eval }
115    assert_equal 15,    c.module_eval { Const }
116    assert_equal 16,    c.module_eval { 7 + 9 }
117    assert_equal 17,    c.module_eval { "17".to_i }
118    assert_equal "18",  c.module_eval { "18" }
119    assert_equal "19",  c.module_eval { "1#{9}" }
120
121    @ivar = 12
122    1.times {
123      assert_equal 12,  c.module_eval { @ivar }
124      assert_equal 13,  c.module_eval { @@cvar }
125      assert_equal 14,  c.module_eval { $gvar__eval }
126      assert_equal 15,  c.module_eval { Const }
127    }
128  end
129
130  def forall_TYPE
131    objects = [Object.new, [], nil, true, false, :sym] # TODO: check
132    objects.each do |obj|
133      obj.instance_variable_set :@ivar, 12
134      yield obj
135    end
136  end
137
138  def test_instance_eval_string_basic
139    forall_TYPE do |o|
140      assert_equal nil,   o.instance_eval("nil")
141      assert_equal true,  o.instance_eval("true")
142      assert_equal false, o.instance_eval("false")
143      assert_equal o,     o.instance_eval("self")
144      assert_equal 1,     o.instance_eval("1")
145      assert_equal :sym,  o.instance_eval(":sym")
146
147      assert_equal 11,    o.instance_eval("11")
148      assert_equal 12,    o.instance_eval("@ivar")
149      assert_equal 13,    o.instance_eval("@@cvar")
150      assert_equal 14,    o.instance_eval("$gvar__eval")
151      assert_equal 15,    o.instance_eval("Const")
152      assert_equal 16,    o.instance_eval("7 + 9")
153      assert_equal 17,    o.instance_eval("17.to_i")
154      assert_equal "18",  o.instance_eval(%q("18"))
155      assert_equal "19",  o.instance_eval(%q("1#{9}"))
156
157      1.times {
158        assert_equal 12,  o.instance_eval("@ivar")
159        assert_equal 13,  o.instance_eval("@@cvar")
160        assert_equal 14,  o.instance_eval("$gvar__eval")
161        assert_equal 15,  o.instance_eval("Const")
162      }
163    end
164  end
165
166  def test_instance_eval_block_basic
167    forall_TYPE do |o|
168      assert_equal nil,   o.instance_eval { nil }
169      assert_equal true,  o.instance_eval { true }
170      assert_equal false, o.instance_eval { false }
171      assert_equal o,     o.instance_eval { self }
172      assert_equal 1,     o.instance_eval { 1 }
173      assert_equal :sym,  o.instance_eval { :sym }
174
175      assert_equal 11,    o.instance_eval { 11 }
176      assert_equal 12,    o.instance_eval { @ivar }
177      assert_equal 13,    o.instance_eval { @@cvar }
178      assert_equal 14,    o.instance_eval { $gvar__eval }
179      assert_equal 15,    o.instance_eval { Const }
180      assert_equal 16,    o.instance_eval { 7 + 9 }
181      assert_equal 17,    o.instance_eval { 17.to_i }
182      assert_equal "18",  o.instance_eval { "18" }
183      assert_equal "19",  o.instance_eval { "1#{9}" }
184
185      1.times {
186        assert_equal 12,  o.instance_eval { @ivar }
187        assert_equal 13,  o.instance_eval { @@cvar }
188        assert_equal 14,  o.instance_eval { $gvar__eval }
189        assert_equal 15,  o.instance_eval { Const }
190      }
191    end
192  end
193
194  def test_instance_eval_cvar
195    [Object.new, [], 7, :sym, true, false, nil].each do |obj|
196      assert_equal(13, obj.instance_eval("@@cvar"))
197      assert_equal(13, obj.instance_eval{@@cvar})
198      # assert_raise(NameError){obj.instance_eval("@@cvar")}
199      # assert_raise(NameError){obj.instance_eval{@@cvar}}
200    end
201  end
202
203  def test_instance_eval_method
204    bug2788 = '[ruby-core:28324]'
205    [Object.new, [], nil, true, false].each do |o|
206      assert_nothing_raised(TypeError, "#{bug2788} (#{o.inspect})") do
207        o.instance_eval {
208          def defd_using_instance_eval() :ok end
209        }
210      end
211      assert_equal(:ok, o.defd_using_instance_eval)
212      class << o
213        remove_method :defd_using_instance_eval
214      end
215    end
216  end
217
218  def test_instance_eval_on_argf_singleton_class
219    bug8188 = '[ruby-core:53839] [Bug #8188]'
220    assert_warning('', bug8188) do
221      ARGF.singleton_class.instance_eval{}
222    end
223  end
224
225  class Foo
226    Bar = 2
227  end
228
229  def test_instance_eval_const
230    bar = nil
231    assert_nothing_raised(NameError) do
232      bar = Foo.new.instance_eval("Bar")
233    end
234    assert_equal(2, bar)
235  end
236
237  #
238  # From ruby/test/ruby/test_eval.rb
239  #
240
241  def test_ev
242    local1 = "local1"
243    lambda {
244      local2 = "local2"
245      return binding
246    }.call
247  end
248
249  def test_eval_orig
250    assert_nil(eval(""))
251    bad=false
252    eval 'while false; bad = true; print "foo\n" end'
253    assert(!bad)
254
255    assert(eval('TRUE'))
256    assert(eval('true'))
257    assert(!eval('NIL'))
258    assert(!eval('nil'))
259    assert(!eval('FALSE'))
260    assert(!eval('false'))
261
262    $foo = 'assert(true)'
263    begin
264      eval $foo
265    rescue
266      assert(false)
267    end
268
269    assert_equal('assert(true)', eval("$foo"))
270    assert_equal(true, eval("true"))
271    i = 5
272    assert(eval("i == 5"))
273    assert_equal(5, eval("i"))
274    assert(eval("defined? i"))
275
276    x = test_ev
277    assert_equal("local1", eval("local1", x)) # normal local var
278    assert_equal("local2", eval("local2", x)) # nested local var
279    bad = true
280    begin
281      p eval("local1")
282    rescue NameError		# must raise error
283      bad = false
284    end
285    assert(!bad)
286
287    # !! use class_eval to avoid nested definition
288    x = self.class.class_eval %q(
289      module EvTest
290	EVTEST1 = 25
291	evtest2 = 125
292	binding
293      end
294    )
295    assert_equal(25, eval("EVTEST1", x))	# constant in module
296    assert_equal(125, eval("evtest2", x))	# local var in module
297    bad = true
298    begin
299      eval("EVTEST1")
300    rescue NameError		# must raise error
301      bad = false
302    end
303    assert(!bad)
304
305    if false
306      # Ruby 2.0 doesn't see Proc as Binding
307      x = proc{}
308      eval "i4 = 1", x
309      assert_equal(1, eval("i4", x))
310      x = proc{proc{}}.call
311      eval "i4 = 22", x
312      assert_equal(22, eval("i4", x))
313      t = []
314      x = proc{proc{}}.call
315      eval "(0..9).each{|i5| t[i5] = proc{i5*2}}", x
316      assert_equal(8, t[4].call)
317    end
318
319    x = binding
320    eval "i = 1", x
321    assert_equal(1, eval("i", x))
322    x = proc{binding}.call
323    eval "i = 22", x
324    assert_equal(22, eval("i", x))
325    t = []
326    x = proc{binding}.call
327    eval "(0..9).each{|i5| t[i5] = proc{i5*2}}", x
328    assert_equal(8, t[4].call)
329    x = proc{binding}.call
330    eval "for i6 in 1..1; j6=i6; end", x
331    assert(eval("defined? i6", x))
332    assert(eval("defined? j6", x))
333
334    proc {
335      p = binding
336      eval "foo11 = 1", p
337      foo22 = 5
338      proc{foo11=22}.call
339      proc{foo22=55}.call
340      # assert_equal(eval("foo11"), eval("foo11", p))
341      # assert_equal(1, eval("foo11"))
342      assert_equal(eval("foo22"), eval("foo22", p))
343      assert_equal(55, eval("foo22"))
344    }.call
345
346    if false
347      # Ruby 2.0 doesn't see Proc as Binding
348      p1 = proc{i7 = 0; proc{i7}}.call
349      assert_equal(0, p1.call)
350      eval "i7=5", p1
351      assert_equal(5, p1.call)
352      assert(!defined?(i7))
353    end
354
355    if false
356      # Ruby 2.0 doesn't see Proc as Binding
357      p1 = proc{i7 = 0; proc{i7}}.call
358      i7 = nil
359      assert_equal(0, p1.call)
360      eval "i7=1", p1
361      assert_equal(1, p1.call)
362      eval "i7=5", p1
363      assert_equal(5, p1.call)
364      assert_nil(i7)
365    end
366  end
367
368  def test_nil_instance_eval_cvar
369    def nil.test_binding
370      binding
371    end
372    bb = eval("nil.instance_eval \"binding\"", nil.test_binding)
373    assert_raise(NameError, "[ruby-dev:24103]") { eval("@@a", bb) }
374    class << nil
375      remove_method :test_binding
376    end
377  end
378
379  def test_fixnum_instance_eval_cvar
380    assert_raise(NameError, "[ruby-dev:24213]") { 1.instance_eval "@@a" }
381  end
382
383  def test_cvar_scope_with_instance_eval
384    # TODO: check
385    Fixnum.class_eval "@@test_cvar_scope_with_instance_eval = 1" # depends on [ruby-dev:24229]
386    @@test_cvar_scope_with_instance_eval = 4
387    assert_equal(4, 1.instance_eval("@@test_cvar_scope_with_instance_eval"), "[ruby-dev:24223]")
388    Fixnum.__send__(:remove_class_variable, :@@test_cvar_scope_with_instance_eval)
389  end
390
391  def test_eval_and_define_method
392    assert_nothing_raised("[ruby-dev:24228]") {
393      def temporally_method_for_test_eval_and_define_method(&block)
394        lambda {
395          class << Object.new; self end.send(:define_method, :zzz, &block)
396        }
397      end
398      v = eval("temporally_method_for_test_eval_and_define_method {}")
399      {}[0] = {}
400      v.call
401    }
402  end
403
404  def test_define_method_block
405    cc = Class.new do
406      define_method(:foo) {|&block|
407        block.call if block
408      }
409    end
410
411    c = cc.new
412    x = "ng"
413    c.foo() {x = "ok"}
414    assert_equal("ok", x)
415  end
416
417  def test_define_method_toplevel
418    feature6609 = '[ruby-core:45715]'
419    main = eval("self", TOPLEVEL_BINDING)
420    assert_nothing_raised(NoMethodError, feature6609) do
421      main.instance_eval do
422        define_method("feature6609_block") {feature6609}
423      end
424    end
425    assert_equal(feature6609, feature6609_block)
426
427    assert_nothing_raised(NoMethodError, feature6609) do
428      main.instance_eval do
429        define_method("feature6609_method", Object.instance_method(:feature6609_block))
430      end
431    end
432    assert_equal(feature6609, feature6609_method)
433  end
434
435  def test_eval_using_integer_as_binding
436    assert_raise(TypeError) { eval("", 1) }
437  end
438
439  def test_eval_raise
440    assert_raise(RuntimeError) { eval("raise ''") }
441  end
442
443  def test_eval_using_untainted_binding_under_safe4
444    assert_raise(SecurityError) do
445      Thread.new do
446        b = binding
447        $SAFE = 4
448        eval("", b)
449      end.join
450    end
451  end
452
453  def test_eval_with_toplevel_binding # [ruby-dev:37142]
454    ruby("-e", "x = 0; eval('p x', TOPLEVEL_BINDING)") do |f|
455      f.close_write
456      assert_equal("0", f.read.chomp)
457    end
458  end
459
460  def test_eval_ascii_incompatible
461    assert_raise(ArgumentError) {eval("__ENCODING__".encode("utf-16be"))}
462    assert_raise(ArgumentError) {eval("__ENCODING__".encode("utf-16le"))}
463    assert_raise(ArgumentError) {eval("__ENCODING__".encode("utf-32be"))}
464    assert_raise(ArgumentError) {eval("__ENCODING__".encode("utf-32le"))}
465  end
466
467  def test_instance_eval_method_proc
468    bug3860 = Class.new do
469      def initialize(a);
470        @a=a
471      end
472      def get(*args)
473        @a
474      end
475    end
476    foo = bug3860.new 1
477    foo_pr = foo.method(:get).to_proc
478    result = foo.instance_eval(&foo_pr)
479    assert_equal(1, result, 'Bug #3786, Bug #3860, [ruby-core:32501]')
480  end
481
482  def test_file_encoding
483    fname = "\u{3042}".encode("euc-jp")
484    assert_equal(fname, eval("__FILE__", nil, fname, 1))
485  end
486end
487