4a091d36b5391ea6b83c8c997a70cd3978177cce
[gitmo/Class-MOP.git] / t / 004_advanced_methods.t
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use Test::More tests => 14;
7 use Test::Exception;
8
9 BEGIN {
10     use_ok('Class::MOP');   
11     use_ok('Class::MOP::Class');        
12 }
13
14 =pod
15
16 The following class hierarhcy is very contrived 
17 and totally horrid (it won't work under C3 even),
18 but it tests a number of aspect of this module.
19
20 A more real-world example would be a nice addition :)
21
22 =cut
23
24 {
25     package Foo;
26     
27     sub BUILD { 'Foo::BUILD' }    
28     sub foo { 'Foo::foo' }
29     
30     package Bar;
31     our @ISA = ('Foo');
32     
33     sub BUILD { 'Bar::BUILD' }    
34     sub bar { 'Bar::bar' }     
35     
36     package Baz;
37     our @ISA = ('Bar');
38     
39     sub baz { 'Baz::baz' }
40     sub foo { 'Baz::foo' }           
41     
42     package Foo::Bar;
43     our @ISA = ('Foo', 'Bar');
44     
45     sub BUILD { 'Foo::Bar::BUILD' }    
46     sub foobar { 'Foo::Bar::foobar' }    
47     
48     package Foo::Bar::Baz;
49     our @ISA = ('Foo', 'Bar', 'Baz');
50     
51     sub BUILD { 'Foo::Bar::Baz::BUILD' }    
52     sub bar { 'Foo::Bar::Baz::bar' }    
53     sub foobarbaz { 'Foo::Bar::Baz::foobarbaz' }    
54 }
55
56 ok(!defined(Class::MOP::Class->initialize('Foo')->find_next_method_by_name('BUILD')), 
57    '... Foo::BUILD has not next method');
58
59 is(Class::MOP::Class->initialize('Bar')->find_next_method_by_name('BUILD'), 
60    Class::MOP::Class->initialize('Foo')->get_method('BUILD'),     
61    '... Bar::BUILD does have a next method');
62    
63 is(Class::MOP::Class->initialize('Baz')->find_next_method_by_name('BUILD'), 
64    Class::MOP::Class->initialize('Bar')->get_method('BUILD'),     
65    '... Baz->BUILD does have a next method');   
66    
67 is(Class::MOP::Class->initialize('Foo::Bar')->find_next_method_by_name('BUILD'), 
68    Class::MOP::Class->initialize('Foo')->get_method('BUILD'),     
69    '... Foo::Bar->BUILD does have a next method');   
70    
71 is(Class::MOP::Class->initialize('Foo::Bar::Baz')->find_next_method_by_name('BUILD'), 
72    Class::MOP::Class->initialize('Foo')->get_method('BUILD'),     
73    '... Foo::Bar::Baz->BUILD does have a next method');   
74
75 is_deeply(
76     [ sort { $a->{name} cmp $b->{name} } Class::MOP::Class->initialize('Foo')->compute_all_applicable_methods() ],
77     [
78         {
79             name  => 'BUILD',
80             class => 'Foo',
81             code  => \&Foo::BUILD 
82         },    
83         {
84             name  => 'foo',
85             class => 'Foo',
86             code  => \&Foo::foo 
87         },       
88     ],
89     '... got the right list of applicable methods for Foo');
90     
91 is_deeply(
92     [ sort { $a->{name} cmp $b->{name} } Class::MOP::Class->initialize('Bar')->compute_all_applicable_methods() ],
93     [
94         {
95             name  => 'BUILD',
96             class => 'Bar',
97             code  => \&Bar::BUILD 
98         },    
99         {
100             name  => 'bar',
101             class => 'Bar',
102             code  => \&Bar::bar  
103         },
104         {
105             name  => 'foo',
106             class => 'Foo',
107             code  => \&Foo::foo  
108         },       
109     ],
110     '... got the right list of applicable methods for Bar');
111     
112
113 is_deeply(
114     [ sort { $a->{name} cmp $b->{name} } Class::MOP::Class->initialize('Baz')->compute_all_applicable_methods() ],
115     [   
116         {
117             name  => 'BUILD',
118             class => 'Bar',
119             code  => \&Bar::BUILD 
120         },    
121         {
122             name  => 'bar',
123             class => 'Bar',
124             code  => \&Bar::bar  
125         },
126         {
127             name  => 'baz',
128             class => 'Baz',
129             code  => \&Baz::baz  
130         },        
131         {
132             name  => 'foo',
133             class => 'Baz',
134             code  => \&Baz::foo  
135         },       
136     ],
137     '... got the right list of applicable methods for Baz');
138
139 is_deeply(
140     [ sort { $a->{name} cmp $b->{name} } Class::MOP::Class->initialize('Foo::Bar')->compute_all_applicable_methods() ],
141     [
142         {
143             name  => 'BUILD',
144             class => 'Foo::Bar',
145             code  => \&Foo::Bar::BUILD 
146         },    
147         {
148             name  => 'bar',
149             class => 'Bar',
150             code  => \&Bar::bar  
151         },
152         {
153             name  => 'foo',
154             class => 'Foo',
155             code  => \&Foo::foo  
156         },       
157         {
158             name  => 'foobar',
159             class => 'Foo::Bar',
160             code  => \&Foo::Bar::foobar  
161         },        
162     ],
163     '... got the right list of applicable methods for Foo::Bar');
164
165 is_deeply(
166     [ sort { $a->{name} cmp $b->{name} } Class::MOP::Class->initialize('Foo::Bar::Baz')->compute_all_applicable_methods() ],
167     [
168         {
169             name  => 'BUILD',
170             class => 'Foo::Bar::Baz',
171             code  => \&Foo::Bar::Baz::BUILD 
172         },    
173         {
174             name  => 'bar',
175             class => 'Foo::Bar::Baz',
176             code  => \&Foo::Bar::Baz::bar  
177         },
178         {
179             name  => 'baz',
180             class => 'Baz',
181             code  => \&Baz::baz  
182         },        
183         {
184             name  => 'foo',
185             class => 'Foo',
186             code  => \&Foo::foo  
187         },   
188         {
189             name  => 'foobarbaz',
190             class => 'Foo::Bar::Baz',
191             code  => \&Foo::Bar::Baz::foobarbaz  
192         },            
193     ],
194     '... got the right list of applicable methods for Foo::Bar::Baz');
195
196 ## find_all_methods_by_name
197
198 is_deeply(
199     [ Class::MOP::Class->initialize('Foo::Bar')->find_all_methods_by_name('BUILD') ],
200     [
201         {
202             name  => 'BUILD',
203             class => 'Foo::Bar',
204             code  => \&Foo::Bar::BUILD 
205         },    
206         {
207             name  => 'BUILD',
208             class => 'Foo',
209             code  => \&Foo::BUILD 
210         },    
211         {
212             name  => 'BUILD',
213             class => 'Bar',
214             code  => \&Bar::BUILD 
215         }
216     ],
217     '... got the right list of BUILD methods for Foo::Bar');
218
219 is_deeply(
220     [ Class::MOP::Class->initialize('Foo::Bar::Baz')->find_all_methods_by_name('BUILD') ],
221     [
222         {
223             name  => 'BUILD',
224             class => 'Foo::Bar::Baz',
225             code  => \&Foo::Bar::Baz::BUILD 
226         },    
227         {
228             name  => 'BUILD',
229             class => 'Foo',
230             code  => \&Foo::BUILD 
231         },    
232         {
233             name  => 'BUILD',
234             class => 'Bar',
235             code  => \&Bar::BUILD 
236         },            
237     ],
238     '... got the right list of BUILD methods for Foo::Bar::Baz');