Commit | Line | Data |
4403da90 |
1 | #!/usr/bin/perl |
2 | |
3 | use strict; |
4 | use warnings; |
5 | |
3d659f7f |
6 | use Test::More; |
b10dde3a |
7 | use Test::Fatal; |
b30e7781 |
8 | |
4d438a84 |
9 | use Test::Requires { |
10 | 'Test::Output' => '0.01', # skip all if not installed |
11 | }; |
b30e7781 |
12 | |
13 | { |
14 | package HasOwnImmutable; |
15 | |
16 | use Moose; |
17 | |
18 | no Moose; |
19 | |
8b23f9f8 |
20 | ::stderr_is( sub { eval q[sub make_immutable { return 'foo' }] }, |
b30e7781 |
21 | '', |
22 | 'no warning when defining our own make_immutable sub' ); |
23 | } |
24 | |
25 | { |
26 | is( HasOwnImmutable->make_immutable(), 'foo', |
27 | 'HasOwnImmutable->make_immutable does not get overwritten' ); |
28 | } |
2c9c8797 |
29 | |
4403da90 |
30 | { |
31 | package MooseX::Empty; |
32 | |
33 | use Moose (); |
aedcb7d9 |
34 | Moose::Exporter->setup_import_methods( also => 'Moose' ); |
4403da90 |
35 | } |
36 | |
37 | { |
38 | package WantsMoose; |
39 | |
2c9c8797 |
40 | MooseX::Empty->import(); |
4403da90 |
41 | |
42 | sub foo { 1 } |
43 | |
2c9c8797 |
44 | ::can_ok( 'WantsMoose', 'has' ); |
45 | ::can_ok( 'WantsMoose', 'with' ); |
46 | ::can_ok( 'WantsMoose', 'foo' ); |
4403da90 |
47 | |
2c9c8797 |
48 | MooseX::Empty->unimport(); |
4403da90 |
49 | } |
50 | |
51 | { |
2c9c8797 |
52 | # Note: it's important that these methods be out of scope _now_, |
53 | # after unimport was called. We tried a |
54 | # namespace::clean(0.08)-based solution, but had to abandon it |
55 | # because it cleans the namespace _later_ (when the file scope |
56 | # ends). |
4403da90 |
57 | ok( ! WantsMoose->can('has'), 'WantsMoose::has() has been cleaned' ); |
58 | ok( ! WantsMoose->can('with'), 'WantsMoose::with() has been cleaned' ); |
59 | can_ok( 'WantsMoose', 'foo' ); |
42c391b1 |
60 | |
61 | # This makes sure that Moose->init_meta() happens properly |
62 | isa_ok( WantsMoose->meta(), 'Moose::Meta::Class' ); |
63 | isa_ok( WantsMoose->new(), 'Moose::Object' ); |
64 | |
4403da90 |
65 | } |
66 | |
67 | { |
68 | package MooseX::Sugar; |
69 | |
70 | use Moose (); |
71 | |
72 | sub wrapped1 { |
0661fc1a |
73 | my $meta = shift; |
74 | return $meta->name . ' called wrapped1'; |
4403da90 |
75 | } |
76 | |
aedcb7d9 |
77 | Moose::Exporter->setup_import_methods( |
0661fc1a |
78 | with_meta => ['wrapped1'], |
79 | also => 'Moose', |
2c9c8797 |
80 | ); |
4403da90 |
81 | } |
82 | |
83 | { |
84 | package WantsSugar; |
85 | |
2c9c8797 |
86 | MooseX::Sugar->import(); |
4403da90 |
87 | |
88 | sub foo { 1 } |
89 | |
2c9c8797 |
90 | ::can_ok( 'WantsSugar', 'has' ); |
91 | ::can_ok( 'WantsSugar', 'with' ); |
92 | ::can_ok( 'WantsSugar', 'wrapped1' ); |
93 | ::can_ok( 'WantsSugar', 'foo' ); |
94 | ::is( wrapped1(), 'WantsSugar called wrapped1', |
95 | 'wrapped1 identifies the caller correctly' ); |
4403da90 |
96 | |
2c9c8797 |
97 | MooseX::Sugar->unimport(); |
4403da90 |
98 | } |
99 | |
100 | { |
101 | ok( ! WantsSugar->can('has'), 'WantsSugar::has() has been cleaned' ); |
102 | ok( ! WantsSugar->can('with'), 'WantsSugar::with() has been cleaned' ); |
103 | ok( ! WantsSugar->can('wrapped1'), 'WantsSugar::wrapped1() has been cleaned' ); |
104 | can_ok( 'WantsSugar', 'foo' ); |
105 | } |
106 | |
107 | { |
108 | package MooseX::MoreSugar; |
109 | |
110 | use Moose (); |
111 | |
112 | sub wrapped2 { |
3b400403 |
113 | my $caller = shift->name; |
4403da90 |
114 | return $caller . ' called wrapped2'; |
115 | } |
116 | |
117 | sub as_is1 { |
118 | return 'as_is1'; |
119 | } |
120 | |
aedcb7d9 |
121 | Moose::Exporter->setup_import_methods( |
3b400403 |
122 | with_meta => ['wrapped2'], |
123 | as_is => ['as_is1'], |
124 | also => 'MooseX::Sugar', |
2c9c8797 |
125 | ); |
4403da90 |
126 | } |
127 | |
128 | { |
129 | package WantsMoreSugar; |
130 | |
2c9c8797 |
131 | MooseX::MoreSugar->import(); |
4403da90 |
132 | |
133 | sub foo { 1 } |
134 | |
2c9c8797 |
135 | ::can_ok( 'WantsMoreSugar', 'has' ); |
136 | ::can_ok( 'WantsMoreSugar', 'with' ); |
137 | ::can_ok( 'WantsMoreSugar', 'wrapped1' ); |
138 | ::can_ok( 'WantsMoreSugar', 'wrapped2' ); |
139 | ::can_ok( 'WantsMoreSugar', 'as_is1' ); |
140 | ::can_ok( 'WantsMoreSugar', 'foo' ); |
141 | ::is( wrapped1(), 'WantsMoreSugar called wrapped1', |
142 | 'wrapped1 identifies the caller correctly' ); |
143 | ::is( wrapped2(), 'WantsMoreSugar called wrapped2', |
144 | 'wrapped2 identifies the caller correctly' ); |
145 | ::is( as_is1(), 'as_is1', |
146 | 'as_is1 works as expected' ); |
147 | |
148 | MooseX::MoreSugar->unimport(); |
4403da90 |
149 | } |
150 | |
151 | { |
152 | ok( ! WantsMoreSugar->can('has'), 'WantsMoreSugar::has() has been cleaned' ); |
153 | ok( ! WantsMoreSugar->can('with'), 'WantsMoreSugar::with() has been cleaned' ); |
154 | ok( ! WantsMoreSugar->can('wrapped1'), 'WantsMoreSugar::wrapped1() has been cleaned' ); |
155 | ok( ! WantsMoreSugar->can('wrapped2'), 'WantsMoreSugar::wrapped2() has been cleaned' ); |
156 | ok( ! WantsMoreSugar->can('as_is1'), 'WantsMoreSugar::as_is1() has been cleaned' ); |
157 | can_ok( 'WantsMoreSugar', 'foo' ); |
158 | } |
159 | |
160 | { |
085fba61 |
161 | package My::Metaclass; |
162 | use Moose; |
163 | BEGIN { extends 'Moose::Meta::Class' } |
164 | |
165 | package My::Object; |
166 | use Moose; |
167 | BEGIN { extends 'Moose::Object' } |
168 | |
169 | package HasInitMeta; |
170 | |
171 | use Moose (); |
172 | |
173 | sub init_meta { |
174 | shift; |
175 | return Moose->init_meta( @_, |
176 | metaclass => 'My::Metaclass', |
177 | base_class => 'My::Object', |
178 | ); |
179 | } |
180 | |
aedcb7d9 |
181 | Moose::Exporter->setup_import_methods( also => 'Moose' ); |
085fba61 |
182 | } |
183 | |
184 | { |
185 | package NewMeta; |
186 | |
2c9c8797 |
187 | HasInitMeta->import(); |
085fba61 |
188 | } |
189 | |
190 | { |
191 | isa_ok( NewMeta->meta(), 'My::Metaclass' ); |
192 | isa_ok( NewMeta->new(), 'My::Object' ); |
193 | } |
194 | |
195 | { |
4403da90 |
196 | package MooseX::CircularAlso; |
197 | |
198 | use Moose (); |
199 | |
b10dde3a |
200 | ::like( |
201 | ::exception{ Moose::Exporter->setup_import_methods( |
4403da90 |
202 | also => [ 'Moose', 'MooseX::CircularAlso' ], |
203 | ); |
b10dde3a |
204 | }, |
b822369d |
205 | qr/\QCircular reference in 'also' parameter to Moose::Exporter between MooseX::CircularAlso and MooseX::CircularAlso/, |
b10dde3a |
206 | 'a circular reference in also dies with an error' |
4403da90 |
207 | ); |
208 | } |
209 | |
210 | { |
ba1a3c2f |
211 | package MooseX::NoAlso; |
4403da90 |
212 | |
213 | use Moose (); |
214 | |
4403da90 |
215 | ::like( |
b10dde3a |
216 | ::exception{ Moose::Exporter->setup_import_methods( |
217 | also => ['NoSuchThing'], |
218 | ); |
219 | }, |
ba1a3c2f |
220 | qr/\QPackage in also (NoSuchThing) does not seem to use Moose::Exporter (is it loaded?) at /, |
b10dde3a |
221 | 'a package which does not use Moose::Exporter in also dies with an error' |
ba1a3c2f |
222 | ); |
223 | } |
224 | |
225 | { |
226 | package MooseX::NotExporter; |
227 | |
228 | use Moose (); |
229 | |
ba1a3c2f |
230 | ::like( |
b10dde3a |
231 | ::exception{ Moose::Exporter->setup_import_methods( |
232 | also => ['Moose::Meta::Method'], |
233 | ); |
234 | }, |
ba1a3c2f |
235 | qr/\QPackage in also (Moose::Meta::Method) does not seem to use Moose::Exporter at /, |
b10dde3a |
236 | 'a package which does not use Moose::Exporter in also dies with an error' |
4403da90 |
237 | ); |
238 | } |
ae8817b6 |
239 | |
240 | { |
241 | package MooseX::OverridingSugar; |
242 | |
243 | use Moose (); |
244 | |
245 | sub has { |
3b400403 |
246 | my $caller = shift->name; |
ae8817b6 |
247 | return $caller . ' called has'; |
248 | } |
249 | |
250 | Moose::Exporter->setup_import_methods( |
3b400403 |
251 | with_meta => ['has'], |
252 | also => 'Moose', |
ae8817b6 |
253 | ); |
254 | } |
255 | |
256 | { |
257 | package WantsOverridingSugar; |
258 | |
259 | MooseX::OverridingSugar->import(); |
260 | |
261 | ::can_ok( 'WantsOverridingSugar', 'has' ); |
262 | ::can_ok( 'WantsOverridingSugar', 'with' ); |
263 | ::is( has('foo'), 'WantsOverridingSugar called has', |
264 | 'has from MooseX::OverridingSugar is called, not has from Moose' ); |
265 | |
266 | MooseX::OverridingSugar->unimport(); |
267 | } |
268 | |
269 | { |
f7d62c2e |
270 | ok( ! WantsOverridingSugar->can('has'), 'WantsSugar::has() has been cleaned' ); |
271 | ok( ! WantsOverridingSugar->can('with'), 'WantsSugar::with() has been cleaned' ); |
272 | } |
273 | |
274 | { |
275 | package MooseX::OverridingSugar::PassThru; |
064a13a3 |
276 | |
f7d62c2e |
277 | sub with { |
278 | my $caller = shift->name; |
279 | return $caller . ' called with'; |
280 | } |
064a13a3 |
281 | |
f7d62c2e |
282 | Moose::Exporter->setup_import_methods( |
283 | with_meta => ['with'], |
284 | also => 'MooseX::OverridingSugar', |
285 | ); |
f7d62c2e |
286 | } |
287 | |
288 | { |
289 | |
290 | package WantsOverridingSugar::PassThru; |
291 | |
292 | MooseX::OverridingSugar::PassThru->import(); |
293 | |
294 | ::can_ok( 'WantsOverridingSugar::PassThru', 'has' ); |
295 | ::can_ok( 'WantsOverridingSugar::PassThru', 'with' ); |
296 | ::is( |
297 | has('foo'), |
298 | 'WantsOverridingSugar::PassThru called has', |
299 | 'has from MooseX::OverridingSugar is called, not has from Moose' |
300 | ); |
301 | |
302 | ::is( |
303 | with('foo'), |
304 | 'WantsOverridingSugar::PassThru called with', |
305 | 'with from MooseX::OverridingSugar::PassThru is called, not has from Moose' |
306 | ); |
307 | |
308 | |
309 | MooseX::OverridingSugar::PassThru->unimport(); |
310 | } |
311 | |
312 | { |
313 | ok( ! WantsOverridingSugar::PassThru->can('has'), 'WantsOverridingSugar::PassThru::has() has been cleaned' ); |
314 | ok( ! WantsOverridingSugar::PassThru->can('with'), 'WantsOverridingSugar::PassThru::with() has been cleaned' ); |
ae8817b6 |
315 | } |
316 | |
e6a5040f |
317 | { |
f7d62c2e |
318 | |
e6a5040f |
319 | package NonExistentExport; |
320 | |
321 | use Moose (); |
322 | |
323 | ::stderr_like { |
324 | Moose::Exporter->setup_import_methods( |
325 | also => ['Moose'], |
3b400403 |
326 | with_meta => ['does_not_exist'], |
e6a5040f |
327 | ); |
328 | } qr/^Trying to export undefined sub NonExistentExport::does_not_exist/, |
329 | "warns when a non-existent method is requested to be exported"; |
330 | } |
331 | |
332 | { |
333 | package WantsNonExistentExport; |
334 | |
335 | NonExistentExport->import; |
336 | |
337 | ::ok(!__PACKAGE__->can('does_not_exist'), |
338 | "undefined subs do not get exported"); |
a584a0c8 |
339 | } |
addd05f6 |
340 | |
a584a0c8 |
341 | { |
0661fc1a |
342 | package AllOptions; |
343 | use Moose (); |
3b400403 |
344 | use Moose::Deprecated -api_version => '0.88'; |
0661fc1a |
345 | use Moose::Exporter; |
346 | |
347 | Moose::Exporter->setup_import_methods( |
348 | also => ['Moose'], |
349 | with_meta => [ 'with_meta1', 'with_meta2' ], |
350 | with_caller => [ 'with_caller1', 'with_caller2' ], |
351 | as_is => ['as_is1'], |
352 | ); |
353 | |
354 | sub with_caller1 { |
355 | return @_; |
356 | } |
357 | |
358 | sub with_caller2 (&) { |
359 | return @_; |
360 | } |
361 | |
362 | sub as_is1 {2} |
363 | |
364 | sub with_meta1 { |
365 | return @_; |
366 | } |
367 | |
368 | sub with_meta2 (&) { |
369 | return @_; |
370 | } |
371 | } |
372 | |
373 | { |
374 | package UseAllOptions; |
375 | |
376 | AllOptions->import(); |
377 | } |
378 | |
379 | { |
380 | can_ok( 'UseAllOptions', $_ ) |
381 | for qw( with_meta1 with_meta2 with_caller1 with_caller2 as_is1 ); |
382 | |
383 | { |
384 | my ( $caller, $arg1 ) = UseAllOptions::with_caller1(42); |
385 | is( $caller, 'UseAllOptions', 'with_caller wrapped sub gets the right caller' ); |
386 | is( $arg1, 42, 'with_caller wrapped sub returns argument it was passed' ); |
387 | } |
388 | |
389 | { |
390 | my ( $meta, $arg1 ) = UseAllOptions::with_meta1(42); |
391 | isa_ok( $meta, 'Moose::Meta::Class', 'with_meta first argument' ); |
392 | is( $arg1, 42, 'with_meta1 returns argument it was passed' ); |
393 | } |
394 | |
395 | is( |
5a204c51 |
396 | prototype( UseAllOptions->can('with_caller2') ), |
397 | prototype( AllOptions->can('with_caller2') ), |
398 | 'using correct prototype on with_meta function' |
399 | ); |
400 | |
401 | is( |
0661fc1a |
402 | prototype( UseAllOptions->can('with_meta2') ), |
403 | prototype( AllOptions->can('with_meta2') ), |
404 | 'using correct prototype on with_meta function' |
405 | ); |
a584a0c8 |
406 | } |
0661fc1a |
407 | |
a584a0c8 |
408 | { |
409 | package UseAllOptions; |
410 | AllOptions->unimport(); |
411 | } |
0661fc1a |
412 | |
a584a0c8 |
413 | { |
0661fc1a |
414 | ok( ! UseAllOptions->can($_), "UseAllOptions::$_ has been unimported" ) |
415 | for qw( with_meta1 with_meta2 with_caller1 with_caller2 as_is1 ); |
e6a5040f |
416 | } |
a28e50e4 |
417 | |
360e6512 |
418 | { |
419 | package InitMetaError; |
420 | use Moose::Exporter; |
421 | use Moose (); |
422 | Moose::Exporter->setup_import_methods(also => ['Moose']); |
423 | sub init_meta { |
424 | my $package = shift; |
425 | my %options = @_; |
426 | Moose->init_meta(%options, metaclass => 'Not::Loaded'); |
427 | } |
428 | } |
429 | |
430 | { |
431 | package InitMetaError::Role; |
432 | use Moose::Exporter; |
433 | use Moose::Role (); |
434 | Moose::Exporter->setup_import_methods(also => ['Moose::Role']); |
435 | sub init_meta { |
436 | my $package = shift; |
437 | my %options = @_; |
438 | Moose::Role->init_meta(%options, metaclass => 'Not::Loaded'); |
439 | } |
440 | } |
441 | |
442 | { |
443 | package WantsInvalidMetaclass; |
444 | ::like( |
445 | ::exception { InitMetaError->import }, |
446 | qr/The Metaclass Not::Loaded must be loaded\. \(Perhaps you forgot to 'use Not::Loaded'\?\)/, |
447 | "error when wanting a nonexistent metaclass" |
448 | ); |
449 | } |
450 | |
451 | { |
452 | package WantsInvalidMetaclass::Role; |
453 | ::like( |
454 | ::exception { InitMetaError::Role->import }, |
455 | qr/The Metaclass Not::Loaded must be loaded\. \(Perhaps you forgot to 'use Not::Loaded'\?\)/, |
456 | "error when wanting a nonexistent metaclass" |
457 | ); |
458 | } |
459 | |
54e41ffd |
460 | { |
461 | my @init_metas_called; |
462 | |
463 | BEGIN { |
464 | package MultiLevelExporter1; |
465 | use Moose::Exporter; |
466 | |
467 | sub foo { 1 } |
468 | sub bar { 1 } |
469 | sub baz { 1 } |
470 | sub quux { 1 } |
471 | |
472 | Moose::Exporter->setup_import_methods( |
473 | with_meta => [qw(foo bar baz quux)], |
474 | ); |
475 | |
476 | sub init_meta { |
477 | push @init_metas_called, 1; |
478 | } |
479 | |
480 | $INC{'MultiLevelExporter1.pm'} = __FILE__; |
481 | } |
482 | |
483 | BEGIN { |
484 | package MultiLevelExporter2; |
485 | use Moose::Exporter; |
486 | |
487 | sub bar { 2 } |
488 | sub baz { 2 } |
489 | sub quux { 2 } |
490 | |
491 | Moose::Exporter->setup_import_methods( |
492 | also => ['MultiLevelExporter1'], |
493 | with_meta => [qw(bar baz quux)], |
494 | ); |
495 | |
496 | sub init_meta { |
497 | push @init_metas_called, 2; |
498 | } |
499 | |
500 | $INC{'MultiLevelExporter2.pm'} = __FILE__; |
501 | } |
502 | |
503 | BEGIN { |
504 | package MultiLevelExporter3; |
505 | use Moose::Exporter; |
506 | |
507 | sub baz { 3 } |
508 | sub quux { 3 } |
509 | |
510 | Moose::Exporter->setup_import_methods( |
511 | also => ['MultiLevelExporter2'], |
512 | with_meta => [qw(baz quux)], |
513 | ); |
514 | |
515 | sub init_meta { |
516 | push @init_metas_called, 3; |
517 | } |
518 | |
519 | $INC{'MultiLevelExporter3.pm'} = __FILE__; |
520 | } |
521 | |
522 | BEGIN { |
523 | package MultiLevelExporter4; |
524 | use Moose::Exporter; |
525 | |
526 | sub quux { 4 } |
527 | |
528 | Moose::Exporter->setup_import_methods( |
529 | also => ['MultiLevelExporter3'], |
530 | with_meta => [qw(quux)], |
531 | ); |
532 | |
533 | sub init_meta { |
534 | push @init_metas_called, 4; |
535 | } |
536 | |
537 | $INC{'MultiLevelExporter4.pm'} = __FILE__; |
538 | } |
539 | |
540 | BEGIN { @init_metas_called = () } |
541 | { |
542 | package UsesMulti1; |
543 | use Moose; |
544 | use MultiLevelExporter1; |
545 | ::is(foo(), 1); |
546 | ::is(bar(), 1); |
547 | ::is(baz(), 1); |
548 | ::is(quux(), 1); |
549 | } |
550 | use Data::Dumper; |
551 | BEGIN { is_deeply(\@init_metas_called, [ 1 ]) || diag(Dumper(\@init_metas_called)) } |
552 | |
553 | BEGIN { @init_metas_called = () } |
554 | { |
555 | package UsesMulti2; |
556 | use Moose; |
557 | use MultiLevelExporter2; |
558 | ::is(foo(), 1); |
559 | ::is(bar(), 2); |
560 | ::is(baz(), 2); |
561 | ::is(quux(), 2); |
562 | } |
563 | BEGIN { is_deeply(\@init_metas_called, [ 2, 1 ]) || diag(Dumper(\@init_metas_called)) } |
564 | |
565 | BEGIN { @init_metas_called = () } |
566 | { |
567 | package UsesMulti3; |
568 | use Moose; |
569 | use MultiLevelExporter3; |
570 | ::is(foo(), 1); |
571 | ::is(bar(), 2); |
572 | ::is(baz(), 3); |
573 | ::is(quux(), 3); |
574 | } |
575 | BEGIN { is_deeply(\@init_metas_called, [ 3, 2, 1 ]) || diag(Dumper(\@init_metas_called)) } |
576 | |
577 | BEGIN { @init_metas_called = () } |
578 | { |
579 | package UsesMulti4; |
580 | use Moose; |
581 | use MultiLevelExporter4; |
582 | ::is(foo(), 1); |
583 | ::is(bar(), 2); |
584 | ::is(baz(), 3); |
585 | ::is(quux(), 4); |
586 | } |
587 | BEGIN { is_deeply(\@init_metas_called, [ 4, 3, 2, 1 ]) || diag(Dumper(\@init_metas_called)) } |
588 | } |
589 | |
a28e50e4 |
590 | done_testing; |