1require 'test/unit'
2require_relative 'envutil'
3
4class TestDefined < Test::Unit::TestCase
5  class Foo
6    def foo
7      p :foo
8    end
9    protected :foo
10    def bar(f)
11      yield(defined?(self.foo))
12      yield(defined?(f.foo))
13    end
14    def baz(f)
15    end
16    attr_accessor :attr
17    def attrasgn_test
18      yield(defined?(self.attr = 1))
19    end
20  end
21
22  def defined_test
23    return !defined?(yield)
24  end
25
26  def test_defined
27    $x = nil
28
29    assert(defined?($x))		# global variable
30    assert_equal('global-variable', defined?($x))# returns description
31
32    assert_nil(defined?(foo))		# undefined
33    foo=5
34    assert(defined?(foo))		# local variable
35
36    assert(defined?(Array))		# constant
37    assert(defined?(::Array))		# toplevel constant
38    assert(defined?(File::Constants))	# nested constant
39    assert(defined?(Object.new))	# method
40    assert(defined?(Object::new))	# method
41    assert(!defined?(Object.print))	# private method
42    assert(defined?(1 == 2))		# operator expression
43
44    f = Foo.new
45    assert_nil(defined?(f.foo))         # protected method
46    f.bar(f) { |v| assert(v) }
47    assert_nil(defined?(f.quux))        # undefined method
48    assert_nil(defined?(f.baz(x)))      # undefined argument
49    x = 0
50    assert(defined?(f.baz(x)))
51    assert_nil(defined?(f.quux(x)))
52    assert(defined?(print(x)))
53    assert_nil(defined?(quux(x)))
54    assert(defined?(f.attr = 1))
55    f.attrasgn_test { |v| assert(v) }
56
57    assert(defined_test)		# not iterator
58    assert(!defined_test{})	        # called as iterator
59
60    /a/ =~ ''
61    assert_equal nil, defined?($&)
62    assert_equal nil, defined?($`)
63    assert_equal nil, defined?($')
64    assert_equal nil, defined?($+)
65    assert_equal nil, defined?($1)
66    assert_equal nil, defined?($2)
67    /a/ =~ 'a'
68    assert_equal 'global-variable', defined?($&)
69    assert_equal 'global-variable', defined?($`)
70    assert_equal 'global-variable', defined?($') # '
71    assert_equal nil, defined?($+)
72    assert_equal nil, defined?($1)
73    assert_equal nil, defined?($2)
74    /(a)/ =~ 'a'
75    assert_equal 'global-variable', defined?($&)
76    assert_equal 'global-variable', defined?($`)
77    assert_equal 'global-variable', defined?($') # '
78    assert_equal 'global-variable', defined?($+)
79    assert_equal 'global-variable', defined?($1)
80    assert_equal nil, defined?($2)
81    /(a)b/ =~ 'ab'
82    assert_equal 'global-variable', defined?($&)
83    assert_equal 'global-variable', defined?($`)
84    assert_equal 'global-variable', defined?($') # '
85    assert_equal 'global-variable', defined?($+)
86    assert_equal 'global-variable', defined?($1)
87    assert_equal nil, defined?($2)
88
89    assert_equal("nil", defined?(nil))
90    assert_equal("true", defined?(true))
91    assert_equal("false", defined?(false))
92    assert_equal("expression", defined?(1))
93  end
94
95  def test_defined_impl_specific
96    feature7035 = '[ruby-core:47558]' # not spec
97    assert_predicate(defined?(Foo), :frozen?, feature7035)
98    assert_same(defined?(Foo), defined?(Array), feature7035)
99  end
100
101  class TestAutoloadedSuperclass
102    autoload :A, "a"
103  end
104
105  class TestAutoloadedSubclass < TestAutoloadedSuperclass
106    def a?
107      defined?(A)
108    end
109  end
110
111  def test_autoloaded_subclass
112    bug = "[ruby-core:35509]"
113
114    x = TestAutoloadedSuperclass.new
115    class << x
116      def a?; defined?(A); end
117    end
118    assert_equal("constant", x.a?, bug)
119
120    assert_equal("constant", TestAutoloadedSubclass.new.a?, bug)
121  end
122
123  class TestAutoloadedNoload
124    autoload :A, "a"
125    def a?
126      defined?(A)
127    end
128    def b?
129      defined?(A::B)
130    end
131  end
132
133  def test_autoloaded_noload
134    loaded = $".dup
135    $".clear
136    loadpath = $:.dup
137    $:.clear
138    x = TestAutoloadedNoload.new
139    assert_equal("constant", x.a?)
140    assert_nil(x.b?)
141    assert_equal([], $")
142  ensure
143    $".replace(loaded)
144    $:.replace(loadpath)
145  end
146
147  def test_exception
148    bug5786 = '[ruby-dev:45021]'
149    assert_nil(defined?(raise("[Bug#5786]")::A), bug5786)
150  end
151
152  def test_define_method
153    bug6644 = '[ruby-core:45831]'
154    a = Class.new do
155      def self.def_f!;
156        singleton_class.send(:define_method, :f) { defined? super }
157      end
158    end
159    aa = Class.new(a)
160    a.def_f!
161    assert_nil(a.f)
162    assert_nil(aa.f)
163    aa.def_f!
164    assert_equal("super", aa.f, bug6644)
165    assert_nil(a.f, bug6644)
166  end
167
168  def test_super_in_included_method
169    c0 = Class.new do
170      def m
171      end
172    end
173    m1 = Module.new do
174      def m
175        defined?(super)
176      end
177    end
178    c = Class.new(c0) do include m1
179      def m
180        super
181      end
182    end
183    assert_equal("super", c.new.m)
184  end
185
186  def test_super_in_block
187    bug8367 = '[ruby-core:54769] [Bug #8367]'
188    c = Class.new do
189      def x; end
190    end
191
192    m = Module.new do
193      def b; yield; end
194      def x; b {return defined?(super)}; end
195    end
196
197    o = c.new
198    o.extend(m)
199    assert_equal("super", o.x)
200  end
201
202  def test_super_toplevel
203    assert_separately([], "assert_nil(defined?(super))")
204  end
205end
206