1require 'test/unit'
2require 'pp'
3require_relative 'envutil'
4
5$m0 = Module.nesting
6
7class TestModule < Test::Unit::TestCase
8  def _wrap_assertion
9    yield
10  end
11
12  def assert_method_defined?(klass, mid, message="")
13    message = build_message(message, "#{klass}\##{mid} expected to be defined.")
14    _wrap_assertion do
15      klass.method_defined?(mid) or
16        raise Test::Unit::AssertionFailedError, message, caller(3)
17    end
18  end
19
20  def assert_method_not_defined?(klass, mid, message="")
21    message = build_message(message, "#{klass}\##{mid} expected to not be defined.")
22    _wrap_assertion do
23      klass.method_defined?(mid) and
24        raise Test::Unit::AssertionFailedError, message, caller(3)
25    end
26  end
27
28  def setup
29    @verbose = $VERBOSE
30    $VERBOSE = nil
31  end
32
33  def teardown
34    $VERBOSE = @verbose
35  end
36
37  def test_LT_0
38    assert_equal true, String < Object
39    assert_equal false, Object < String
40    assert_nil String < Array
41    assert_equal true, Array < Enumerable
42    assert_equal false, Enumerable < Array
43    assert_nil Proc < Comparable
44    assert_nil Comparable < Proc
45  end
46
47  def test_GT_0
48    assert_equal false, String > Object
49    assert_equal true, Object > String
50    assert_nil String > Array
51    assert_equal false, Array > Enumerable
52    assert_equal true, Enumerable > Array
53    assert_nil Comparable > Proc
54    assert_nil Proc > Comparable
55  end
56
57  def test_CMP_0
58    assert_equal(-1, (String <=> Object))
59    assert_equal 1, (Object <=> String)
60    assert_nil(Array <=> String)
61  end
62
63  ExpectedException = NoMethodError
64
65  # Support stuff
66
67  module Mixin
68    MIXIN = 1
69    def mixin
70    end
71  end
72
73  module User
74    USER = 2
75    include Mixin
76    def user
77    end
78  end
79
80  module Other
81    def other
82    end
83  end
84
85  class AClass
86    def AClass.cm1
87      "cm1"
88    end
89    def AClass.cm2
90      cm1 + "cm2" + cm3
91    end
92    def AClass.cm3
93      "cm3"
94    end
95
96    private_class_method :cm1, "cm3"
97
98    def aClass
99      :aClass
100    end
101
102    def aClass1
103      :aClass1
104    end
105
106    def aClass2
107      :aClass2
108    end
109
110    private :aClass1
111    protected :aClass2
112  end
113
114  class BClass < AClass
115    def bClass1
116      :bClass1
117    end
118
119    private
120
121    def bClass2
122      :bClass2
123    end
124
125    protected
126    def bClass3
127      :bClass3
128    end
129  end
130
131  class CClass < BClass
132    def self.cClass
133    end
134  end
135
136  MyClass = AClass.clone
137  class MyClass
138    public_class_method :cm1
139  end
140
141  # -----------------------------------------------------------
142
143  def test_CMP # '<=>'
144    assert_equal( 0, Mixin <=> Mixin)
145    assert_equal(-1, User <=> Mixin)
146    assert_equal( 1, Mixin <=> User)
147
148    assert_equal( 0, Object <=> Object)
149    assert_equal(-1, String <=> Object)
150    assert_equal( 1, Object <=> String)
151  end
152
153  def test_GE # '>='
154    assert(Mixin >= User)
155    assert(Mixin >= Mixin)
156    assert(!(User >= Mixin))
157
158    assert(Object >= String)
159    assert(String >= String)
160    assert(!(String >= Object))
161  end
162
163  def test_GT # '>'
164    assert(Mixin   > User)
165    assert(!(Mixin > Mixin))
166    assert(!(User  > Mixin))
167
168    assert(Object > String)
169    assert(!(String > String))
170    assert(!(String > Object))
171  end
172
173  def test_LE # '<='
174    assert(User <= Mixin)
175    assert(Mixin <= Mixin)
176    assert(!(Mixin <= User))
177
178    assert(String <= Object)
179    assert(String <= String)
180    assert(!(Object <= String))
181  end
182
183  def test_LT # '<'
184    assert(User < Mixin)
185    assert(!(Mixin < Mixin))
186    assert(!(Mixin < User))
187
188    assert(String < Object)
189    assert(!(String < String))
190    assert(!(Object < String))
191  end
192
193  def test_VERY_EQUAL # '==='
194    assert(Object === self)
195    assert(Test::Unit::TestCase === self)
196    assert(TestModule === self)
197    assert(!(String === self))
198  end
199
200  def test_ancestors
201    assert_equal([User, Mixin],      User.ancestors)
202    assert_equal([Mixin],            Mixin.ancestors)
203
204    ancestors = Object.ancestors
205    mixins = ancestors - [Object, Kernel, BasicObject]
206    mixins << JSON::Ext::Generator::GeneratorMethods::String if defined?(JSON::Ext::Generator::GeneratorMethods::String)
207    assert_equal([Object, Kernel, BasicObject], ancestors - mixins)
208    assert_equal([String, Comparable, Object, Kernel, BasicObject], String.ancestors - mixins)
209  end
210
211  CLASS_EVAL = 2
212  @@class_eval = 'b'
213
214  def test_class_eval
215    Other.class_eval("CLASS_EVAL = 1")
216    assert_equal(1, Other::CLASS_EVAL)
217    assert(Other.constants.include?(:CLASS_EVAL))
218    assert_equal(2, Other.class_eval { CLASS_EVAL })
219
220    Other.class_eval("@@class_eval = 'a'")
221    assert_equal('a', Other.class_variable_get(:@@class_eval))
222    assert_equal('b', Other.class_eval { @@class_eval })
223
224    Other.class_eval do
225      module_function
226
227      def class_eval_test
228        "foo"
229      end
230    end
231    assert_equal("foo", Other.class_eval_test)
232
233    assert_equal([Other], Other.class_eval { |*args| args })
234  end
235
236  def test_const_defined?
237    assert(Math.const_defined?(:PI))
238    assert(Math.const_defined?("PI"))
239    assert(!Math.const_defined?(:IP))
240    assert(!Math.const_defined?("IP"))
241  end
242
243  def test_bad_constants
244    [
245      "#<Class:0x7b8b718b>",
246      ":Object",
247      "",
248      ":",
249      ["String::", "[Bug #7573]"],
250    ].each do |name, msg|
251      e = assert_raises(NameError, "#{msg}#{': ' if msg}wrong constant name #{name.dump}") {
252        Object.const_get name
253      }
254      assert_equal("wrong constant name %s" % name, e.message)
255    end
256  end
257
258  def test_leading_colons
259    assert_equal Object, AClass.const_get('::Object')
260  end
261
262  def test_const_get
263    assert_equal(Math::PI, Math.const_get("PI"))
264    assert_equal(Math::PI, Math.const_get(:PI))
265  end
266
267  def test_nested_get
268    assert_equal Other, Object.const_get([self.class, Other].join('::'))
269    assert_equal User::USER, self.class.const_get([User, 'USER'].join('::'))
270  end
271
272  def test_nested_get_symbol
273    const = [self.class, Other].join('::').to_sym
274    assert_raise(NameError) {Object.const_get(const)}
275
276    const = [User, 'USER'].join('::').to_sym
277    assert_raise(NameError) {self.class.const_get(const)}
278  end
279
280  def test_nested_get_const_missing
281    classes = []
282    klass = Class.new {
283      define_singleton_method(:const_missing) { |name|
284	classes << name
285	klass
286      }
287    }
288    klass.const_get("Foo::Bar::Baz")
289    assert_equal [:Foo, :Bar, :Baz], classes
290  end
291
292  def test_nested_bad_class
293    assert_raises(TypeError) do
294      self.class.const_get([User, 'USER', 'Foo'].join('::'))
295    end
296  end
297
298  def test_const_set
299    assert(!Other.const_defined?(:KOALA))
300    Other.const_set(:KOALA, 99)
301    assert(Other.const_defined?(:KOALA))
302    assert_equal(99, Other::KOALA)
303    Other.const_set("WOMBAT", "Hi")
304    assert_equal("Hi", Other::WOMBAT)
305  end
306
307  def test_constants
308    assert_equal([:MIXIN], Mixin.constants)
309    assert_equal([:MIXIN, :USER], User.constants.sort)
310  end
311
312  def test_self_initialize_copy
313    bug9535 = '[ruby-dev:47989] [Bug #9535]'
314    m = Module.new do
315      def foo
316        :ok
317      end
318      initialize_copy(self)
319    end
320    assert_equal(:ok, Object.new.extend(m).foo, bug9535)
321  end
322
323  def test_dup
324    bug6454 = '[ruby-core:45132]'
325
326    a = Module.new
327    Other.const_set :BUG6454, a
328
329    original = Other::BUG6454.inspect
330
331    b = a.dup
332    Other.const_set :BUG6454_dup, b
333
334    assert_equal "TestModule::Other::BUG6454_dup", b.inspect, bug6454
335  end
336
337  def test_dup_anonymous
338    bug6454 = '[ruby-core:45132]'
339
340    a = Module.new
341    original = a.inspect
342
343    b = a.dup
344
345    refute_equal original, b.inspect, bug6454
346  end
347
348  def test_included_modules
349    assert_equal([], Mixin.included_modules)
350    assert_equal([Mixin], User.included_modules)
351
352    mixins = Object.included_modules - [Kernel]
353    mixins << JSON::Ext::Generator::GeneratorMethods::String if defined?(JSON::Ext::Generator::GeneratorMethods::String)
354    assert_equal([Kernel], Object.included_modules - mixins)
355    assert_equal([Comparable, Kernel], String.included_modules - mixins)
356  end
357
358  def test_instance_methods
359    assert_equal([:user], User.instance_methods(false))
360    assert_equal([:user, :mixin].sort, User.instance_methods(true).sort)
361    assert_equal([:mixin], Mixin.instance_methods)
362    assert_equal([:mixin], Mixin.instance_methods(true))
363    assert_equal([:cClass], (class << CClass; self; end).instance_methods(false))
364    assert_equal([], (class << BClass; self; end).instance_methods(false))
365    assert_equal([:cm2], (class << AClass; self; end).instance_methods(false))
366    # Ruby 1.8 feature change:
367    # #instance_methods includes protected methods.
368    #assert_equal([:aClass], AClass.instance_methods(false))
369    assert_equal([:aClass, :aClass2], AClass.instance_methods(false).sort)
370    assert_equal([:aClass, :aClass2],
371        (AClass.instance_methods(true) - Object.instance_methods(true)).sort)
372  end
373
374  def test_method_defined?
375    assert_method_not_defined?(User, :wombat)
376    assert_method_defined?(User, :user)
377    assert_method_defined?(User, :mixin)
378    assert_method_not_defined?(User, :wombat)
379    assert_method_defined?(User, :user)
380    assert_method_defined?(User, :mixin)
381  end
382
383  def module_exec_aux
384    Proc.new do
385      def dynamically_added_method_3; end
386    end
387  end
388  def module_exec_aux_2(&block)
389    User.module_exec(&block)
390  end
391
392  def test_module_exec
393    User.module_exec do
394      def dynamically_added_method_1; end
395    end
396    assert_method_defined?(User, :dynamically_added_method_1)
397
398    block = Proc.new do
399      def dynamically_added_method_2; end
400    end
401    User.module_exec(&block)
402    assert_method_defined?(User, :dynamically_added_method_2)
403
404    User.module_exec(&module_exec_aux)
405    assert_method_defined?(User, :dynamically_added_method_3)
406
407    module_exec_aux_2 do
408      def dynamically_added_method_4; end
409    end
410    assert_method_defined?(User, :dynamically_added_method_4)
411  end
412
413  def test_module_eval
414    User.module_eval("MODULE_EVAL = 1")
415    assert_equal(1, User::MODULE_EVAL)
416    assert(User.constants.include?(:MODULE_EVAL))
417    User.instance_eval("remove_const(:MODULE_EVAL)")
418    assert(!User.constants.include?(:MODULE_EVAL))
419  end
420
421  def test_name
422    assert_equal("Fixnum", Fixnum.name)
423    assert_equal("TestModule::Mixin",  Mixin.name)
424    assert_equal("TestModule::User",   User.name)
425  end
426
427  def test_classpath
428    m = Module.new
429    n = Module.new
430    m.const_set(:N, n)
431    assert_nil(m.name)
432    assert_nil(n.name)
433    assert_equal([:N], m.constants)
434    m.module_eval("module O end")
435    assert_equal([:N, :O], m.constants)
436    m.module_eval("class C; end")
437    assert_equal([:N, :O, :C], m.constants)
438    assert_nil(m::N.name)
439    assert_match(/\A#<Module:.*>::O\z/, m::O.name)
440    assert_match(/\A#<Module:.*>::C\z/, m::C.name)
441    self.class.const_set(:M, m)
442    prefix = self.class.name + "::M::"
443    assert_equal(prefix+"N", m.const_get(:N).name)
444    assert_equal(prefix+"O", m.const_get(:O).name)
445    assert_equal(prefix+"C", m.const_get(:C).name)
446  end
447
448  def test_private_class_method
449    assert_raise(ExpectedException) { AClass.cm1 }
450    assert_raise(ExpectedException) { AClass.cm3 }
451    assert_equal("cm1cm2cm3", AClass.cm2)
452  end
453
454  def test_private_instance_methods
455    assert_equal([:aClass1], AClass.private_instance_methods(false))
456    assert_equal([:bClass2], BClass.private_instance_methods(false))
457    assert_equal([:aClass1, :bClass2],
458        (BClass.private_instance_methods(true) -
459         Object.private_instance_methods(true)).sort)
460  end
461
462  def test_protected_instance_methods
463    assert_equal([:aClass2], AClass.protected_instance_methods)
464    assert_equal([:bClass3], BClass.protected_instance_methods(false))
465    assert_equal([:bClass3, :aClass2].sort,
466                 (BClass.protected_instance_methods(true) -
467                  Object.protected_instance_methods(true)).sort)
468  end
469
470  def test_public_class_method
471    assert_equal("cm1",       MyClass.cm1)
472    assert_equal("cm1cm2cm3", MyClass.cm2)
473    assert_raise(ExpectedException) { eval "MyClass.cm3" }
474  end
475
476  def test_public_instance_methods
477    assert_equal([:aClass],  AClass.public_instance_methods(false))
478    assert_equal([:bClass1], BClass.public_instance_methods(false))
479  end
480
481  def test_s_constants
482    c1 = Module.constants
483    Object.module_eval "WALTER = 99"
484    c2 = Module.constants
485    assert_equal([:WALTER], c2 - c1)
486
487    assert_equal([], Module.constants(true))
488    assert_equal([], Module.constants(false))
489
490    src = <<-INPUT
491      ary = Module.constants
492      module M
493        WALTER = 99
494      end
495      class Module
496        include M
497      end
498      p Module.constants - ary, Module.constants(true), Module.constants(false)
499    INPUT
500    assert_in_out_err([], src, %w([:M] [:WALTER] []), [])
501
502    klass = Class.new do
503      const_set(:X, 123)
504    end
505    assert_equal(false, klass.class_eval { Module.constants }.include?(:X))
506  end
507
508  module M1
509    $m1 = Module.nesting
510    module M2
511      $m2 = Module.nesting
512    end
513  end
514
515  def test_s_nesting
516    assert_equal([],                               $m0)
517    assert_equal([TestModule::M1, TestModule],     $m1)
518    assert_equal([TestModule::M1::M2,
519                  TestModule::M1, TestModule],     $m2)
520  end
521
522  def test_s_new
523    m = Module.new
524    assert_instance_of(Module, m)
525  end
526
527  def test_freeze
528    m = Module.new
529    m.freeze
530    assert_raise(RuntimeError) do
531      m.module_eval do
532        def foo; end
533      end
534    end
535  end
536
537  def test_attr_obsoleted_flag
538    c = Class.new
539    c.class_eval do
540      def initialize
541        @foo = :foo
542        @bar = :bar
543      end
544      attr :foo, true
545      attr :bar, false
546    end
547    o = c.new
548    assert_equal(true, o.respond_to?(:foo))
549    assert_equal(true, o.respond_to?(:foo=))
550    assert_equal(true, o.respond_to?(:bar))
551    assert_equal(false, o.respond_to?(:bar=))
552  end
553
554  def test_const_get_evaled
555    c1 = Class.new
556    c2 = Class.new(c1)
557
558    eval("c1::Foo = :foo")
559    assert_equal(:foo, c1::Foo)
560    assert_equal(:foo, c2::Foo)
561    assert_equal(:foo, c2.const_get(:Foo))
562    assert_raise(NameError) { c2.const_get(:Foo, false) }
563
564    eval("c1::Foo = :foo")
565    assert_raise(NameError) { c1::Bar }
566    assert_raise(NameError) { c2::Bar }
567    assert_raise(NameError) { c2.const_get(:Bar) }
568    assert_raise(NameError) { c2.const_get(:Bar, false) }
569    assert_raise(NameError) { c2.const_get("Bar", false) }
570    assert_raise(NameError) { c2.const_get("BaR11", false) }
571    assert_raise(NameError) { Object.const_get("BaR11", false) }
572
573    c1.instance_eval do
574      def const_missing(x)
575        x
576      end
577    end
578
579    assert_equal(:Bar, c1::Bar)
580    assert_equal(:Bar, c2::Bar)
581    assert_equal(:Bar, c2.const_get(:Bar))
582    assert_equal(:Bar, c2.const_get(:Bar, false))
583    assert_equal(:Bar, c2.const_get("Bar"))
584    assert_equal(:Bar, c2.const_get("Bar", false))
585
586    v = c2.const_get("Bar11", false)
587    assert_equal("Bar11".to_sym, v)
588
589    assert_raise(NameError) { c1.const_get(:foo) }
590  end
591
592  def test_const_set_invalid_name
593    c1 = Class.new
594    assert_raise(NameError) { c1.const_set(:foo, :foo) }
595  end
596
597  def test_const_get_invalid_name
598    c1 = Class.new
599    assert_raise(NameError) { c1.const_get(:foo) }
600    bug5084 = '[ruby-dev:44200]'
601    assert_raise(TypeError, bug5084) { c1.const_get(1) }
602    bug7574 = '[ruby-dev:46749]'
603    e = assert_raise(NameError) { Object.const_get("String\0") }
604    assert_equal("wrong constant name \"String\\u0000\"", e.message, bug7574)
605  end
606
607  def test_const_defined_invalid_name
608    c1 = Class.new
609    assert_raise(NameError) { c1.const_defined?(:foo) }
610    bug5084 = '[ruby-dev:44200]'
611    assert_raise(TypeError, bug5084) { c1.const_defined?(1) }
612    bug7574 = '[ruby-dev:46749]'
613    e = assert_raise(NameError) { Object.const_defined?("String\0") }
614    assert_equal("wrong constant name \"String\\u0000\"", e.message, bug7574)
615  end
616
617  def test_const_get_no_inherited
618    bug3422 = '[ruby-core:30719]'
619    assert_in_out_err([], <<-INPUT, %w[1 NameError A], [], bug3422)
620    BasicObject::A = 1
621    puts [true, false].map {|inh|
622      begin
623        Object.const_get(:A, inh)
624      rescue NameError => e
625        [e.class, e.name]
626      end
627    }
628    INPUT
629  end
630
631  def test_const_get_inherited
632    bug3423 = '[ruby-core:30720]'
633    assert_in_out_err([], <<-INPUT, %w[NameError A NameError A], [], bug3423)
634    module Foo; A = 1; end
635    class Object; include Foo; end
636    class Bar; include Foo; end
637
638    puts [Object, Bar].map {|klass|
639      begin
640        klass.const_get(:A, false)
641      rescue NameError => e
642        [e.class, e.name]
643      end
644    }
645    INPUT
646  end
647
648  def test_const_in_module
649    bug3423 = '[ruby-core:37698]'
650    assert_in_out_err([], <<-INPUT, %w[ok], [], bug3423)
651    module LangModuleSpecInObject
652      module LangModuleTop
653      end
654    end
655    include LangModuleSpecInObject
656    module LangModuleTop
657    end
658    puts "ok" if LangModuleSpecInObject::LangModuleTop == LangModuleTop
659    INPUT
660
661    bug5264 = '[ruby-core:39227]'
662    assert_in_out_err([], <<-'INPUT', [], [], bug5264)
663    class A
664      class X; end
665    end
666    class B < A
667      module X; end
668    end
669    INPUT
670  end
671
672  def test_class_variable_get
673    c = Class.new
674    c.class_eval('@@foo = :foo')
675    assert_equal(:foo, c.class_variable_get(:@@foo))
676    assert_raise(NameError) { c.class_variable_get(:@@bar) } # c.f. instance_variable_get
677    assert_raise(NameError) { c.class_variable_get(:'@@') }
678    assert_raise(NameError) { c.class_variable_get('@@') }
679    assert_raise(NameError) { c.class_variable_get(:foo) }
680  end
681
682  def test_class_variable_set
683    c = Class.new
684    c.class_variable_set(:@@foo, :foo)
685    assert_equal(:foo, c.class_eval('@@foo'))
686    assert_raise(NameError) { c.class_variable_set(:'@@', 1) }
687    assert_raise(NameError) { c.class_variable_set('@@', 1) }
688    assert_raise(NameError) { c.class_variable_set(:foo, 1) }
689  end
690
691  def test_class_variable_defined
692    c = Class.new
693    c.class_eval('@@foo = :foo')
694    assert_equal(true, c.class_variable_defined?(:@@foo))
695    assert_equal(false, c.class_variable_defined?(:@@bar))
696    assert_raise(NameError) { c.class_variable_defined?(:'@@') }
697    assert_raise(NameError) { c.class_variable_defined?('@@') }
698    assert_raise(NameError) { c.class_variable_defined?(:foo) }
699  end
700
701  def test_remove_class_variable
702    c = Class.new
703    c.class_eval('@@foo = :foo')
704    c.class_eval { remove_class_variable(:@@foo) }
705    assert_equal(false, c.class_variable_defined?(:@@foo))
706  end
707
708  def test_export_method
709    m = Module.new
710    assert_raise(NameError) do
711      m.instance_eval { public(:foo) }
712    end
713  end
714
715  def test_attr
716    assert_in_out_err([], <<-INPUT, %w(:ok nil), /warning: private attribute\?$/)
717      $VERBOSE = true
718      c = Class.new
719      c.instance_eval do
720        private
721        attr_reader :foo
722      end
723      o = c.new
724      o.foo rescue p(:ok)
725      p(o.instance_eval { foo })
726    INPUT
727
728    c = Class.new
729    assert_raise(NameError) do
730      c.instance_eval { attr_reader :"." }
731    end
732  end
733
734  def test_undef
735    assert_raise(SecurityError) do
736      Thread.new do
737        $SAFE = 4
738        Class.instance_eval { undef_method(:foo) }
739      end.join
740    end
741
742    c = Class.new
743    assert_raise(NameError) do
744      c.instance_eval { undef_method(:foo) }
745    end
746
747    m = Module.new
748    assert_raise(NameError) do
749      m.instance_eval { undef_method(:foo) }
750    end
751
752    o = Object.new
753    assert_raise(NameError) do
754      class << o; self; end.instance_eval { undef_method(:foo) }
755    end
756
757    %w(object_id __send__ initialize).each do |n|
758      assert_in_out_err([], <<-INPUT, [], %r"warning: undefining `#{n}' may cause serious problems$")
759        $VERBOSE = false
760        Class.new.instance_eval { undef_method(:#{n}) }
761      INPUT
762    end
763  end
764
765  def test_alias
766    m = Module.new
767    assert_raise(NameError) do
768      m.class_eval { alias foo bar }
769    end
770
771    assert_in_out_err([], <<-INPUT, %w(2), /discarding old foo$/)
772      $VERBOSE = true
773      c = Class.new
774      c.class_eval do
775        def foo; 1; end
776        def bar; 2; end
777      end
778      c.class_eval { alias foo bar }
779      p c.new.foo
780    INPUT
781  end
782
783  def test_mod_constants
784    m = Module.new
785    m.const_set(:Foo, :foo)
786    assert_equal([:Foo], m.constants(true))
787    assert_equal([:Foo], m.constants(false))
788    m.instance_eval { remove_const(:Foo) }
789  end
790
791  class Bug9413
792    class << self
793      Foo = :foo
794    end
795  end
796
797  def test_singleton_constants
798    bug9413 = '[ruby-core:59763] [Bug #9413]'
799    c = Bug9413.singleton_class
800    assert_include(c.constants(true), :Foo, bug9413)
801    assert_include(c.constants(false), :Foo, bug9413)
802  end
803
804  def test_frozen_class
805    m = Module.new
806    m.freeze
807    assert_raise(RuntimeError) do
808      m.instance_eval { undef_method(:foo) }
809    end
810
811    c = Class.new
812    c.freeze
813    assert_raise(RuntimeError) do
814      c.instance_eval { undef_method(:foo) }
815    end
816
817    o = Object.new
818    c = class << o; self; end
819    c.freeze
820    assert_raise(RuntimeError) do
821      c.instance_eval { undef_method(:foo) }
822    end
823  end
824
825  def test_method_defined
826    c = Class.new
827    c.class_eval do
828      def foo; end
829      def bar; end
830      def baz; end
831      public :foo
832      protected :bar
833      private :baz
834    end
835
836    assert_equal(true, c.public_method_defined?(:foo))
837    assert_equal(false, c.public_method_defined?(:bar))
838    assert_equal(false, c.public_method_defined?(:baz))
839
840    assert_equal(false, c.protected_method_defined?(:foo))
841    assert_equal(true, c.protected_method_defined?(:bar))
842    assert_equal(false, c.protected_method_defined?(:baz))
843
844    assert_equal(false, c.private_method_defined?(:foo))
845    assert_equal(false, c.private_method_defined?(:bar))
846    assert_equal(true, c.private_method_defined?(:baz))
847  end
848
849  def test_change_visibility_under_safe4
850    c = Class.new
851    c.class_eval do
852      def foo; end
853    end
854    assert_raise(SecurityError) do
855      Thread.new do
856        $SAFE = 4
857        c.class_eval { private :foo }
858      end.join
859    end
860  end
861
862  def test_top_public_private
863    assert_in_out_err([], <<-INPUT, %w([:foo] [:bar]), [])
864      private
865      def foo; :foo; end
866      public
867      def bar; :bar; end
868      p self.private_methods.grep(/^foo$|^bar$/)
869      p self.methods.grep(/^foo$|^bar$/)
870    INPUT
871  end
872
873  def test_append_features
874    t = nil
875    m = Module.new
876    m.module_eval do
877      def foo; :foo; end
878    end
879    class << m; self; end.class_eval do
880      define_method(:append_features) do |mod|
881        t = mod
882        super(mod)
883      end
884    end
885
886    m2 = Module.new
887    m2.module_eval { include(m) }
888    assert_equal(m2, t)
889
890    o = Object.new
891    o.extend(m2)
892    assert_equal(true, o.respond_to?(:foo))
893  end
894
895  def test_append_features_raise
896    m = Module.new
897    m.module_eval do
898      def foo; :foo; end
899    end
900    class << m; self; end.class_eval do
901      define_method(:append_features) {|mod| raise }
902    end
903
904    m2 = Module.new
905    assert_raise(RuntimeError) do
906      m2.module_eval { include(m) }
907    end
908
909    o = Object.new
910    o.extend(m2)
911    assert_equal(false, o.respond_to?(:foo))
912  end
913
914  def test_append_features_type_error
915    assert_raise(TypeError) do
916      Module.new.instance_eval { append_features(1) }
917    end
918  end
919
920  def test_included
921    m = Module.new
922    m.module_eval do
923      def foo; :foo; end
924    end
925    class << m; self; end.class_eval do
926      define_method(:included) {|mod| raise }
927    end
928
929    m2 = Module.new
930    assert_raise(RuntimeError) do
931      m2.module_eval { include(m) }
932    end
933
934    o = Object.new
935    o.extend(m2)
936    assert_equal(true, o.respond_to?(:foo))
937  end
938
939  def test_cyclic_include
940    m1 = Module.new
941    m2 = Module.new
942    m1.instance_eval { include(m2) }
943    assert_raise(ArgumentError) do
944      m2.instance_eval { include(m1) }
945    end
946  end
947
948  def test_include_p
949    m = Module.new
950    c1 = Class.new
951    c1.instance_eval { include(m) }
952    c2 = Class.new(c1)
953    assert_equal(true, c1.include?(m))
954    assert_equal(true, c2.include?(m))
955    assert_equal(false, m.include?(m))
956  end
957
958  def test_include_under_safe4
959    m = Module.new
960    c1 = Class.new
961    assert_raise(SecurityError) do
962      lambda {
963        $SAFE = 4
964        c1.instance_eval { include(m) }
965      }.call
966    end
967    assert_nothing_raised do
968      lambda {
969        $SAFE = 4
970        c2 = Class.new
971        c2.instance_eval { include(m) }
972      }.call
973    end
974  end
975
976  def test_send
977    a = AClass.new
978    assert_equal(:aClass, a.__send__(:aClass))
979    assert_equal(:aClass1, a.__send__(:aClass1))
980    assert_equal(:aClass2, a.__send__(:aClass2))
981    b = BClass.new
982    assert_equal(:aClass, b.__send__(:aClass))
983    assert_equal(:aClass1, b.__send__(:aClass1))
984    assert_equal(:aClass2, b.__send__(:aClass2))
985    assert_equal(:bClass1, b.__send__(:bClass1))
986    assert_equal(:bClass2, b.__send__(:bClass2))
987    assert_equal(:bClass3, b.__send__(:bClass3))
988  end
989
990
991  def test_nonascii_name
992    c = eval("class ::C\u{df}; self; end")
993    assert_equal("C\u{df}", c.name, '[ruby-core:24600]')
994    c = eval("class C\u{df}; self; end")
995    assert_equal("TestModule::C\u{df}", c.name, '[ruby-core:24600]')
996  end
997
998  def test_method_added
999    memo = []
1000    mod = Module.new do
1001      mod = self
1002      (class << self ; self ; end).class_eval do
1003        define_method :method_added do |sym|
1004          memo << sym
1005          memo << mod.instance_methods(false)
1006          memo << (mod.instance_method(sym) rescue nil)
1007        end
1008      end
1009      def f
1010      end
1011      alias g f
1012      attr_reader :a
1013      attr_writer :a
1014    end
1015    assert_equal :f, memo.shift
1016    assert_equal [:f], memo.shift, '[ruby-core:25536]'
1017    assert_equal mod.instance_method(:f), memo.shift
1018    assert_equal :g, memo.shift
1019    assert_equal [:f, :g], memo.shift
1020    assert_equal mod.instance_method(:f), memo.shift
1021    assert_equal :a, memo.shift
1022    assert_equal [:f, :g, :a], memo.shift
1023    assert_equal mod.instance_method(:a), memo.shift
1024    assert_equal :a=, memo.shift
1025    assert_equal [:f, :g, :a, :a=], memo.shift
1026    assert_equal mod.instance_method(:a=), memo.shift
1027  end
1028
1029  def test_method_undefined
1030    added = []
1031    undefed = []
1032    removed = []
1033    mod = Module.new do
1034      mod = self
1035      def f
1036      end
1037      (class << self ; self ; end).class_eval do
1038        define_method :method_added do |sym|
1039          added << sym
1040        end
1041        define_method :method_undefined do |sym|
1042          undefed << sym
1043        end
1044        define_method :method_removed do |sym|
1045          removed << sym
1046        end
1047      end
1048    end
1049    assert_method_defined?(mod, :f)
1050    mod.module_eval do
1051      undef :f
1052    end
1053    assert_equal [], added
1054    assert_equal [:f], undefed
1055    assert_equal [], removed
1056  end
1057
1058  def test_method_removed
1059    added = []
1060    undefed = []
1061    removed = []
1062    mod = Module.new do
1063      mod = self
1064      def f
1065      end
1066      (class << self ; self ; end).class_eval do
1067        define_method :method_added do |sym|
1068          added << sym
1069        end
1070        define_method :method_undefined do |sym|
1071          undefed << sym
1072        end
1073        define_method :method_removed do |sym|
1074          removed << sym
1075        end
1076      end
1077    end
1078    assert_method_defined?(mod, :f)
1079    mod.module_eval do
1080      remove_method :f
1081    end
1082    assert_equal [], added
1083    assert_equal [], undefed
1084    assert_equal [:f], removed
1085  end
1086
1087  def test_method_redefinition
1088    feature2155 = '[ruby-dev:39400]'
1089
1090    line = __LINE__+4
1091    stderr = EnvUtil.verbose_warning do
1092      Module.new do
1093        def foo; end
1094        def foo; end
1095      end
1096    end
1097    assert_match(/:#{line}: warning: method redefined; discarding old foo/, stderr)
1098    assert_match(/:#{line-1}: warning: previous definition of foo/, stderr, feature2155)
1099
1100    stderr = EnvUtil.verbose_warning do
1101      Module.new do
1102        def foo; end
1103        alias bar foo
1104        def foo; end
1105      end
1106    end
1107    assert_equal("", stderr)
1108
1109    stderr = EnvUtil.verbose_warning do
1110      Module.new do
1111        def foo; end
1112        alias bar foo
1113        alias bar foo
1114      end
1115    end
1116    assert_equal("", stderr)
1117
1118    line = __LINE__+4
1119    stderr = EnvUtil.verbose_warning do
1120      Module.new do
1121        define_method(:foo) do end
1122        def foo; end
1123      end
1124    end
1125    assert_match(/:#{line}: warning: method redefined; discarding old foo/, stderr)
1126    assert_match(/:#{line-1}: warning: previous definition of foo/, stderr, feature2155)
1127
1128    stderr = EnvUtil.verbose_warning do
1129      Module.new do
1130        define_method(:foo) do end
1131        alias bar foo
1132        alias bar foo
1133      end
1134    end
1135    assert_equal("", stderr)
1136
1137    stderr = EnvUtil.verbose_warning do
1138      Module.new do
1139        module_function
1140        def foo; end
1141        module_function :foo
1142      end
1143    end
1144    assert_equal("", stderr, '[ruby-dev:39397]')
1145
1146    stderr = EnvUtil.verbose_warning do
1147      Module.new do
1148        def foo; end
1149        undef foo
1150      end
1151    end
1152    assert_equal("", stderr)
1153  end
1154
1155  def test_protected_singleton_method
1156    klass = Class.new
1157    x = klass.new
1158    class << x
1159      protected
1160
1161      def foo
1162      end
1163    end
1164    assert_raise(NoMethodError) do
1165      x.foo
1166    end
1167    klass.send(:define_method, :bar) do
1168      x.foo
1169    end
1170    assert_nothing_raised do
1171      x.bar
1172    end
1173    y = klass.new
1174    assert_raise(NoMethodError) do
1175      y.bar
1176    end
1177  end
1178
1179  def test_uninitialized_toplevel_constant
1180    bug3123 = '[ruby-dev:40951]'
1181    e = assert_raise(NameError) {eval("Bug3123", TOPLEVEL_BINDING)}
1182    assert_not_match(/Object::/, e.message, bug3123)
1183  end
1184
1185  def test_attr_inherited_visibility
1186    bug3406 = '[ruby-core:30638]'
1187    c = Class.new do
1188      class << self
1189        private
1190        def attr_accessor(*); super; end
1191      end
1192      attr_accessor :x
1193    end.new
1194    assert_nothing_raised(bug3406) {c.x = 1}
1195    assert_equal(1, c.x, bug3406)
1196  end
1197
1198  def test_attr_writer_with_no_arguments
1199    bug8540 = "[ruby-core:55543]"
1200    c = Class.new do
1201      attr_writer :foo
1202    end
1203    assert_raise(ArgumentError) { c.new.send :foo= }
1204  end
1205
1206  def test_private_constant
1207    c = Class.new
1208    c.const_set(:FOO, "foo")
1209    assert_equal("foo", c::FOO)
1210    c.private_constant(:FOO)
1211    assert_raise(NameError) { c::FOO }
1212    assert_equal("foo", c.class_eval("FOO"))
1213    assert_equal("foo", c.const_get("FOO"))
1214    $VERBOSE, verbose = nil, $VERBOSE
1215    c.const_set(:FOO, "foo")
1216    $VERBOSE = verbose
1217    assert_raise(NameError) { c::FOO }
1218  end
1219
1220  def test_private_constant2
1221    c = Class.new
1222    c.const_set(:FOO, "foo")
1223    c.const_set(:BAR, "bar")
1224    assert_equal("foo", c::FOO)
1225    assert_equal("bar", c::BAR)
1226    c.private_constant(:FOO, :BAR)
1227    assert_raise(NameError) { c::FOO }
1228    assert_raise(NameError) { c::BAR }
1229    assert_equal("foo", c.class_eval("FOO"))
1230    assert_equal("bar", c.class_eval("BAR"))
1231  end
1232
1233  def test_private_constant_with_no_args
1234    assert_in_out_err([], <<-RUBY, [], ["-:3: warning: private_constant with no argument is just ignored"])
1235      $-w = true
1236      class X
1237        private_constant
1238      end
1239    RUBY
1240  end
1241
1242  class PrivateClass
1243  end
1244  private_constant :PrivateClass
1245
1246  def test_define_module_under_private_constant
1247    assert_raise(NameError) do
1248      eval %q{class TestModule::PrivateClass; end}
1249    end
1250    assert_raise(NameError) do
1251      eval %q{module TestModule::PrivateClass::TestModule; end}
1252    end
1253    eval %q{class PrivateClass; end}
1254    eval %q{module PrivateClass::TestModule; end}
1255    assert_instance_of(Module, PrivateClass::TestModule)
1256    PrivateClass.class_eval { remove_const(:TestModule) }
1257  end
1258
1259  def test_public_constant
1260    c = Class.new
1261    c.const_set(:FOO, "foo")
1262    assert_equal("foo", c::FOO)
1263    c.private_constant(:FOO)
1264    assert_raise(NameError) { c::FOO }
1265    assert_equal("foo", c.class_eval("FOO"))
1266    c.public_constant(:FOO)
1267    assert_equal("foo", c::FOO)
1268  end
1269
1270  def test_constants_with_private_constant
1271    assert(!(::TestModule).constants.include?(:PrivateClass))
1272  end
1273
1274  def test_toplevel_private_constant
1275    src = <<-INPUT
1276      class Object
1277        private_constant :Object
1278      end
1279      p Object
1280      begin
1281        p ::Object
1282      rescue
1283        p :ok
1284      end
1285    INPUT
1286    assert_in_out_err([], src, %w(Object :ok), [])
1287  end
1288
1289  def test_private_constants_clear_inlinecache
1290    bug5702 = '[ruby-dev:44929]'
1291    src = <<-INPUT
1292    class A
1293      C = :Const
1294      def self.get_C
1295        A::C
1296      end
1297      # fill cache
1298      A.get_C
1299      private_constant :C, :D rescue nil
1300      begin
1301        A.get_C
1302      rescue NameError
1303        puts "A.get_C"
1304      end
1305    end
1306    INPUT
1307    assert_in_out_err([], src, %w(A.get_C), [], bug5702)
1308  end
1309
1310  def test_constant_lookup_in_method_defined_by_class_eval
1311    src = <<-INPUT
1312      class A
1313        B = 42
1314      end
1315
1316      A.class_eval do
1317        def self.f
1318          B
1319        end
1320
1321        def f
1322          B
1323        end
1324      end
1325
1326      begin
1327        A.f
1328      rescue NameError
1329        puts "A.f"
1330      end
1331      begin
1332        A.new.f
1333      rescue NameError
1334        puts "A.new.f"
1335      end
1336    INPUT
1337    assert_in_out_err([], src, %w(A.f A.new.f), [])
1338  end
1339
1340  def test_constant_lookup_in_toplevel_class_eval
1341    src = <<-INPUT
1342      module X
1343        A = 123
1344      end
1345      begin
1346        X.class_eval { A }
1347      rescue NameError => e
1348        puts e
1349      end
1350    INPUT
1351    assert_in_out_err([], src, ["uninitialized constant A"], [])
1352  end
1353
1354  def test_constant_lookup_in_module_in_class_eval
1355    src = <<-INPUT
1356      class A
1357        B = 42
1358      end
1359
1360      A.class_eval do
1361        module C
1362          begin
1363            B
1364          rescue NameError
1365            puts "NameError"
1366          end
1367        end
1368      end
1369    INPUT
1370    assert_in_out_err([], src, ["NameError"], [])
1371  end
1372
1373  module M0
1374    def m1; [:M0] end
1375  end
1376  module M1
1377    def m1; [:M1, *super] end
1378  end
1379  module M2
1380    def m1; [:M2, *super] end
1381  end
1382  M3 = Module.new do
1383    def m1; [:M3, *super] end
1384  end
1385  module M4
1386    def m1; [:M4, *super] end
1387  end
1388  class C
1389    def m1; end
1390  end
1391  class C0 < C
1392    include M0
1393    prepend M1
1394    def m1; [:C0, *super] end
1395  end
1396  class C1 < C0
1397    prepend M2, M3
1398    include M4
1399    def m1; [:C1, *super] end
1400  end
1401
1402  def test_prepend
1403    obj = C0.new
1404    expected = [:M1,:C0,:M0]
1405    assert_equal(expected, obj.m1)
1406    obj = C1.new
1407    expected = [:M2,:M3,:C1,:M4,:M1,:C0,:M0]
1408    assert_equal(expected, obj.m1)
1409  end
1410
1411  def test_prepend_inheritance
1412    bug6654 = '[ruby-core:45914]'
1413    a = labeled_module("a")
1414    b = labeled_module("b") {include a}
1415    c = labeled_class("c") {prepend b}
1416    assert_operator(c, :<, b, bug6654)
1417    assert_operator(c, :<, a, bug6654)
1418    bug8357 = '[ruby-core:54736] [Bug #8357]'
1419    b = labeled_module("b") {prepend a}
1420    c = labeled_class("c") {include b}
1421    assert_operator(c, :<, b, bug8357)
1422    assert_operator(c, :<, a, bug8357)
1423    bug8357 = '[ruby-core:54742] [Bug #8357]'
1424    assert_kind_of(b, c.new, bug8357)
1425  end
1426
1427  def test_prepend_instance_methods
1428    bug6655 = '[ruby-core:45915]'
1429    assert_equal(Object.instance_methods, Class.new {prepend Module.new}.instance_methods, bug6655)
1430  end
1431
1432  def test_prepend_singleton_methods
1433    o = Object.new
1434    o.singleton_class.class_eval {prepend Module.new}
1435    assert_equal([], o.singleton_methods)
1436  end
1437
1438  def test_prepend_remove_method
1439    c = Class.new do
1440      prepend Module.new {def foo; end}
1441    end
1442    assert_raise(NameError) do
1443      c.class_eval do
1444        remove_method(:foo)
1445      end
1446    end
1447    c.class_eval do
1448      def foo; end
1449    end
1450    removed = nil
1451    c.singleton_class.class_eval do
1452      define_method(:method_removed) {|id| removed = id}
1453    end
1454    assert_nothing_raised(NoMethodError, NameError, '[Bug #7843]') do
1455      c.class_eval do
1456        remove_method(:foo)
1457      end
1458    end
1459    assert_equal(:foo, removed)
1460  end
1461
1462  def test_prepend_class_ancestors
1463    bug6658 = '[ruby-core:45919]'
1464    m = labeled_module("m")
1465    c = labeled_class("c") {prepend m}
1466    assert_equal([m, c], c.ancestors[0, 2], bug6658)
1467
1468    bug6662 = '[ruby-dev:45868]'
1469    c2 = labeled_class("c2", c)
1470    anc = c2.ancestors
1471    assert_equal([c2, m, c, Object], anc[0..anc.index(Object)], bug6662)
1472  end
1473
1474  def test_prepend_module_ancestors
1475    bug6659 = '[ruby-dev:45861]'
1476    m0 = labeled_module("m0") {def x; [:m0, *super] end}
1477    m1 = labeled_module("m1") {def x; [:m1, *super] end; prepend m0}
1478    m2 = labeled_module("m2") {def x; [:m2, *super] end; prepend m1}
1479    c0 = labeled_class("c0") {def x; [:c0] end}
1480    c1 = labeled_class("c1") {def x; [:c1] end; prepend m2}
1481    c2 = labeled_class("c2", c0) {def x; [:c2, *super] end; include m2}
1482
1483    assert_equal([m0, m1], m1.ancestors, bug6659)
1484
1485    bug6662 = '[ruby-dev:45868]'
1486    assert_equal([m0, m1, m2], m2.ancestors, bug6662)
1487    assert_equal([m0, m1, m2, c1], c1.ancestors[0, 4], bug6662)
1488    assert_equal([:m0, :m1, :m2, :c1], c1.new.x)
1489    assert_equal([c2, m0, m1, m2, c0], c2.ancestors[0, 5], bug6662)
1490    assert_equal([:c2, :m0, :m1, :m2, :c0], c2.new.x)
1491
1492    m3 = labeled_module("m3") {include m1; prepend m1}
1493    assert_equal([m3, m0, m1], m3.ancestors)
1494    m3 = labeled_module("m3") {prepend m1; include m1}
1495    assert_equal([m0, m1, m3], m3.ancestors)
1496    m3 = labeled_module("m3") {prepend m1; prepend m1}
1497    assert_equal([m0, m1, m3], m3.ancestors)
1498    m3 = labeled_module("m3") {include m1; include m1}
1499    assert_equal([m3, m0, m1], m3.ancestors)
1500  end
1501
1502  def labeled_module(name, &block)
1503    EnvUtil.labeled_module(name, &block)
1504  end
1505
1506  def labeled_class(name, superclass = Object, &block)
1507    EnvUtil.labeled_class(name, superclass, &block)
1508  end
1509
1510  def test_prepend_instance_methods_false
1511    bug6660 = '[ruby-dev:45863]'
1512    assert_equal([:m1], Class.new{ prepend Module.new; def m1; end }.instance_methods(false), bug6660)
1513    assert_equal([:m1], Class.new(Class.new{def m2;end}){ prepend Module.new; def m1; end }.instance_methods(false), bug6660)
1514  end
1515
1516  def test_cyclic_prepend
1517    bug7841 = '[ruby-core:52205] [Bug #7841]'
1518    m1 = Module.new
1519    m2 = Module.new
1520    m1.instance_eval { prepend(m2) }
1521    assert_raise(ArgumentError, bug7841) do
1522      m2.instance_eval { prepend(m1) }
1523    end
1524  end
1525
1526  def test_prepend_optmethod
1527    bug7983 = '[ruby-dev:47124] [Bug #7983]'
1528    assert_separately [], %{
1529      module M
1530        def /(other)
1531          to_f / other
1532        end
1533      end
1534      Fixnum.send(:prepend, M)
1535      assert_equal(0.5, 1 / 2, "#{bug7983}")
1536    }
1537    assert_equal(0, 1 / 2)
1538  end
1539
1540  def test_prepend_visibility
1541    bug8005 = '[ruby-core:53106] [Bug #8005]'
1542    c = Class.new do
1543      prepend Module.new {}
1544      def foo() end
1545      protected :foo
1546    end
1547    a = c.new
1548    assert_respond_to a, [:foo, true]
1549    assert_nothing_raised(NoMethodError) {a.send :foo}
1550  end
1551
1552  def test_prepend_visibility_inherited
1553    bug8238 = '[ruby-core:54105] [Bug #8238]'
1554    assert_separately [], <<-"end;", timeout: 3
1555      class A
1556        def foo() A; end
1557        private :foo
1558      end
1559      class B < A
1560        public :foo
1561        prepend Module.new
1562      end
1563      assert_equal(A, B.new.foo, "#{bug8238}")
1564    end;
1565  end
1566
1567  def test_prepend_included_modules
1568    bug8025 = '[ruby-core:53158] [Bug #8025]'
1569    mixin = labeled_module("mixin")
1570    c = labeled_module("c") {prepend mixin}
1571    im = c.included_modules
1572    assert_not_include(im, c, bug8025)
1573    assert_include(im, mixin, bug8025)
1574    c1 = labeled_class("c1") {prepend mixin}
1575    c2 = labeled_class("c2", c1)
1576    im = c2.included_modules
1577    assert_not_include(im, c1, bug8025)
1578    assert_not_include(im, c2, bug8025)
1579    assert_include(im, mixin, bug8025)
1580  end
1581
1582  def test_prepend_super_in_alias
1583    bug7842 = '[Bug #7842]'
1584
1585    p = labeled_module("P") do
1586      def m; "P"+super; end
1587    end
1588    a = labeled_class("A") do
1589      def m; "A"; end
1590    end
1591    b = labeled_class("B", a) do
1592      def m; "B"+super; end
1593      alias m2 m
1594      prepend p
1595      alias m3 m
1596    end
1597    assert_equal("BA", b.new.m2, bug7842)
1598    assert_equal("PBA", b.new.m3, bug7842)
1599  end
1600
1601  def test_include_super_in_alias
1602    bug9236 = '[Bug #9236]'
1603
1604    fun = labeled_module("Fun") do
1605      def hello
1606        orig_hello
1607      end
1608    end
1609
1610    m1 = labeled_module("M1") do
1611      def hello
1612        'hello!'
1613      end
1614    end
1615
1616    m2 = labeled_module("M2") do
1617      def hello
1618        super
1619      end
1620    end
1621
1622    foo = labeled_class("Foo") do
1623      include m1
1624      include m2
1625
1626      alias orig_hello hello
1627      include fun
1628    end
1629
1630    assert_equal('hello!', foo.new.hello, bug9236)
1631  end
1632
1633  def test_class_variables
1634    m = Module.new
1635    m.class_variable_set(:@@foo, 1)
1636    m2 = Module.new
1637    m2.send(:include, m)
1638    m2.class_variable_set(:@@bar, 2)
1639    assert_equal([:@@foo], m.class_variables)
1640    assert_equal([:@@bar, :@@foo], m2.class_variables)
1641    assert_equal([:@@bar, :@@foo], m2.class_variables(true))
1642    assert_equal([:@@bar], m2.class_variables(false))
1643  end
1644
1645  Bug6891 = '[ruby-core:47241]'
1646
1647  def test_extend_module_with_protected_method
1648    list = []
1649
1650    x = Class.new {
1651      @list = list
1652
1653      extend Module.new {
1654        protected
1655
1656        def inherited(klass)
1657          @list << "protected"
1658          super(klass)
1659        end
1660      }
1661
1662      extend Module.new {
1663        def inherited(klass)
1664          @list << "public"
1665          super(klass)
1666        end
1667      }
1668    }
1669
1670    assert_nothing_raised(NoMethodError, Bug6891) {Class.new(x)}
1671    assert_equal(['public', 'protected'], list)
1672  end
1673
1674  def test_extend_module_with_protected_bmethod
1675    list = []
1676
1677    x = Class.new {
1678      extend Module.new {
1679        protected
1680
1681        define_method(:inherited) do |klass|
1682          list << "protected"
1683          super(klass)
1684        end
1685      }
1686
1687      extend Module.new {
1688        define_method(:inherited) do |klass|
1689          list << "public"
1690          super(klass)
1691        end
1692      }
1693    }
1694
1695    assert_nothing_raised(NoMethodError, Bug6891) {Class.new(x)}
1696    assert_equal(['public', 'protected'], list)
1697  end
1698
1699  def test_invalid_attr
1700    %w[
1701      foo?
1702      @foo
1703      @@foo
1704      $foo
1705    ].each do |name|
1706      assert_raises(NameError) do
1707        Module.new { attr_accessor name.to_sym }
1708      end
1709    end
1710  end
1711
1712  class AttrTest
1713    class << self
1714      attr_accessor :cattr
1715    end
1716    attr_accessor :iattr
1717    def ivar
1718      @ivar
1719    end
1720  end
1721
1722  def test_uninitialized_instance_variable
1723    a = AttrTest.new
1724    stderr = EnvUtil.verbose_warning do
1725      assert_nil(a.ivar)
1726    end
1727    assert_match(/instance variable @ivar not initialized/, stderr)
1728    a.instance_variable_set(:@ivar, 42)
1729    stderr = EnvUtil.verbose_warning do
1730      assert_equal(42, a.ivar)
1731    end
1732    assert_equal("", stderr)
1733  end
1734
1735  def test_uninitialized_attr
1736    a = AttrTest.new
1737    stderr = EnvUtil.verbose_warning do
1738      assert_nil(a.iattr)
1739    end
1740    assert_equal("", stderr)
1741    a.iattr = 42
1742    stderr = EnvUtil.verbose_warning do
1743      assert_equal(42, a.iattr)
1744    end
1745    assert_equal("", stderr)
1746  end
1747
1748  def test_uninitialized_attr_class
1749    stderr = EnvUtil.verbose_warning do
1750      assert_nil(AttrTest.cattr)
1751    end
1752    assert_equal("", stderr)
1753    AttrTest.cattr = 42
1754    stderr = EnvUtil.verbose_warning do
1755      assert_equal(42, AttrTest.cattr)
1756    end
1757    assert_equal("", stderr)
1758  end
1759
1760  def test_uninitialized_attr_non_object
1761    a = Class.new(Array) do
1762      attr_accessor :iattr
1763    end.new
1764    stderr = EnvUtil.verbose_warning do
1765      assert_nil(a.iattr)
1766    end
1767    assert_equal("", stderr)
1768    a.iattr = 42
1769    stderr = EnvUtil.verbose_warning do
1770      assert_equal(42, a.iattr)
1771    end
1772    assert_equal("", stderr)
1773  end
1774
1775  def test_remove_const
1776    m = Module.new
1777    assert_raise(NameError){ m.instance_eval { remove_const(:__FOO__) } }
1778  end
1779
1780  def test_private_top_methods
1781    assert_top_method_is_private(:include)
1782    assert_top_method_is_private(:public)
1783    assert_top_method_is_private(:private)
1784    assert_top_method_is_private(:define_method)
1785  end
1786
1787  module PrivateConstantReopen
1788    PRIVATE_CONSTANT = true
1789    private_constant :PRIVATE_CONSTANT
1790  end
1791
1792  def test_private_constant_reopen
1793    assert_raise(NameError) do
1794      eval <<-EOS, TOPLEVEL_BINDING
1795        module TestModule::PrivateConstantReopen::PRIVATE_CONSTANT
1796        end
1797      EOS
1798    end
1799    assert_raise(NameError) do
1800      eval <<-EOS, TOPLEVEL_BINDING
1801        class TestModule::PrivateConstantReopen::PRIVATE_CONSTANT
1802        end
1803      EOS
1804    end
1805  end
1806
1807  def test_anonymous_module_public_class_method
1808    bug8284 = '[ruby-core:54404] [Bug #8284]'
1809    assert_raise(NoMethodError) {Object.define_method}
1810    Module.new.public_class_method(:define_method)
1811    assert_raise(NoMethodError, bug8284) {Object.define_method}
1812  end
1813
1814  def test_include_module_with_constants_invalidates_method_cache
1815    assert_in_out_err([], <<-RUBY, %w(123 456), [])
1816      A = 123
1817
1818      class Foo
1819        def self.a
1820          A
1821        end
1822      end
1823
1824      module M
1825        A = 456
1826      end
1827
1828      puts Foo.a
1829      Foo.send(:include, M)
1830      puts Foo.a
1831    RUBY
1832  end
1833
1834  private
1835
1836  def assert_top_method_is_private(method)
1837    top = eval("self", TOPLEVEL_BINDING)
1838    methods = top.singleton_class.private_instance_methods(false)
1839    assert(methods.include?(method), "#{method} should be private")
1840
1841    assert_in_out_err([], <<-INPUT, [], /private method `#{method}' called for main:Object \(NoMethodError\)/)
1842      self.#{method}
1843    INPUT
1844  end
1845end
1846