foo
[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 => 15;
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 }
31
32 =begin nonsense
33     package Role::ProvideFoo;
34     use strict;
35     use warnings;
36     use Moose::Role;
37     
38     ::lives_ok {
39         with 'Role::RequireFoo';
40     } '... the required "foo" method will not exist yet (but we will live)';
41     
42     override 'foo' => sub { 'Role::ProvideFoo::foo' };    
43 }
44
45 is_deeply(
46     [ Role::ProvideFoo->meta->get_required_method_list ], 
47     [ 'foo' ], 
48     '... foo method is still required for Role::ProvideFoo');
49
50 =cut
51
52 =pod
53
54 Role which requires a method implemented 
55 in the consuming class as an override. 
56 It will fail since method modifiers are 
57 second class citizens.
58
59 =cut
60
61 {
62     package Class::ProvideFoo::Base;
63     use Moose;
64
65     sub foo { 'Class::ProvideFoo::Base::foo' }
66         
67     package Class::ProvideFoo::Override1;
68     use Moose;
69     
70     extends 'Class::ProvideFoo::Base';
71     
72     ::dies_ok {
73         with 'Role::RequireFoo';
74     } '... the required "foo" method will not exist yet (and we will die)';
75     
76     override 'foo' => sub { 'Class::ProvideFoo::foo' };    
77     
78     package Class::ProvideFoo::Override2;
79     use Moose;
80     
81     extends 'Class::ProvideFoo::Base';
82     
83     override 'foo' => sub { 'Class::ProvideFoo::foo' };     
84     
85     ::dies_ok {
86         with 'Role::RequireFoo';
87     } '... the required "foo" method exists, but it is an override (and we will die)';
88
89 }
90
91 =pod
92
93 Now same thing, but with a before 
94 method modifier.
95
96 =cut
97
98 {
99     package Class::ProvideFoo::Before1;
100     use Moose;
101     
102     extends 'Class::ProvideFoo::Base';
103     
104     ::dies_ok {
105         with 'Role::RequireFoo';
106     } '... the required "foo" method will not exist yet (and we will die)';
107     
108     before 'foo' => sub { 'Class::ProvideFoo::foo:before' };    
109     
110     package Class::ProvideFoo::Before2;
111     use Moose;
112     
113     extends 'Class::ProvideFoo::Base';
114     
115     before 'foo' => sub { 'Class::ProvideFoo::foo:before' };     
116     
117     ::dies_ok {
118         with 'Role::RequireFoo';
119     } '... the required "foo" method exists, but it is a before (and we will die)';    
120     
121     package Class::ProvideFoo::Before3;
122     use Moose;
123     
124     extends 'Class::ProvideFoo::Base';
125     
126     ::lives_ok {
127         with 'Role::RequireFoo';
128     } '... the required "foo" method will not exist yet (and we will die)';
129     
130     sub foo { 'Class::ProvideFoo::foo' }
131     before 'foo' => sub { 'Class::ProvideFoo::foo:before' };    
132     
133     package Class::ProvideFoo::Before4;
134     use Moose;
135     
136     extends 'Class::ProvideFoo::Base';
137     
138     sub foo { 'Class::ProvideFoo::foo' }    
139     before 'foo' => sub { 'Class::ProvideFoo::foo:before' };     
140
141     ::isa_ok(__PACKAGE__->meta->get_method('foo'), 'Class::MOP::Method::Wrapped');
142     ::is(__PACKAGE__->meta->get_method('foo')->get_original_method->package_name, __PACKAGE__, 
143     '... but the original method is from our package');
144     
145     ::lives_ok {
146         with 'Role::RequireFoo';
147     } '... the required "foo" method exists in the symbol table (and we will live)'; 
148     
149     package Class::ProvideFoo::Before5;
150     use Moose;
151     
152     extends 'Class::ProvideFoo::Base';
153        
154     before 'foo' => sub { 'Class::ProvideFoo::foo:before' };   
155     
156     ::isa_ok(__PACKAGE__->meta->get_method('foo'), 'Class::MOP::Method::Wrapped');
157     ::isnt(__PACKAGE__->meta->get_method('foo')->get_original_method->package_name, __PACKAGE__, 
158     '... but the original method is not from our package');      
159     
160     ::dies_ok {
161         with 'Role::RequireFoo';
162     } '... the required "foo" method exists, but it is a before wrapping the super (and we will die)';       
163 }    
164
165 =pod
166
167 Now same thing, but with a method from an attribute
168 method modifier.
169
170 =cut
171
172 {
173     
174     package Class::ProvideFoo::Attr1;
175     use Moose;
176     
177     extends 'Class::ProvideFoo::Base';
178     
179     ::dies_ok {
180         with 'Role::RequireFoo';
181     } '... the required "foo" method will not exist yet (and we will die)';
182     
183     has 'foo' => (is => 'ro');
184     
185     package Class::ProvideFoo::Attr2;
186     use Moose;
187     
188     extends 'Class::ProvideFoo::Base';
189     
190     has 'foo' => (is => 'ro');     
191     
192     ::dies_ok {
193         with 'Role::RequireFoo';
194     } '... the required "foo" method exists, but it is a before (and we will die)';    
195 }    
196     
197