Changelogging
[gitmo/Mouse.git] / t-failing / 030_roles / 007_roles_and_req_method_edge_cases.t
1 #!/usr/bin/perl
2 # This is automatically generated by author/import-moose-test.pl.
3 # DO NOT EDIT THIS FILE. ANY CHANGES WILL BE LOST!!!
4 use t::lib::MooseCompat;
5
6 use strict;
7 use warnings;
8
9 use Test::More;
10 $TODO = q{Mouse is not yet completed};
11 use Test::Exception;
12
13 =pod
14
15 NOTE:
16 A fair amount of these tests will likely be irrelevant
17 once we have more fine grained control over the class
18 building process. A lot of the edge cases tested here
19 are actually related to class construction order and
20 not any real functionality.
21 - SL
22
23 Role which requires a method implemented
24 in another role as an override (it does
25 not remove the requirement)
26
27 =cut
28
29 {
30     package Role::RequireFoo;
31     use strict;
32     use warnings;
33     use Mouse::Role;
34
35     requires 'foo';
36
37     package Role::ProvideFoo;
38     use strict;
39     use warnings;
40     use Mouse::Role;
41
42     ::lives_ok {
43         with 'Role::RequireFoo';
44     } '... the required "foo" method will not exist yet (but we will live)';
45
46     override 'foo' => sub { 'Role::ProvideFoo::foo' };
47 }
48
49 is_deeply(
50     [ Role::ProvideFoo->meta->get_required_method_list ],
51     [ 'foo' ],
52     '... foo method is still required for Role::ProvideFoo');
53
54 =pod
55
56 Role which requires a method implemented
57 in the consuming class as an override.
58 It will fail since method modifiers are
59 second class citizens.
60
61 =cut
62
63 {
64     package Class::ProvideFoo::Base;
65     use Mouse;
66
67     sub foo { 'Class::ProvideFoo::Base::foo' }
68
69     package Class::ProvideFoo::Override1;
70     use Mouse;
71
72     extends 'Class::ProvideFoo::Base';
73
74     ::lives_ok {
75         with 'Role::RequireFoo';
76     } '... the required "foo" method will be found in the superclass';
77
78     override 'foo' => sub { 'Class::ProvideFoo::foo' };
79
80     package Class::ProvideFoo::Override2;
81     use Mouse;
82
83     extends 'Class::ProvideFoo::Base';
84
85     override 'foo' => sub { 'Class::ProvideFoo::foo' };
86
87     ::lives_ok {
88         with 'Role::RequireFoo';
89     } '... the required "foo" method exists, although it is overriden locally';
90
91 }
92
93 =pod
94
95 Now same thing, but with a before
96 method modifier.
97
98 =cut
99
100 {
101     package Class::ProvideFoo::Before1;
102     use Mouse;
103
104     extends 'Class::ProvideFoo::Base';
105
106     ::lives_ok {
107         with 'Role::RequireFoo';
108     } '... the required "foo" method will be found in the superclass';
109
110     before 'foo' => sub { 'Class::ProvideFoo::foo:before' };
111
112     package Class::ProvideFoo::Before2;
113     use Mouse;
114
115     extends 'Class::ProvideFoo::Base';
116
117     before 'foo' => sub { 'Class::ProvideFoo::foo:before' };
118
119     ::lives_ok {
120         with 'Role::RequireFoo';
121     } '... the required "foo" method exists, although it is a before modifier locally';
122
123     package Class::ProvideFoo::Before3;
124     use Mouse;
125
126     extends 'Class::ProvideFoo::Base';
127
128     sub foo { 'Class::ProvideFoo::foo' }
129     before 'foo' => sub { 'Class::ProvideFoo::foo:before' };
130
131     ::lives_ok {
132         with 'Role::RequireFoo';
133     } '... the required "foo" method exists locally, and it is modified locally';
134
135     package Class::ProvideFoo::Before4;
136     use Mouse;
137
138     extends 'Class::ProvideFoo::Base';
139
140     sub foo { 'Class::ProvideFoo::foo' }
141     before 'foo' => sub { 'Class::ProvideFoo::foo:before' };
142
143     ::isa_ok(__PACKAGE__->meta->get_method('foo'), 'Mouse::Meta::Method');
144     ::is(__PACKAGE__->meta->get_method('foo')->get_original_method->package_name, __PACKAGE__,
145     '... but the original method is from our package');
146
147     ::lives_ok {
148         with 'Role::RequireFoo';
149     } '... the required "foo" method exists in the symbol table (and we will live)';
150
151 }
152
153 =pod
154
155 Now same thing, but with a method from an attribute
156 method modifier.
157
158 =cut
159
160 {
161
162     package Class::ProvideFoo::Attr1;
163     use Mouse;
164
165     extends 'Class::ProvideFoo::Base';
166
167     ::lives_ok {
168         with 'Role::RequireFoo';
169     } '... the required "foo" method will be found in the superclass (but then overriden)';
170
171     has 'foo' => (is => 'ro');
172
173     package Class::ProvideFoo::Attr2;
174     use Mouse;
175
176     extends 'Class::ProvideFoo::Base';
177
178     has 'foo' => (is => 'ro');
179
180     ::lives_ok {
181         with 'Role::RequireFoo';
182     } '... the required "foo" method exists, and is an accessor';
183 }
184
185 # ...
186 # a method required in a role, but then
187 # implemented in the superclass (as an
188 # attribute accessor too)
189
190 {
191     package Foo::Class::Base;
192     use Mouse;
193
194     has 'bar' =>  (
195         isa     => 'Int',
196         is      => 'rw',
197         default => sub { 1 }
198     );
199 }
200 {
201     package Foo::Role;
202     use Mouse::Role;
203
204     requires 'bar';
205
206     has 'foo' => (
207         isa     => 'Int',
208         is      => 'rw',
209         lazy    => 1,
210         default => sub { (shift)->bar + 1 }
211     );
212 }
213 {
214     package Foo::Class::Child;
215     use Mouse;
216     extends 'Foo::Class::Base';
217
218     ::lives_ok {
219         with 'Foo::Role';
220     } '... our role combined successfully';
221 }
222
223 # a method required in a role and implemented in a superclass, with a method
224 # modifier in the subclass.  this should live, but dies in 0.26 -- hdp,
225 # 2007-10-11
226
227 {
228     package Bar::Class::Base;
229     use Mouse;
230
231     sub bar { "hello!" }
232 }
233 {
234     package Bar::Role;
235     use Mouse::Role;
236     requires 'bar';
237 }
238 {
239     package Bar::Class::Child;
240     use Mouse;
241     extends 'Bar::Class::Base';
242     after bar => sub { "o noes" };
243     # technically we could run lives_ok here, too, but putting it into a
244     # grandchild class makes it more obvious why this matters.
245 }
246 {
247     package Bar::Class::Grandchild;
248     use Mouse;
249     extends 'Bar::Class::Child';
250     ::lives_ok {
251         with 'Bar::Role';
252     } 'required method exists in superclass as non-modifier, so we live';
253 }
254
255 {
256     package Bar2::Class::Base;
257     use Mouse;
258
259     sub bar { "hello!" }
260 }
261 {
262     package Bar2::Role;
263     use Mouse::Role;
264     requires 'bar';
265 }
266 {
267     package Bar2::Class::Child;
268     use Mouse;
269     extends 'Bar2::Class::Base';
270     override bar => sub { "o noes" };
271     # technically we could run lives_ok here, too, but putting it into a
272     # grandchild class makes it more obvious why this matters.
273 }
274 {
275     package Bar2::Class::Grandchild;
276     use Mouse;
277     extends 'Bar2::Class::Child';
278     ::lives_ok {
279         with 'Bar2::Role';
280     } 'required method exists in superclass as non-modifier, so we live';
281 }
282
283 done_testing;