add some more tests (including some TODOs)
[gitmo/Moose.git] / t / 050_metaclasses / 060_reinitialize.t
1 #!/usr/bin/env perl
2 use strict;
3 use warnings;
4 use Test::More;
5 use Test::Moose;
6 use Test::Exception;
7
8 sub check_meta_sanity {
9     my ($meta, $class) = @_;
10     local $Test::Builder::Level = $Test::Builder::Level + 1;
11     isa_ok($meta, 'Moose::Meta::Class');
12     is($meta->name, $class);
13     ok($meta->has_method('foo'));
14     isa_ok($meta->get_method('foo'), 'Moose::Meta::Method');
15     ok($meta->has_attribute('bar'));
16     isa_ok($meta->get_attribute('bar'), 'Moose::Meta::Attribute');
17 }
18
19 {
20     package Foo;
21     use Moose;
22     sub foo {}
23     has bar => (is => 'ro');
24 }
25
26 check_meta_sanity(Foo->meta, 'Foo');
27
28 Moose::Meta::Class->reinitialize('Foo');
29 check_meta_sanity(Foo->meta, 'Foo');
30
31 {
32     package Foo::Role::Method;
33     use Moose::Role;
34
35     has foo => (is => 'rw');
36 }
37
38 {
39     package Foo::Role::Attribute;
40     use Moose::Role;
41     has oof => (is => 'rw');
42 }
43
44 Moose::Util::MetaRole::apply_metaroles(
45     for => 'Foo',
46     class_metaroles => {
47         method    => ['Foo::Role::Method'],
48         attribute => ['Foo::Role::Attribute'],
49     },
50 );
51 check_meta_sanity(Foo->meta, 'Foo');
52 does_ok(Foo->meta->get_method('foo'), 'Foo::Role::Method');
53 does_ok(Foo->meta->get_attribute('bar'), 'Foo::Role::Attribute');
54
55 Moose::Meta::Class->reinitialize('Foo');
56 check_meta_sanity(Foo->meta, 'Foo');
57 does_ok(Foo->meta->get_method('foo'), 'Foo::Role::Method');
58 does_ok(Foo->meta->get_attribute('bar'), 'Foo::Role::Attribute');
59
60 Foo->meta->get_method('foo')->foo('TEST');
61 Foo->meta->get_attribute('bar')->oof('TSET');
62 is(Foo->meta->get_method('foo')->foo, 'TEST');
63 is(Foo->meta->get_attribute('bar')->oof, 'TSET');
64 Moose::Meta::Class->reinitialize('Foo');
65 check_meta_sanity(Foo->meta, 'Foo');
66 is(Foo->meta->get_method('foo')->foo, 'TEST');
67 is(Foo->meta->get_attribute('bar')->oof, 'TSET');
68
69 {
70     package Bar::Role::Method;
71     use Moose::Role;
72 }
73
74 {
75     package Bar::Role::Attribute;
76     use Moose::Role;
77 }
78
79 {
80     package Bar;
81     use Moose;
82     Moose::Util::MetaRole::apply_metaroles(
83         for => 'Bar',
84         class_metaroles => {
85             method    => ['Bar::Role::Method'],
86             attribute => ['Bar::Role::Attribute'],
87         },
88     );
89     sub foo {}
90     has bar => (is => 'ro');
91 }
92
93 check_meta_sanity(Bar->meta, 'Bar');
94 does_ok(Bar->meta->get_method('foo'), 'Bar::Role::Method');
95 does_ok(Bar->meta->get_attribute('bar'), 'Bar::Role::Attribute');
96
97 Moose::Meta::Class->reinitialize('Bar');
98 check_meta_sanity(Bar->meta, 'Bar');
99 does_ok(Bar->meta->get_method('foo'), 'Bar::Role::Method');
100 does_ok(Bar->meta->get_attribute('bar'), 'Bar::Role::Attribute');
101 ok(!Moose::Util::does_role(Bar->meta->get_method('foo'), 'Foo::Role::Method'));
102 ok(!Moose::Util::does_role(Bar->meta->get_attribute('bar'), 'Foo::Role::Attribute'));
103
104 Moose::Util::MetaRole::apply_metaroles(
105     for => 'Bar',
106     class_metaroles => {
107         method    => ['Foo::Role::Method'],
108         attribute => ['Foo::Role::Attribute'],
109     },
110 );
111 check_meta_sanity(Bar->meta, 'Bar');
112 does_ok(Bar->meta->get_method('foo'), 'Bar::Role::Method');
113 does_ok(Bar->meta->get_attribute('bar'), 'Bar::Role::Attribute');
114 does_ok(Bar->meta->get_method('foo'), 'Foo::Role::Method');
115 does_ok(Bar->meta->get_attribute('bar'), 'Foo::Role::Attribute');
116
117 {
118     package Bar::Meta::Method;
119     use Moose;
120     BEGIN { extends 'Moose::Meta::Method' };
121 }
122
123 {
124     package Bar::Meta::Attribute;
125     use Moose;
126     BEGIN { extends 'Moose::Meta::Attribute' };
127 }
128
129 throws_ok {
130     Moose::Meta::Class->reinitialize(
131         'Bar',
132         method_metaclass    => 'Bar::Meta::Method',
133         attribute_metaclass => 'Bar::Meta::Attribute',
134     );
135 } qr/compatible/;
136
137 {
138     package Baz::Meta::Class;
139     use Moose;
140     BEGIN { extends 'Moose::Meta::Class' };
141
142     sub initialize {
143         my $self = shift;
144         return $self->SUPER::initialize(
145             @_,
146             method_metaclass    => 'Bar::Meta::Method',
147             attribute_metaclass => 'Bar::Meta::Attribute'
148         );
149     }
150 }
151
152 {
153     package Baz;
154     use Moose -metaclass => 'Baz::Meta::Class';
155     sub foo {}
156     has bar => (is => 'ro');
157 }
158
159 check_meta_sanity(Baz->meta, 'Baz');
160 isa_ok(Baz->meta->get_method('foo'), 'Bar::Meta::Method');
161 isa_ok(Baz->meta->get_attribute('bar'), 'Bar::Meta::Attribute');
162 Moose::Meta::Class->reinitialize('Baz');
163 check_meta_sanity(Baz->meta, 'Baz');
164 isa_ok(Baz->meta->get_method('foo'), 'Bar::Meta::Method');
165 isa_ok(Baz->meta->get_attribute('bar'), 'Bar::Meta::Attribute');
166
167 Moose::Util::MetaRole::apply_metaroles(
168     for => 'Baz',
169     class_metaroles => {
170         method    => ['Foo::Role::Method'],
171         attribute => ['Foo::Role::Attribute'],
172     },
173 );
174 check_meta_sanity(Baz->meta, 'Baz');
175 isa_ok(Baz->meta->get_method('foo'), 'Bar::Meta::Method');
176 isa_ok(Baz->meta->get_attribute('bar'), 'Bar::Meta::Attribute');
177 does_ok(Baz->meta->get_method('foo'), 'Foo::Role::Method');
178 does_ok(Baz->meta->get_attribute('bar'), 'Foo::Role::Attribute');
179
180 {
181     package Baz::Meta::Method;
182     use Moose;
183     extends 'Moose::Meta::Method';
184 }
185
186 {
187     package Baz::Meta::Attribute;
188     use Moose;
189     extends 'Moose::Meta::Attribute';
190 }
191
192 throws_ok {
193     Moose::Meta::Class->reinitialize(
194         'Baz',
195         method_metaclass    => 'Baz::Meta::Method',
196         attribute_metaclass => 'Baz::Meta::Attribute',
197     );
198 } qr/compatible/;
199
200 {
201     package Quux;
202     use Moose;
203     sub foo { }
204     before foo => sub { };
205     has bar => (is => 'ro');
206     sub DEMOLISH { }
207     __PACKAGE__->meta->make_immutable;
208 }
209
210 ok(Quux->meta->has_method('new'));
211 isa_ok(Quux->meta->get_method('new'), 'Moose::Meta::Method::Constructor');
212 ok(Quux->meta->has_method('meta'));
213 isa_ok(Quux->meta->get_method('meta'), 'Moose::Meta::Method::Meta');
214 ok(Quux->meta->has_method('foo'));
215 isa_ok(Quux->meta->get_method('foo'), 'Class::MOP::Method::Wrapped');
216 ok(Quux->meta->has_method('bar'));
217 isa_ok(Quux->meta->get_method('bar'), 'Moose::Meta::Method::Accessor');
218 ok(Quux->meta->has_method('DESTROY'));
219 isa_ok(Quux->meta->get_method('DESTROY'), 'Moose::Meta::Method::Destructor');
220 ok(Quux->meta->has_method('DEMOLISH'));
221 isa_ok(Quux->meta->get_method('DEMOLISH'), 'Moose::Meta::Method');
222
223 Quux->meta->make_mutable;
224 Moose::Meta::Class->reinitialize('Quux');
225 Quux->meta->make_immutable;
226
227 ok(Quux->meta->has_method('new'));
228 isa_ok(Quux->meta->get_method('new'), 'Moose::Meta::Method::Constructor');
229 ok(Quux->meta->has_method('meta'));
230 isa_ok(Quux->meta->get_method('meta'), 'Moose::Meta::Method::Meta');
231 ok(Quux->meta->has_method('foo'));
232 isa_ok(Quux->meta->get_method('foo'), 'Class::MOP::Method::Wrapped');
233 ok(Quux->meta->has_method('bar'));
234 isa_ok(Quux->meta->get_method('bar'), 'Moose::Meta::Method::Accessor');
235 ok(Quux->meta->has_method('DESTROY'));
236 isa_ok(Quux->meta->get_method('DESTROY'), 'Moose::Meta::Method::Destructor');
237 ok(Quux->meta->has_method('DEMOLISH'));
238 isa_ok(Quux->meta->get_method('DEMOLISH'), 'Moose::Meta::Method');
239
240 Quux->meta->make_mutable;
241 Moose::Util::MetaRole::apply_metaroles(
242     for => 'Quux',
243     class_metaroles => {
244         method    => ['Foo::Role::Method'],
245         attribute => ['Foo::Role::Attribute'],
246     },
247 );
248 Quux->meta->make_immutable;
249
250 ok(Quux->meta->has_method('new'));
251 isa_ok(Quux->meta->get_method('new'), 'Moose::Meta::Method::Constructor');
252 { local $TODO = "constructor methods don't get metaroles yet";
253 does_ok(Quux->meta->get_method('new'), 'Foo::Role::Method');
254 }
255 ok(Quux->meta->has_method('meta'));
256 isa_ok(Quux->meta->get_method('meta'), 'Moose::Meta::Method::Meta');
257 { local $TODO = "meta methods don't get metaroles yet";
258 does_ok(Quux->meta->get_method('meta'), 'Foo::Role::Method');
259 }
260 ok(Quux->meta->has_method('foo'));
261 isa_ok(Quux->meta->get_method('foo'), 'Class::MOP::Method::Wrapped');
262 { local $TODO = "modified methods don't get metaroles yet";
263 does_ok(Quux->meta->get_method('foo'), 'Foo::Role::Method');
264 }
265 ok(Quux->meta->has_method('bar'));
266 isa_ok(Quux->meta->get_method('bar'), 'Moose::Meta::Method::Accessor');
267 { local $TODO = "accessor methods don't get metaroles yet";
268 does_ok(Quux->meta->get_method('bar'), 'Foo::Role::Method');
269 }
270 ok(Quux->meta->has_method('DESTROY'));
271 isa_ok(Quux->meta->get_method('DESTROY'), 'Moose::Meta::Method::Destructor');
272 { local $TODO = "destructor methods don't get metaroles yet";
273 does_ok(Quux->meta->get_method('DESTROY'), 'Foo::Role::Method');
274 }
275 ok(Quux->meta->has_method('DEMOLISH'));
276 isa_ok(Quux->meta->get_method('DEMOLISH'), 'Moose::Meta::Method');
277 does_ok(Quux->meta->get_method('DEMOLISH'), 'Foo::Role::Method');
278
279 done_testing;