Implemented Mouse::Role->does; modified Mouse::Meta::Class->initialise
[gitmo/Mouse.git] / t / 030_roles / failing / 011_overriding.t
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use Test::More tests => 39;
7 use Test::Exception;
8
9
10
11
12     # test no conflicts here
13     package Role::A;
14     use Mouse::Role;
15
16     sub bar { 'Role::A::bar' }
17
18     package Role::B;
19     use Mouse::Role;
20
21     sub xxy { 'Role::B::xxy' }
22
23     package Role::C;
24     use Mouse::Role;
25     
26     ::lives_ok {
27         with qw(Role::A Role::B); # no conflict here
28     } "define role C";
29
30     sub foo { 'Role::C::foo' }
31     sub zot { 'Role::C::zot' }
32
33     package Class::A;
34     use Mouse;
35
36     ::lives_ok {
37         with qw(Role::C);
38     } "define class A";
39     
40     sub zot { 'Class::A::zot' }
41 }
42
43 can_ok( Class::A->new, qw(foo bar xxy zot) );
44
45 is( Class::A->new->foo, "Role::C::foo",  "... got the right foo method" );
46 is( Class::A->new->zot, "Class::A::zot", "... got the right zot method" );
47 is( Class::A->new->bar, "Role::A::bar",  "... got the right bar method" );
48 is( Class::A->new->xxy, "Role::B::xxy",  "... got the right xxy method" );
49
50 {
51     # check that when a role is added to another role
52     # and they conflict and the method they conflicted
53     # with is then required. 
54     
55     package Role::A::Conflict;
56     use Mouse::Role;
57     
58     with 'Role::A';
59     
60     sub bar { 'Role::A::Conflict::bar' }
61     
62     package Class::A::Conflict;
63     use Mouse;
64     
65     ::throws_ok {
66         with 'Role::A::Conflict';
67     }  qr/requires.*'bar'/, '... did not fufill the requirement of &bar method';
68     
69     package Class::A::Resolved;
70     use Mouse;
71     
72     ::lives_ok {
73         with 'Role::A::Conflict';
74     } '... did fufill the requirement of &bar method';    
75     
76     sub bar { 'Class::A::Resolved::bar' }
77 }
78
79 ok(Role::A::Conflict->meta->requires_method('bar'), '... Role::A::Conflict created the bar requirement');
80
81 can_ok( Class::A::Resolved->new, qw(bar) );
82
83 is( Class::A::Resolved->new->bar, 'Class::A::Resolved::bar', "... got the right bar method" );
84
85 {
86     # check that when two roles are composed, they conflict
87     # but the composing role can resolve that conflict
88     
89     package Role::D;
90     use Mouse::Role;
91
92     sub foo { 'Role::D::foo' }
93     sub bar { 'Role::D::bar' }    
94
95     package Role::E;
96     use Mouse::Role;
97
98     sub foo { 'Role::E::foo' }
99     sub xxy { 'Role::E::xxy' }
100
101     package Role::F;
102     use Mouse::Role;
103
104     ::lives_ok {
105         with qw(Role::D Role::E); # conflict between 'foo's here
106     } "define role Role::F";
107     
108     sub foo { 'Role::F::foo' }
109     sub zot { 'Role::F::zot' }    
110     
111     package Class::B;
112     use Mouse;
113     
114     ::lives_ok {
115         with qw(Role::F);
116     } "define class Class::B";
117     
118     sub zot { 'Class::B::zot' }
119 }
120
121 can_ok( Class::B->new, qw(foo bar xxy zot) );
122
123 is( Class::B->new->foo, "Role::F::foo",  "... got the &foo method okay" );
124 is( Class::B->new->zot, "Class::B::zot", "... got the &zot method okay" );
125 is( Class::B->new->bar, "Role::D::bar",  "... got the &bar method okay" );
126 is( Class::B->new->xxy, "Role::E::xxy",  "... got the &xxy method okay" );
127
128 ok(!Role::F->meta->requires_method('foo'), '... Role::F fufilled the &foo requirement');
129
130 {
131     # check that a conflict can be resolved
132     # by a role, but also new ones can be 
133     # created just as easily ...
134     
135     package Role::D::And::E::Conflict;
136     use Mouse::Role;
137
138     ::lives_ok {
139         with qw(Role::D Role::E); # conflict between 'foo's here
140     } "... define role Role::D::And::E::Conflict";
141     
142     sub foo { 'Role::D::And::E::Conflict::foo' }  # this overrides ...
143       
144     # but these conflict      
145     sub xxy { 'Role::D::And::E::Conflict::xxy' }  
146     sub bar { 'Role::D::And::E::Conflict::bar' }        
147
148 }
149
150 ok(!Role::D::And::E::Conflict->meta->requires_method('foo'), '... Role::D::And::E::Conflict fufilled the &foo requirement');
151 ok(Role::D::And::E::Conflict->meta->requires_method('xxy'), '... Role::D::And::E::Conflict adds the &xxy requirement');
152 ok(Role::D::And::E::Conflict->meta->requires_method('bar'), '... Role::D::And::E::Conflict adds the &bar requirement');
153
154 {
155     # conflict propagation
156     
157     package Role::H;
158     use Mouse::Role;
159
160     sub foo { 'Role::H::foo' }
161     sub bar { 'Role::H::bar' }    
162
163     package Role::J;
164     use Mouse::Role;
165
166     sub foo { 'Role::J::foo' }
167     sub xxy { 'Role::J::xxy' }
168
169     package Role::I;
170     use Mouse::Role;
171
172     ::lives_ok {
173         with qw(Role::J Role::H); # conflict between 'foo's here
174     } "define role Role::I";
175     
176     sub zot { 'Role::I::zot' }
177     sub zzy { 'Role::I::zzy' }
178
179     package Class::C;
180     use Mouse;
181     
182     ::throws_ok {
183         with qw(Role::I);
184     } qr/requires.*'foo'/, "defining class Class::C fails";
185
186     sub zot { 'Class::C::zot' }
187
188     package Class::E;
189     use Mouse;
190
191     ::lives_ok {
192         with qw(Role::I);
193     } "resolved with method";        
194
195     sub foo { 'Class::E::foo' }
196     sub zot { 'Class::E::zot' }    
197 }
198
199 can_ok( Class::E->new, qw(foo bar xxy zot) );
200
201 is( Class::E->new->foo, "Class::E::foo", "... got the right &foo method" );
202 is( Class::E->new->zot, "Class::E::zot", "... got the right &zot method" );
203 is( Class::E->new->bar, "Role::H::bar",  "... got the right &bar method" );
204 is( Class::E->new->xxy, "Role::J::xxy",  "... got the right &xxy method" );
205
206 ok(Role::I->meta->requires_method('foo'), '... Role::I still have the &foo requirement');
207
208 {
209     lives_ok {
210         package Class::D;
211         use Mouse;
212
213         has foo => ( default => __PACKAGE__ . "::foo", is => "rw" );
214
215         sub zot { 'Class::D::zot' }
216
217         with qw(Role::I);
218
219     } "resolved with attr";
220
221     can_ok( Class::D->new, qw(foo bar xxy zot) );
222     is( eval { Class::D->new->bar }, "Role::H::bar", "bar" );
223     is( eval { Class::D->new->zzy }, "Role::I::zzy", "zzy" );
224
225     is( eval { Class::D->new->foo }, "Class::D::foo", "foo" );
226     is( eval { Class::D->new->zot }, "Class::D::zot", "zot" );
227
228 }
229