1module Super
2  module S1
3    class A
4      def foo(a)
5        a << "A#foo"
6        bar(a)
7      end
8      def bar(a)
9        a << "A#bar"
10      end
11    end
12    class B < A
13      def foo(a)
14        a << "B#foo"
15        super(a)
16      end
17      def bar(a)
18        a << "B#bar"
19        super(a)
20      end
21    end
22  end
23
24  module S2
25    class A
26      def baz(a)
27        a << "A#baz"
28      end
29    end
30    class B < A
31      def foo(a)
32        a << "B#foo"
33        baz(a)
34      end
35    end
36    class C < B
37      def baz(a)
38        a << "C#baz"
39        super(a)
40      end
41    end
42  end
43
44  module S3
45    class A
46      def foo(a)
47        a << "A#foo"
48      end
49      def self.foo(a)
50        a << "A.foo"
51      end
52      def self.bar(a)
53        a << "A.bar"
54        foo(a)
55      end
56    end
57    class B < A
58      def self.foo(a)
59        a << "B.foo"
60        super(a)
61      end
62      def self.bar(a)
63        a << "B.bar"
64        super(a)
65      end
66    end
67  end
68
69  module S4
70    class A
71      def foo(a)
72        a << "A#foo"
73      end
74    end
75    class B < A
76      def foo(a, b)
77        a << "B#foo(a,#{b})"
78        super(a)
79      end
80    end
81  end
82
83  class S5
84    def here
85      :good
86    end
87  end
88
89  class S6 < S5
90    def under
91      yield
92    end
93
94    def here
95      under {
96        super
97      }
98    end
99  end
100
101  class S7 < S5
102    define_method(:here) { super() }
103  end
104
105  module MS1
106    module ModA
107      def foo(a)
108        a << "ModA#foo"
109        bar(a)
110      end
111      def bar(a)
112        a << "ModA#bar"
113      end
114    end
115    class A
116      include ModA
117    end
118    module ModB
119      def bar(a)
120        a << "ModB#bar"
121        super(a)
122      end
123    end
124    class B < A
125      def foo(a)
126        a << "B#foo"
127        super(a)
128      end
129      include ModB
130    end
131  end
132
133  module MS2
134    class A
135      def baz(a)
136        a << "A#baz"
137      end
138    end
139    module ModB
140      def foo(a)
141        a << "ModB#foo"
142        baz(a)
143      end
144    end
145    class B < A
146      include ModB
147    end
148    class C < B
149      def baz(a)
150        a << "C#baz"
151        super(a)
152      end
153    end
154  end
155
156  module MultiSuperTargets
157    module M
158      def foo
159        super
160      end
161    end
162
163    class BaseA
164      def foo
165        :BaseA
166      end
167    end
168
169    class BaseB
170      def foo
171        :BaseB
172      end
173    end
174
175    class A < BaseA
176      include M
177    end
178
179    class B < BaseB
180      include M
181    end
182  end
183
184  module MS3
185    module ModA
186      def foo(a)
187        a << "ModA#foo"
188      end
189      def bar(a)
190        a << "ModA#bar"
191        foo(a)
192      end
193    end
194    class A
195      def foo(a)
196        a << "A#foo"
197      end
198      class << self
199        include ModA
200      end
201    end
202    class B < A
203      def self.foo(a)
204        a << "B.foo"
205        super(a)
206      end
207      def self.bar(a)
208        a << "B.bar"
209        super(a)
210      end
211    end
212  end
213
214  module MS4
215    module Layer1
216      def example
217        5
218      end
219    end
220
221    module Layer2
222      include Layer1
223      def example
224        super
225      end
226    end
227
228    class A
229      include Layer2
230      public :example
231    end
232  end
233
234  class MM_A
235    undef_method :is_a?
236  end
237
238  class MM_B < MM_A
239    def is_a?(blah)
240      # should fire the method_missing below
241      super
242    end
243
244    def method_missing(*)
245      false
246    end
247  end
248
249  class Alias1
250    def name
251      [:alias1]
252    end
253  end
254
255  class Alias2 < Alias1
256    def initialize
257      @times = 0
258    end
259
260    def name
261      if @times >= 10
262        raise "runaway super"
263      end
264
265      @times += 1
266
267      # Use this so that we can see collect all supers that we see.
268      # One bug that arises is that we call Alias2#name from Alias2#name
269      # as it's superclass. In that case, either we get a runaway recursion
270      # super OR we get the return value being [:alias2, :alias2, :alias1]
271      # rather than [:alias2, :alias1].
272      #
273      # Which one depends on caches and how super is implemented.
274      [:alias2] + super
275    end
276  end
277
278  class Alias3 < Alias2
279    alias_method :name3, :name
280    # In the method table for Alias3 now should be a special alias entry
281    # that references Alias2 and Alias2#name (probably as an object).
282    #
283    # When name3 is called then, Alias2 (NOT Alias3) is presented as the
284    # current module to Alias2#name, so that when super is called,
285    # Alias2->superclass is next.
286    #
287    # Otherwise, Alias2 is next, which is where name was to begin with,
288    # causing the wrong #name method to be called.
289  end
290
291  module AliasWithSuper
292    module AS1
293      def foo
294        :a
295      end
296    end
297
298    module BS1
299      def foo
300        [:b, super]
301      end
302    end
303
304    class Base
305      extend AS1
306      extend BS1
307    end
308
309    class Trigger < Base
310      class << self
311        def foo_quux
312          foo_baz
313        end
314
315        alias_method :foo_baz, :foo
316        alias_method :foo, :foo_quux
317      end
318    end
319  end
320
321  module RestArgsWithSuper
322    class A
323      def a(*args)
324        args
325      end
326    end
327
328    class B < A
329      def a(*args)
330        args << "foo"
331
332        super
333      end
334    end
335  end
336
337  class AnonymousModuleIncludedTwiceBase
338    def self.whatever
339      mod = Module.new do
340        def a(array)
341          array << "anon"
342          super
343        end
344      end
345
346      include mod
347    end
348
349    def a(array)
350      array << "non-anon"
351    end
352  end
353
354  class AnonymousModuleIncludedTwice < AnonymousModuleIncludedTwiceBase
355    whatever
356    whatever
357  end
358
359  module ZSuperWithBlock
360    class A
361      def a
362        yield
363      end
364
365      def b(&block)
366        block.call
367      end
368
369      def c
370        yield
371      end
372    end
373
374    class B < A
375      def a
376        super { 14 }
377      end
378
379      def b
380        block_ref = lambda { 15 }
381        [super { 14 }, super(&block_ref)]
382      end
383
384      def c
385        block_ref = lambda { 16 }
386        super(&block_ref)
387      end
388    end
389  end
390
391  module ZSuperWithOptional
392    class A
393      def m(x, y, z)
394        z
395      end
396    end
397
398    class B < A
399      def m(x, y, z = 14)
400        super
401      end
402    end
403
404    class C < A
405      def m(x, y, z = 14)
406        z = 100
407        super
408      end
409    end
410  end
411
412  module ZSuperWithRest
413    class A
414      def m(*args)
415        args
416      end
417
418      def m_modified(*args)
419        args
420      end
421    end
422
423    class B < A
424      def m(*args)
425        super
426      end
427
428      def m_modified(*args)
429        args[1] = 14
430        super
431      end
432    end
433  end
434
435  module ZSuperWithRestAndOthers
436    class A
437      def m(a, b, *args)
438        args
439      end
440
441      def m_modified(a, b, *args)
442        args
443      end
444    end
445
446    class B < A
447      def m(a, b, *args)
448        super
449      end
450
451      def m_modified(a, b, *args)
452        args[1] = 14
453        super
454      end
455    end
456  end
457
458  module ZSuperWithRestReassigned
459    class A
460      def a(*args)
461        args
462      end
463    end
464
465    class B < A
466      def a(*args)
467        args = ["foo"]
468
469        super
470      end
471    end
472  end
473
474  module ZSuperWithRestReassignedWithScalar
475    class A
476      def a(*args)
477        args
478      end
479    end
480
481    class B < A
482      def a(*args)
483        args = "foo"
484
485        super
486      end
487    end
488  end
489
490  module ZSuperWithUnderscores
491    class A
492      def m(*args)
493        args
494      end
495
496      def m_modified(*args)
497        args
498      end
499    end
500
501    class B < A
502      def m(_, _)
503        super
504      end
505
506      def m_modified(_, _)
507        _ = 14
508        super
509      end
510    end
511  end
512
513  module Keywords
514    class Arguments
515      def foo(**args)
516        args
517      end
518    end
519
520    # ----
521
522    class RequiredArguments < Arguments
523      def foo(a:)
524        super
525      end
526    end
527
528    class OptionalArguments < Arguments
529      def foo(b: 'b')
530        super
531      end
532    end
533
534    class PlaceholderArguments < Arguments
535      def foo(**args)
536        super
537      end
538    end
539
540    # ----
541
542    class RequiredAndOptionalArguments < Arguments
543      def foo(a:, b: 'b')
544        super
545      end
546    end
547
548    class RequiredAndPlaceholderArguments < Arguments
549      def foo(a:, **args)
550        super
551      end
552    end
553
554    class OptionalAndPlaceholderArguments < Arguments
555      def foo(b: 'b', **args)
556        super
557      end
558    end
559
560    # ----
561
562    class RequiredAndOptionalAndPlaceholderArguments < Arguments
563      def foo(a:, b: 'b', **args)
564        super
565      end
566    end
567  end
568
569  module RegularAndKeywords
570    class Arguments
571      def foo(a, **options)
572        [a, options]
573      end
574    end
575
576    # -----
577
578    class RequiredArguments < Arguments
579      def foo(a, b:)
580        super
581      end
582    end
583
584    class OptionalArguments < Arguments
585      def foo(a, c: 'c')
586        super
587      end
588    end
589
590    class PlaceholderArguments < Arguments
591      def foo(a, **options)
592        super
593      end
594    end
595
596    # -----
597
598    class RequiredAndOptionalArguments < Arguments
599      def foo(a, b:, c: 'c')
600        super
601      end
602    end
603
604    class RequiredAndPlaceholderArguments < Arguments
605      def foo(a, b:, **options)
606        super
607      end
608    end
609
610    class OptionalAndPlaceholderArguments < Arguments
611      def foo(a, c: 'c', **options)
612        super
613      end
614    end
615
616    # -----
617
618    class RequiredAndOptionalAndPlaceholderArguments < Arguments
619      def foo(a, b:, c: 'c', **options)
620        super
621      end
622    end
623  end
624
625  module SplatAndKeywords
626    class Arguments
627      def foo(*args, **options)
628        [args, options]
629      end
630    end
631
632    class AllArguments < Arguments
633      def foo(*args, **options)
634        super
635      end
636    end
637  end
638
639  module FromBasicObject
640    def __send__(name, *args, &block)
641      super
642    end
643  end
644
645  module IntermediateBasic
646    include FromBasicObject
647  end
648
649  class IncludesFromBasic
650    include FromBasicObject
651
652    def foobar; 43; end
653  end
654
655  class IncludesIntermediate
656    include IntermediateBasic
657
658    def foobar; 42; end
659  end
660
661  module SingletonCase
662    class Base
663      def foobar(array)
664        array << :base
665      end
666    end
667
668    class Foo < Base
669      def foobar(array)
670        array << :foo
671        super
672      end
673    end
674  end
675
676  module SingletonAliasCase
677    class Base
678      def foobar(array)
679        array << :base
680      end
681
682      def alias_on_singleton
683        object = self
684        singleton = (class << object; self; end)
685        singleton.__send__(:alias_method, :new_foobar, :foobar)
686      end
687    end
688
689    class Foo < Base
690      def foobar(array)
691        array << :foo
692        super
693      end
694    end
695  end
696end
697