Require Dist::Zilla 4.200016+
[gitmo/Moose.git] / t / cmop / class_precedence_list.t
1 use strict;
2 use warnings;
3
4 use Test::More;
5
6 use Class::MOP;
7 use Class::MOP::Class;
8
9 =pod
10
11   A
12  / \
13 B   C
14  \ /
15   D
16
17 =cut
18
19 {
20     package My::A;
21     use metaclass;
22     package My::B;
23     our @ISA = ('My::A');
24     package My::C;
25     our @ISA = ('My::A');
26     package My::D;
27     our @ISA = ('My::B', 'My::C');
28 }
29
30 is_deeply(
31     [ My::D->meta->class_precedence_list ],
32     [ 'My::D', 'My::B', 'My::A', 'My::C', 'My::A' ],
33     '... My::D->meta->class_precedence_list == (D B A C A)');
34
35 is_deeply(
36     [ My::D->meta->linearized_isa ],
37     [ 'My::D', 'My::B', 'My::A', 'My::C' ],
38     '... My::D->meta->linearized_isa == (D B A C)');
39
40 =pod
41
42  A <-+
43  |   |
44  B   |
45  |   |
46  C --+
47
48 =cut
49
50 # 5.9.5+ dies at the moment of
51 # recursive @ISA definition, not later when
52 # you try to use the @ISAs.
53 eval {
54     {
55         package My::2::A;
56         use metaclass;
57         our @ISA = ('My::2::C');
58
59         package My::2::B;
60         our @ISA = ('My::2::A');
61
62         package My::2::C;
63         our @ISA = ('My::2::B');
64     }
65
66     My::2::B->meta->class_precedence_list
67 };
68 ok($@, '... recursive inheritance breaks correctly :)');
69
70 =pod
71
72  +--------+
73  |    A   |
74  |   / \  |
75  +->B   C-+
76      \ /
77       D
78
79 =cut
80
81 {
82     package My::3::A;
83     use metaclass;
84     package My::3::B;
85     our @ISA = ('My::3::A');
86     package My::3::C;
87     our @ISA = ('My::3::A', 'My::3::B');
88     package My::3::D;
89     our @ISA = ('My::3::B', 'My::3::C');
90 }
91
92 is_deeply(
93     [ My::3::D->meta->class_precedence_list ],
94     [ 'My::3::D', 'My::3::B', 'My::3::A', 'My::3::C', 'My::3::A', 'My::3::B', 'My::3::A' ],
95     '... My::3::D->meta->class_precedence_list == (D B A C A B A)');
96
97 is_deeply(
98     [ My::3::D->meta->linearized_isa ],
99     [ 'My::3::D', 'My::3::B', 'My::3::A', 'My::3::C' ],
100     '... My::3::D->meta->linearized_isa == (D B A C B)');
101
102 =pod
103
104 Test all the class_precedence_lists
105 using Perl's own dispatcher to check
106 against.
107
108 =cut
109
110 my @CLASS_PRECEDENCE_LIST;
111
112 {
113     package Foo;
114     use metaclass;
115
116     sub CPL { push @CLASS_PRECEDENCE_LIST => 'Foo' }
117
118     package Bar;
119     our @ISA = ('Foo');
120
121     sub CPL {
122         push @CLASS_PRECEDENCE_LIST => 'Bar';
123         $_[0]->SUPER::CPL();
124     }
125
126     package Baz;
127     use metaclass;
128     our @ISA = ('Bar');
129
130     sub CPL {
131         push @CLASS_PRECEDENCE_LIST => 'Baz';
132         $_[0]->SUPER::CPL();
133     }
134
135     package Foo::Bar;
136     our @ISA = ('Baz');
137
138     sub CPL {
139         push @CLASS_PRECEDENCE_LIST => 'Foo::Bar';
140         $_[0]->SUPER::CPL();
141     }
142
143     package Foo::Bar::Baz;
144     our @ISA = ('Foo::Bar');
145
146     sub CPL {
147         push @CLASS_PRECEDENCE_LIST => 'Foo::Bar::Baz';
148         $_[0]->SUPER::CPL();
149     }
150
151 }
152
153 Foo::Bar::Baz->CPL();
154
155 is_deeply(
156     [ Foo::Bar::Baz->meta->class_precedence_list ],
157     [ @CLASS_PRECEDENCE_LIST ],
158     '... Foo::Bar::Baz->meta->class_precedence_list == @CLASS_PRECEDENCE_LIST');
159
160 done_testing;