Commit | Line | Data |
0558683c |
1 | #!/usr/bin/perl |
2 | |
3 | use strict; |
4 | use warnings; |
5 | |
825a80de |
6 | use Test::More tests => 18; |
0558683c |
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 | } |
825a80de |
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'; |
0558683c |
212 | |
825a80de |
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 | |