fix load_first_existing_class to die on an existing class that fails to compile
[gitmo/Class-MOP.git] / t / 004_advanced_methods.t
1 use strict;
2 use warnings;
3
4 use Test::More tests => 12;
5 use Test::Exception;
6
7 use Class::MOP;
8 use Class::MOP::Class;
9
10 =pod
11
12 The following class hierarhcy is very contrived 
13 and totally horrid (it won't work under C3 even),
14 but it tests a number of aspect of this module.
15
16 A more real-world example would be a nice addition :)
17
18 =cut
19
20 {
21     package Foo;
22     
23     sub BUILD { 'Foo::BUILD' }    
24     sub foo { 'Foo::foo' }
25     
26     package Bar;
27     our @ISA = ('Foo');
28     
29     sub BUILD { 'Bar::BUILD' }    
30     sub bar { 'Bar::bar' }     
31     
32     package Baz;
33     our @ISA = ('Bar');
34     
35     sub baz { 'Baz::baz' }
36     sub foo { 'Baz::foo' }           
37     
38     package Foo::Bar;
39     our @ISA = ('Foo', 'Bar');
40     
41     sub BUILD { 'Foo::Bar::BUILD' }    
42     sub foobar { 'Foo::Bar::foobar' }    
43     
44     package Foo::Bar::Baz;
45     our @ISA = ('Foo', 'Bar', 'Baz');
46     
47     sub BUILD { 'Foo::Bar::Baz::BUILD' }    
48     sub bar { 'Foo::Bar::Baz::bar' }    
49     sub foobarbaz { 'Foo::Bar::Baz::foobarbaz' }    
50 }
51
52 ok(!defined(Class::MOP::Class->initialize('Foo')->find_next_method_by_name('BUILD')), 
53    '... Foo::BUILD has not next method');
54
55 is(Class::MOP::Class->initialize('Bar')->find_next_method_by_name('BUILD'), 
56    Class::MOP::Class->initialize('Foo')->get_method('BUILD'),     
57    '... Bar::BUILD does have a next method');
58    
59 is(Class::MOP::Class->initialize('Baz')->find_next_method_by_name('BUILD'), 
60    Class::MOP::Class->initialize('Bar')->get_method('BUILD'),     
61    '... Baz->BUILD does have a next method');   
62    
63 is(Class::MOP::Class->initialize('Foo::Bar')->find_next_method_by_name('BUILD'), 
64    Class::MOP::Class->initialize('Foo')->get_method('BUILD'),     
65    '... Foo::Bar->BUILD does have a next method');   
66    
67 is(Class::MOP::Class->initialize('Foo::Bar::Baz')->find_next_method_by_name('BUILD'), 
68    Class::MOP::Class->initialize('Foo')->get_method('BUILD'),     
69    '... Foo::Bar::Baz->BUILD does have a next method');   
70
71 is_deeply(
72     [ sort { $a->{name} cmp $b->{name} } Class::MOP::Class->initialize('Foo')->get_all_methods() ],
73     [
74         Class::MOP::Class->initialize('Foo')->get_method('BUILD') ,
75         Class::MOP::Class->initialize('Foo')->get_method('foo'),
76     ],
77     '... got the right list of applicable methods for Foo');
78     
79 is_deeply(
80     [ sort { $a->{name} cmp $b->{name} } Class::MOP::Class->initialize('Bar')->get_all_methods() ],
81     [
82         Class::MOP::Class->initialize('Bar')->get_method('BUILD'),
83         Class::MOP::Class->initialize('Bar')->get_method('bar'),
84         Class::MOP::Class->initialize('Foo')->get_method('foo'),
85     ],
86     '... got the right list of applicable methods for Bar');
87     
88
89 is_deeply(
90     [ sort { $a->{name} cmp $b->{name} } Class::MOP::Class->initialize('Baz')->get_all_methods() ],
91     [   
92         Class::MOP::Class->initialize('Bar')->get_method('BUILD'),
93         Class::MOP::Class->initialize('Bar')->get_method('bar'),
94         Class::MOP::Class->initialize('Baz')->get_method('baz'),
95         Class::MOP::Class->initialize('Baz')->get_method('foo'),
96     ],
97     '... got the right list of applicable methods for Baz');
98
99 is_deeply(
100     [ sort { $a->{name} cmp $b->{name} } Class::MOP::Class->initialize('Foo::Bar')->get_all_methods() ],
101     [
102         Class::MOP::Class->initialize('Foo::Bar')->get_method('BUILD'),
103         Class::MOP::Class->initialize('Bar')->get_method('bar'),
104         Class::MOP::Class->initialize('Foo')->get_method('foo'),
105         Class::MOP::Class->initialize('Foo::Bar')->get_method('foobar'),
106     ],
107     '... got the right list of applicable methods for Foo::Bar');
108
109 # test compute_all_applicable_methods once for compat
110 is_deeply(
111     [ sort { $a->{name} cmp $b->{name} } Class::MOP::Class->initialize('Foo::Bar::Baz')->compute_all_applicable_methods() ],
112     [
113         {
114             name  => 'BUILD',
115             class => 'Foo::Bar::Baz',
116             code  => Class::MOP::Class->initialize('Foo::Bar::Baz')->get_method('BUILD')
117         },    
118         {
119             name  => 'bar',
120             class => 'Foo::Bar::Baz',
121             code  => Class::MOP::Class->initialize('Foo::Bar::Baz')->get_method('bar')
122         },
123         {
124             name  => 'baz',
125             class => 'Baz',
126             code  => Class::MOP::Class->initialize('Baz')->get_method('baz')
127         },        
128         {
129             name  => 'foo',
130             class => 'Foo',
131             code  => Class::MOP::Class->initialize('Foo')->get_method('foo')
132         },   
133         {
134             name  => 'foobarbaz',
135             class => 'Foo::Bar::Baz',
136             code  => Class::MOP::Class->initialize('Foo::Bar::Baz')->get_method('foobarbaz')
137         },            
138     ],
139     '... got the right list of applicable methods for Foo::Bar::Baz');
140
141 ## find_all_methods_by_name
142
143 is_deeply(
144     [ Class::MOP::Class->initialize('Foo::Bar')->find_all_methods_by_name('BUILD') ],
145     [
146         {
147             name  => 'BUILD',
148             class => 'Foo::Bar',
149             code  => Class::MOP::Class->initialize('Foo::Bar')->get_method('BUILD')
150         },    
151         {
152             name  => 'BUILD',
153             class => 'Foo',
154             code  => Class::MOP::Class->initialize('Foo')->get_method('BUILD')
155         },    
156         {
157             name  => 'BUILD',
158             class => 'Bar',
159             code  => Class::MOP::Class->initialize('Bar')->get_method('BUILD')
160         }
161     ],
162     '... got the right list of BUILD methods for Foo::Bar');
163
164 is_deeply(
165     [ Class::MOP::Class->initialize('Foo::Bar::Baz')->find_all_methods_by_name('BUILD') ],
166     [
167         {
168             name  => 'BUILD',
169             class => 'Foo::Bar::Baz',
170             code  => Class::MOP::Class->initialize('Foo::Bar::Baz')->get_method('BUILD')
171         },    
172         {
173             name  => 'BUILD',
174             class => 'Foo',
175             code  => Class::MOP::Class->initialize('Foo')->get_method('BUILD')
176         },    
177         {
178             name  => 'BUILD',
179             class => 'Bar',
180             code  => Class::MOP::Class->initialize('Bar')->get_method('BUILD') 
181         },            
182     ],
183     '... got the right list of BUILD methods for Foo::Bar::Baz');