11 'Test::Output' => '0.01', # skip all if not installed
15 package HasOwnImmutable;
21 ::stderr_is( sub { eval q[sub make_immutable { return 'foo' }] },
23 'no warning when defining our own make_immutable sub' );
27 is( HasOwnImmutable->make_immutable(), 'foo',
28 'HasOwnImmutable->make_immutable does not get overwritten' );
32 package MooseX::Empty;
35 Moose::Exporter->setup_import_methods( also => 'Moose' );
41 MooseX::Empty->import();
45 ::can_ok( 'WantsMoose', 'has' );
46 ::can_ok( 'WantsMoose', 'with' );
47 ::can_ok( 'WantsMoose', 'foo' );
49 MooseX::Empty->unimport();
53 # Note: it's important that these methods be out of scope _now_,
54 # after unimport was called. We tried a
55 # namespace::clean(0.08)-based solution, but had to abandon it
56 # because it cleans the namespace _later_ (when the file scope
58 ok( ! WantsMoose->can('has'), 'WantsMoose::has() has been cleaned' );
59 ok( ! WantsMoose->can('with'), 'WantsMoose::with() has been cleaned' );
60 can_ok( 'WantsMoose', 'foo' );
62 # This makes sure that Moose->init_meta() happens properly
63 isa_ok( WantsMoose->meta(), 'Moose::Meta::Class' );
64 isa_ok( WantsMoose->new(), 'Moose::Object' );
69 package MooseX::Sugar;
75 return $meta->name . ' called wrapped1';
78 Moose::Exporter->setup_import_methods(
79 with_meta => ['wrapped1'],
87 MooseX::Sugar->import();
91 ::can_ok( 'WantsSugar', 'has' );
92 ::can_ok( 'WantsSugar', 'with' );
93 ::can_ok( 'WantsSugar', 'wrapped1' );
94 ::can_ok( 'WantsSugar', 'foo' );
95 ::is( wrapped1(), 'WantsSugar called wrapped1',
96 'wrapped1 identifies the caller correctly' );
98 MooseX::Sugar->unimport();
102 ok( ! WantsSugar->can('has'), 'WantsSugar::has() has been cleaned' );
103 ok( ! WantsSugar->can('with'), 'WantsSugar::with() has been cleaned' );
104 ok( ! WantsSugar->can('wrapped1'), 'WantsSugar::wrapped1() has been cleaned' );
105 can_ok( 'WantsSugar', 'foo' );
109 package MooseX::MoreSugar;
114 my $caller = shift->name;
115 return $caller . ' called wrapped2';
122 Moose::Exporter->setup_import_methods(
123 with_meta => ['wrapped2'],
125 also => 'MooseX::Sugar',
130 package WantsMoreSugar;
132 MooseX::MoreSugar->import();
136 ::can_ok( 'WantsMoreSugar', 'has' );
137 ::can_ok( 'WantsMoreSugar', 'with' );
138 ::can_ok( 'WantsMoreSugar', 'wrapped1' );
139 ::can_ok( 'WantsMoreSugar', 'wrapped2' );
140 ::can_ok( 'WantsMoreSugar', 'as_is1' );
141 ::can_ok( 'WantsMoreSugar', 'foo' );
142 ::is( wrapped1(), 'WantsMoreSugar called wrapped1',
143 'wrapped1 identifies the caller correctly' );
144 ::is( wrapped2(), 'WantsMoreSugar called wrapped2',
145 'wrapped2 identifies the caller correctly' );
146 ::is( as_is1(), 'as_is1',
147 'as_is1 works as expected' );
149 MooseX::MoreSugar->unimport();
153 ok( ! WantsMoreSugar->can('has'), 'WantsMoreSugar::has() has been cleaned' );
154 ok( ! WantsMoreSugar->can('with'), 'WantsMoreSugar::with() has been cleaned' );
155 ok( ! WantsMoreSugar->can('wrapped1'), 'WantsMoreSugar::wrapped1() has been cleaned' );
156 ok( ! WantsMoreSugar->can('wrapped2'), 'WantsMoreSugar::wrapped2() has been cleaned' );
157 ok( ! WantsMoreSugar->can('as_is1'), 'WantsMoreSugar::as_is1() has been cleaned' );
158 can_ok( 'WantsMoreSugar', 'foo' );
162 package My::Metaclass;
164 BEGIN { extends 'Moose::Meta::Class' }
168 BEGIN { extends 'Moose::Object' }
176 return Moose->init_meta( @_,
177 metaclass => 'My::Metaclass',
178 base_class => 'My::Object',
182 Moose::Exporter->setup_import_methods( also => 'Moose' );
188 HasInitMeta->import();
192 isa_ok( NewMeta->meta(), 'My::Metaclass' );
193 isa_ok( NewMeta->new(), 'My::Object' );
197 package MooseX::CircularAlso;
202 ::exception{ Moose::Exporter->setup_import_methods(
203 also => [ 'Moose', 'MooseX::CircularAlso' ],
206 qr/\QCircular reference in 'also' parameter to Moose::Exporter between MooseX::CircularAlso and MooseX::CircularAlso/,
207 'a circular reference in also dies with an error'
212 package MooseX::NoAlso;
217 ::exception{ Moose::Exporter->setup_import_methods(
218 also => ['NoSuchThing'],
221 qr/\QPackage in also (NoSuchThing) does not seem to use Moose::Exporter (is it loaded?) at /,
222 'a package which does not use Moose::Exporter in also dies with an error'
227 package MooseX::NotExporter;
232 ::exception{ Moose::Exporter->setup_import_methods(
233 also => ['Moose::Meta::Method'],
236 qr/\QPackage in also (Moose::Meta::Method) does not seem to use Moose::Exporter at /,
237 'a package which does not use Moose::Exporter in also dies with an error'
242 package MooseX::OverridingSugar;
247 my $caller = shift->name;
248 return $caller . ' called has';
251 Moose::Exporter->setup_import_methods(
252 with_meta => ['has'],
258 package WantsOverridingSugar;
260 MooseX::OverridingSugar->import();
262 ::can_ok( 'WantsOverridingSugar', 'has' );
263 ::can_ok( 'WantsOverridingSugar', 'with' );
264 ::is( has('foo'), 'WantsOverridingSugar called has',
265 'has from MooseX::OverridingSugar is called, not has from Moose' );
267 MooseX::OverridingSugar->unimport();
271 ok( ! WantsOverridingSugar->can('has'), 'WantsSugar::has() has been cleaned' );
272 ok( ! WantsOverridingSugar->can('with'), 'WantsSugar::with() has been cleaned' );
276 package MooseX::OverridingSugar::PassThru;
279 my $caller = shift->name;
280 return $caller . ' called with';
283 Moose::Exporter->setup_import_methods(
284 with_meta => ['with'],
285 also => 'MooseX::OverridingSugar',
291 package WantsOverridingSugar::PassThru;
293 MooseX::OverridingSugar::PassThru->import();
295 ::can_ok( 'WantsOverridingSugar::PassThru', 'has' );
296 ::can_ok( 'WantsOverridingSugar::PassThru', 'with' );
299 'WantsOverridingSugar::PassThru called has',
300 'has from MooseX::OverridingSugar is called, not has from Moose'
305 'WantsOverridingSugar::PassThru called with',
306 'with from MooseX::OverridingSugar::PassThru is called, not has from Moose'
310 MooseX::OverridingSugar::PassThru->unimport();
314 ok( ! WantsOverridingSugar::PassThru->can('has'), 'WantsOverridingSugar::PassThru::has() has been cleaned' );
315 ok( ! WantsOverridingSugar::PassThru->can('with'), 'WantsOverridingSugar::PassThru::with() has been cleaned' );
320 package NonExistentExport;
325 Moose::Exporter->setup_import_methods(
327 with_meta => ['does_not_exist'],
329 } qr/^Trying to export undefined sub NonExistentExport::does_not_exist/,
330 "warns when a non-existent method is requested to be exported";
334 package WantsNonExistentExport;
336 NonExistentExport->import;
338 ::ok(!__PACKAGE__->can('does_not_exist'),
339 "undefined subs do not get exported");
345 use Moose::Deprecated -api_version => '0.88';
348 Moose::Exporter->setup_import_methods(
350 with_meta => [ 'with_meta1', 'with_meta2' ],
351 with_caller => [ 'with_caller1', 'with_caller2' ],
359 sub with_caller2 (&) {
375 package UseAllOptions;
377 AllOptions->import();
381 can_ok( 'UseAllOptions', $_ )
382 for qw( with_meta1 with_meta2 with_caller1 with_caller2 as_is1 );
385 my ( $caller, $arg1 ) = UseAllOptions::with_caller1(42);
386 is( $caller, 'UseAllOptions', 'with_caller wrapped sub gets the right caller' );
387 is( $arg1, 42, 'with_caller wrapped sub returns argument it was passed' );
391 my ( $meta, $arg1 ) = UseAllOptions::with_meta1(42);
392 isa_ok( $meta, 'Moose::Meta::Class', 'with_meta first argument' );
393 is( $arg1, 42, 'with_meta1 returns argument it was passed' );
397 prototype( UseAllOptions->can('with_caller2') ),
398 prototype( AllOptions->can('with_caller2') ),
399 'using correct prototype on with_meta function'
403 prototype( UseAllOptions->can('with_meta2') ),
404 prototype( AllOptions->can('with_meta2') ),
405 'using correct prototype on with_meta function'
410 package UseAllOptions;
411 AllOptions->unimport();
415 ok( ! UseAllOptions->can($_), "UseAllOptions::$_ has been unimported" )
416 for qw( with_meta1 with_meta2 with_caller1 with_caller2 as_is1 );
420 package InitMetaError;
423 Moose::Exporter->setup_import_methods(also => ['Moose']);
427 Moose->init_meta(%options, metaclass => 'Not::Loaded');
432 package InitMetaError::Role;
435 Moose::Exporter->setup_import_methods(also => ['Moose::Role']);
439 Moose::Role->init_meta(%options, metaclass => 'Not::Loaded');
444 package WantsInvalidMetaclass;
446 ::exception { InitMetaError->import },
447 qr/The Metaclass Not::Loaded must be loaded\. \(Perhaps you forgot to 'use Not::Loaded'\?\)/,
448 "error when wanting a nonexistent metaclass"
453 package WantsInvalidMetaclass::Role;
455 ::exception { InitMetaError::Role->import },
456 qr/The Metaclass Not::Loaded must be loaded\. \(Perhaps you forgot to 'use Not::Loaded'\?\)/,
457 "error when wanting a nonexistent metaclass"
462 my @init_metas_called;
465 package MultiLevelExporter1;
473 Moose::Exporter->setup_import_methods(
474 with_meta => [qw(foo bar baz quux)],
478 push @init_metas_called, 1;
481 $INC{'MultiLevelExporter1.pm'} = __FILE__;
485 package MultiLevelExporter2;
492 Moose::Exporter->setup_import_methods(
493 also => ['MultiLevelExporter1'],
494 with_meta => [qw(bar baz quux)],
498 push @init_metas_called, 2;
501 $INC{'MultiLevelExporter2.pm'} = __FILE__;
505 package MultiLevelExporter3;
511 Moose::Exporter->setup_import_methods(
512 also => ['MultiLevelExporter2'],
513 with_meta => [qw(baz quux)],
517 push @init_metas_called, 3;
520 $INC{'MultiLevelExporter3.pm'} = __FILE__;
524 package MultiLevelExporter4;
529 Moose::Exporter->setup_import_methods(
530 also => ['MultiLevelExporter3'],
531 with_meta => [qw(quux)],
535 push @init_metas_called, 4;
538 $INC{'MultiLevelExporter4.pm'} = __FILE__;
541 BEGIN { @init_metas_called = () }
545 use MultiLevelExporter1;
552 BEGIN { is_deeply(\@init_metas_called, [ 1 ]) || diag(Dumper(\@init_metas_called)) }
554 BEGIN { @init_metas_called = () }
558 use MultiLevelExporter2;
564 BEGIN { is_deeply(\@init_metas_called, [ 2, 1 ]) || diag(Dumper(\@init_metas_called)) }
566 BEGIN { @init_metas_called = () }
570 use MultiLevelExporter3;
576 BEGIN { is_deeply(\@init_metas_called, [ 3, 2, 1 ]) || diag(Dumper(\@init_metas_called)) }
578 BEGIN { @init_metas_called = () }
582 use MultiLevelExporter4;
588 BEGIN { is_deeply(\@init_metas_called, [ 4, 3, 2, 1 ]) || diag(Dumper(\@init_metas_called)) }
591 # Using "also => [ 'MooseX::UsesAlsoMoose', 'MooseX::SomethingElse' ]" should
592 # continue to work. The init_meta order needs to be MooseX::CurrentExporter,
593 # MooseX::UsesAlsoMoose, Moose, MooseX::SomethingElse. This is a pretty ugly
594 # and messed up use case, but necessary until we come up with a better way to
598 my @init_metas_called;
601 package AlsoTest::Role1;
604 $INC{'AlsoTest/Role1.pm'} = __FILE__;
611 Moose::Exporter->setup_import_methods(
618 ::ok(!Class::MOP::class_of($opts{for_class}));
619 push @init_metas_called, 1;
622 $INC{'AlsoTest1.pm'} = __FILE__;
628 use Moose::Util::MetaRole ();
630 Moose::Exporter->setup_import_methods;
635 ::ok(Class::MOP::class_of($opts{for_class}));
636 Moose::Util::MetaRole::apply_metaroles(
637 for => $opts{for_class},
639 class => ['AlsoTest::Role1'],
642 push @init_metas_called, 2;
645 $INC{'AlsoTest2.pm'} = __FILE__;
652 Moose::Exporter->setup_import_methods(
653 also => [ 'AlsoTest1', 'AlsoTest2' ],
659 ::ok(!Class::MOP::class_of($opts{for_class}));
660 push @init_metas_called, 3;
663 $INC{'AlsoTest3.pm'} = __FILE__;
666 BEGIN { @init_metas_called = () }
668 package UsesAlsoTest3;
673 is_deeply(\@init_metas_called, [ 3, 1, 2 ])
674 || diag(Dumper(\@init_metas_called));
675 isa_ok(Class::MOP::class_of('UsesAlsoTest3'), 'Moose::Meta::Class');
676 does_ok(Class::MOP::class_of('UsesAlsoTest3'), 'AlsoTest::Role1');