1##
2# Class ISO Test
3
4assert('Class', '15.2.3') do
5  assert_equal(Class, Class.class)
6end
7
8assert('Class#initialize', '15.2.3.3.1') do
9  c = Class.new do
10    def test
11      :test
12    end
13  end.new
14
15  assert_equal(c.test, :test)
16end
17
18assert('Class#initialize_copy', '15.2.3.3.2') do
19  class TestClass
20    attr_accessor :n
21    def initialize(n)
22      @n = n
23    end
24    def initialize_copy(obj)
25      @n = n
26    end
27  end
28
29  c1 = TestClass.new('Foo')
30  c2 = c1.dup
31  c3 = TestClass.new('Bar')
32
33  assert_equal(c1.n, c2.n)
34  assert_not_equal(c1.n, c3.n)
35end
36
37assert('Class#new', '15.2.3.3.3') do
38  assert_raise(TypeError, 'Singleton should raise TypeError') do
39    (class <<"a"; self; end).new
40  end
41
42  class TestClass
43    def initialize args, &block
44      @result = if not args.nil? and block.nil?
45        # only arguments
46        :only_args
47      elsif not args.nil? and not block.nil?
48        # args and block is given
49        :args_and_block
50      else
51        # this should never happen
52        :broken
53      end
54    end
55
56    def result; @result; end
57  end
58
59  assert_equal(:only_args, TestClass.new(:arg).result)
60  # with block doesn't work yet
61end
62
63assert('Class#superclass', '15.2.3.3.4') do
64  class SubClass < String; end
65  assert_equal(String, SubClass.superclass)
66end
67
68# Not ISO specified
69
70assert('Class 1') do
71  class C1; end
72  assert_equal(Class, C1.class)
73end
74
75assert('Class 2') do
76  class C2; end
77  assert_equal(C2, C2.new.class)
78end
79
80assert('Class 3') do
81  class C3; end
82  assert_equal(Class, C3.new.class.class)
83end
84
85assert('Class 4') do
86  class C4_A; end
87  class C4 < C4_A; end
88  assert_equal(Class, C4.class)
89end
90
91assert('Class 5') do
92  class C5_A; end
93  class C5 < C5_A; end
94  assert_equal(C5, C5.new.class)
95end
96
97assert('Class 6') do
98  class C6_A; end
99  class C6 < C6_A; end
100  assert_equal(Class, C6.new.class.class)
101end
102
103assert('Class 7') do
104  class C7_A; end
105  class C7_B; end
106
107  class C7 < C7_A; end
108
109  assert_raise(TypeError) do
110    # Different superclass.
111    class C7 < C7_B; end
112  end
113end
114
115assert('Class 8') do
116  class C8_A; end
117
118  class C8; end  # superclass is Object
119
120  assert_raise(TypeError) do
121    # Different superclass.
122    class C8 < C8_A; end
123  end
124end
125
126assert('Class 9') do
127  Class9Const = "a"
128
129  assert_raise(TypeError) do
130    class Class9Const; end
131  end
132end
133
134assert('Class Module 1') do
135  module M; end
136  assert_equal(Module, M.class)
137end
138
139assert('Class Module 2') do
140  module M; end
141  class C; include M; end
142  assert_equal(C, C.new.class)
143end
144
145# nested class
146assert('Class Nested 1') do
147  class A; end
148  class A::B; end
149  assert_equal(A::B, A::B)
150end
151
152assert('Class Nested 2') do
153  class A; end
154  class A::B; end
155  assert_equal(A::B, A::B.new.class)
156end
157
158assert('Class Nested 3') do
159  class A; end
160  class A::B; end
161  assert_equal(Class, A::B.new.class.class)
162end
163
164assert('Class Nested 4') do
165  class A; end
166  class A::B; end
167  class A::B::C; end
168  assert_equal(A::B::C, A::B::C)
169end
170
171assert('Class Nested 5') do
172  class A; end
173  class A::B; end
174  class A::B::C; end
175  assert_equal(Class, A::B::C.class)
176end
177
178assert('Class Nested 6') do
179  class A; end
180  class A::B; end
181  class A::B::C; end
182  assert_equal(A::B::C, A::B::C.new.class)
183end
184
185assert('Class Nested 7') do
186  class A; end
187  class A::B; end
188  class A::B2 < A::B; end
189  assert_equal(A::B2, A::B2)
190end
191
192assert('Class Nested 8') do
193  class A; end
194  class A::B; end
195  class A::B2 < A::B; end
196  assert_equal(Class, A::B2.class)
197end
198
199assert('Class Colon 1') do
200  class A; end
201  A::C = 1
202  assert_equal(1, A::C)
203end
204
205assert('Class Colon 2') do
206  class A; class ::C; end end
207  assert_equal(C, C)
208end
209
210assert('Class Colon 3') do
211  class A; class ::C; end end
212  assert_equal(Class, C.class)
213end
214
215assert('Class Dup 1') do
216  class C; end
217  assert_equal(Class, C.dup.class)
218end
219
220assert('Class Dup 2') do
221  module M; end
222  assert_equal(Module, M.dup.class)
223end
224
225assert('Class.new') do
226  assert_equal(Class, Class.new.class)
227  a = []
228  klass = Class.new do |c|
229    a << c
230  end
231  assert_equal([klass], a)
232end
233
234assert('class to return the last value') do
235  m = class C; :m end
236  assert_equal(m, :m)
237end
238
239assert('class to return nil if body is empty') do
240  assert_nil(class C end)
241  assert_nil(class << self; end)
242end
243
244assert('raise when superclass is not a class') do
245  module FirstModule; end
246  assert_raise(TypeError, 'should raise TypeError') do
247    class FirstClass < FirstModule; end
248  end
249
250  class SecondClass; end
251  assert_raise(TypeError, 'should raise TypeError') do
252    class SecondClass < false; end
253  end
254
255  class ThirdClass; end
256  assert_raise(TypeError, 'should raise TypeError') do
257    class ThirdClass < ThirdClass; end
258  end
259end
260
261assert('Class#inherited') do
262  class Foo
263    @@subclass_name = nil
264    def self.inherited(subclass)
265      @@subclass_name = subclass
266    end
267    def self.subclass_name
268      @@subclass_name
269    end
270  end
271
272  assert_equal(nil, Foo.subclass_name)
273
274  class Bar < Foo
275  end
276
277  assert_equal(Bar, Foo.subclass_name)
278
279  class Baz < Bar
280  end
281
282  assert_equal(Baz, Foo.subclass_name)
283end
284
285assert('singleton tests') do
286  module FooMod
287    def run_foo_mod
288      100
289    end
290  end
291
292  bar = String.new
293
294  baz = class << bar
295    extend FooMod
296    def self.run_baz
297      200
298    end
299  end
300
301  assert_equal :run_baz, baz
302
303  assert_raise(NoMethodError, 'should raise NoMethodError') do
304    bar.run_foo_mod
305  end
306  assert_raise(NoMethodError, 'should raise NoMethodError') do
307    bar.run_baz
308  end
309
310  baz = class << bar
311    extend FooMod
312    def self.run_baz
313      300
314    end
315    self
316  end
317
318  assert_true baz.respond_to? :run_baz
319  assert_true baz.respond_to? :run_foo_mod
320  assert_equal 100, baz.run_foo_mod
321  assert_equal 300, baz.run_baz
322
323  assert_raise(NoMethodError, 'should raise NoMethodError') do
324    bar.run_foo_mod
325  end
326  assert_raise(NoMethodError, 'should raise NoMethodError') do
327    bar.run_baz
328  end
329
330  fv = false
331  class << fv
332    def self.run_false
333      5
334    end
335  end
336
337  nv = nil
338  class << nv
339    def self.run_nil
340      6
341    end
342  end
343
344  tv = true
345  class << tv
346    def self.run_nil
347      7
348    end
349  end
350
351  assert_raise(TypeError, 'should raise TypeError') do
352    num = 1.0
353    class << num
354      def self.run_nil
355        7
356      end
357    end
358  end if Object.const_defined?(:Float)
359end
360
361assert('clone Class') do
362  class Foo
363    def func
364      true
365    end
366  end
367
368  Foo.clone.new.func
369end
370
371assert('class variable and class << self style class method') do
372  class ClassVariableTest
373    @@class_variable = "value"
374    class << self
375      def class_variable
376        @@class_variable
377      end
378    end
379  end
380
381  assert_equal("value", ClassVariableTest.class_variable)
382end
383
384assert('class variable definition in singleton_class') do
385  class ClassVariableDefinitionInSingletonTest
386    class << self
387      @@class_variable = "value"
388    end
389    def class_variable
390      @@class_variable
391    end
392  end
393
394  assert_equal("value", ClassVariableDefinitionInSingletonTest.new.class_variable)
395end
396
397assert('class variable in module and class << self style class method') do
398  module ClassVariableInModuleTest
399    @@class_variable = "value"
400    class << self
401      def class_variable
402        @@class_variable
403      end
404    end
405  end
406
407  assert_equal("value", ClassVariableInModuleTest.class_variable)
408end
409
410assert('child class/module defined in singleton class get parent constant') do
411  actual = module GetParentConstantTest
412            EXPECT = "value"
413            class << self
414              class CHILD
415                class << self
416                    EXPECT
417                end
418              end
419            end
420          end
421  assert_equal("value", actual)
422end
423
424assert('overriding class variable with a module (#3235)') do
425  module ModuleWithCVar
426    @@class_variable = 1
427  end
428  class CVarOverrideTest
429    @@class_variable = 2
430    include ModuleWithCVar
431
432    assert_equal(1, @@class_variable)
433  end
434end
435
436assert('class with non-class/module outer raises TypeError') do
437  assert_raise(TypeError) { class 0::C1; end }
438  assert_raise(TypeError) { class []::C2; end }
439end
440