this is broken, we need to fix it
[gitmo/Moose.git] / t / 046_roles_and_required_method_edge_cases.t
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use Test::More tests => 18;
7 use Test::Exception;
8
9 BEGIN {
10     use_ok('Moose');
11     use_ok('Moose::Role');    
12 }
13
14 =pod
15
16 Role which requires a method implemented 
17 in another role as an override (it does 
18 not remove the requirement)
19
20 =cut
21
22 {
23     package Role::RequireFoo;
24     use strict;
25     use warnings;
26     use Moose::Role;
27     
28     requires 'foo';
29     
30     package Role::ProvideFoo;
31     use strict;
32     use warnings;
33     use Moose::Role;
34     
35     ::lives_ok {
36         with 'Role::RequireFoo';
37     } '... the required "foo" method will not exist yet (but we will live)';
38     
39     override 'foo' => sub { 'Role::ProvideFoo::foo' };    
40 }
41
42 is_deeply(
43     [ Role::ProvideFoo->meta->get_required_method_list ], 
44     [ 'foo' ], 
45     '... foo method is still required for Role::ProvideFoo');
46
47 =pod
48
49 Role which requires a method implemented 
50 in the consuming class as an override. 
51 It will fail since method modifiers are 
52 second class citizens.
53
54 =cut
55
56 {
57     package Class::ProvideFoo::Base;
58     use Moose;
59
60     sub foo { 'Class::ProvideFoo::Base::foo' }
61         
62     package Class::ProvideFoo::Override1;
63     use Moose;
64     
65     extends 'Class::ProvideFoo::Base';
66     
67     ::dies_ok {
68         with 'Role::RequireFoo';
69     } '... the required "foo" method will not exist yet (and we will die)';
70     
71     override 'foo' => sub { 'Class::ProvideFoo::foo' };    
72     
73     package Class::ProvideFoo::Override2;
74     use Moose;
75     
76     extends 'Class::ProvideFoo::Base';
77     
78     override 'foo' => sub { 'Class::ProvideFoo::foo' };     
79     
80     ::dies_ok {
81         with 'Role::RequireFoo';
82     } '... the required "foo" method exists, but it is an override (and we will die)';
83
84 }
85
86 =pod
87
88 Now same thing, but with a before 
89 method modifier.
90
91 =cut
92
93 {
94     package Class::ProvideFoo::Before1;
95     use Moose;
96     
97     extends 'Class::ProvideFoo::Base';
98     
99     ::dies_ok {
100         with 'Role::RequireFoo';
101     } '... the required "foo" method will not exist yet (and we will die)';
102     
103     before 'foo' => sub { 'Class::ProvideFoo::foo:before' };    
104     
105     package Class::ProvideFoo::Before2;
106     use Moose;
107     
108     extends 'Class::ProvideFoo::Base';
109     
110     before 'foo' => sub { 'Class::ProvideFoo::foo:before' };     
111     
112     ::dies_ok {
113         with 'Role::RequireFoo';
114     } '... the required "foo" method exists, but it is a before (and we will die)';    
115     
116     package Class::ProvideFoo::Before3;
117     use Moose;
118     
119     extends 'Class::ProvideFoo::Base';
120     
121     ::lives_ok {
122         with 'Role::RequireFoo';
123     } '... the required "foo" method will not exist yet (and we will die)';
124     
125     sub foo { 'Class::ProvideFoo::foo' }
126     before 'foo' => sub { 'Class::ProvideFoo::foo:before' };    
127     
128     package Class::ProvideFoo::Before4;
129     use Moose;
130     
131     extends 'Class::ProvideFoo::Base';
132     
133     sub foo { 'Class::ProvideFoo::foo' }    
134     before 'foo' => sub { 'Class::ProvideFoo::foo:before' };     
135
136     ::isa_ok(__PACKAGE__->meta->get_method('foo'), 'Class::MOP::Method::Wrapped');
137     ::is(__PACKAGE__->meta->get_method('foo')->get_original_method->package_name, __PACKAGE__, 
138     '... but the original method is from our package');
139     
140     ::lives_ok {
141         with 'Role::RequireFoo';
142     } '... the required "foo" method exists in the symbol table (and we will live)'; 
143     
144     package Class::ProvideFoo::Before5;
145     use Moose;
146     
147     extends 'Class::ProvideFoo::Base';
148        
149     before 'foo' => sub { 'Class::ProvideFoo::foo:before' };   
150     
151     ::isa_ok(__PACKAGE__->meta->get_method('foo'), 'Class::MOP::Method::Wrapped');
152     ::isnt(__PACKAGE__->meta->get_method('foo')->get_original_method->package_name, __PACKAGE__, 
153     '... but the original method is not from our package');      
154     
155     ::dies_ok {
156         with 'Role::RequireFoo';
157     } '... the required "foo" method exists, but it is a before wrapping the super (and we will die)';       
158 }    
159
160 =pod
161
162 Now same thing, but with a method from an attribute
163 method modifier.
164
165 =cut
166
167 {
168     
169     package Class::ProvideFoo::Attr1;
170     use Moose;
171     
172     extends 'Class::ProvideFoo::Base';
173     
174     ::dies_ok {
175         with 'Role::RequireFoo';
176     } '... the required "foo" method will not exist yet (and we will die)';
177     
178     has 'foo' => (is => 'ro');
179     
180     package Class::ProvideFoo::Attr2;
181     use Moose;
182     
183     extends 'Class::ProvideFoo::Base';
184     
185     has 'foo' => (is => 'ro');     
186     
187     ::dies_ok {
188         with 'Role::RequireFoo';
189     } '... the required "foo" method exists, but it is a before (and we will die)';    
190 }    
191
192 # ...
193 # a method required in a role, but then 
194 # implemented in the superclass (as an 
195 # attribute accessor too)
196     
197 {
198     package Foo::Class::Base;
199     use Moose;
200     
201     has 'bar' =>  ( 
202         isa     => 'Int', 
203         is      => 'rw', 
204         default => sub { 1 }
205     );
206 }
207 {
208     package Foo::Role;
209     use Moose::Role;
210     
211     requires 'bar';
212     
213     has 'foo' => ( 
214         isa     => 'Int', 
215         is      => 'rw', 
216         lazy    => 1, 
217         default => sub { (shift)->bar + 1 } 
218     );
219 }
220 {
221     package Foo::Class::Child;
222     use Moose;
223     extends 'Foo::Class::Base';
224     
225     ::dies_ok {       
226         with 'Foo::Role';
227     } '... our role combined successfully';
228 }
229
230
231