X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=t%2Fmetaclasses%2Foverloading.t;h=daeed8cef01da448e08a94bdba5f8fe0d3a8e686;hb=8c70b0e6167da4bb0f3008749964f682e5c1715e;hp=8c5bdd1b624891140a23b7af510e19e735be65aa;hpb=644d6eaacc4b24118f85c91026d4d7ea760c8988;p=gitmo%2FMoose.git diff --git a/t/metaclasses/overloading.t b/t/metaclasses/overloading.t index 8c5bdd1..daeed8c 100644 --- a/t/metaclasses/overloading.t +++ b/t/metaclasses/overloading.t @@ -2,6 +2,9 @@ use strict; use warnings; use Test::More; +use Test::Fatal; + +my $quote = qr/['`"]/; { package Foo; @@ -9,13 +12,27 @@ use Test::More; } { - is_deeply([Foo->meta->get_overload_list], []); - is_deeply([Foo->meta->get_overloaded_operators], []); + my $meta = Foo->meta; + + ok(!$meta->is_overloaded); + + is_deeply([sort $meta->overload_operators], + [sort map { split /\s+/ } values %overload::ops]); + + ok(!$meta->has_overloaded_operator('+')); + ok(!$meta->has_overloaded_operator('-')); + + is_deeply([$meta->get_overload_list], []); + + is_deeply([$meta->get_all_overloaded_operators], []); + + is($meta->get_overloaded_operator('+'), undef); + is($meta->get_overloaded_operator('-'), undef); } -my $plus; +my $plus = 0; my $plus_impl; -BEGIN { $plus_impl = sub { $plus = 1; $_[0] + $_[1] } } +BEGIN { $plus_impl = sub { $plus = 1; "plus" } } { package Foo::Overloaded; use Moose; @@ -23,8 +40,16 @@ BEGIN { $plus_impl = sub { $plus = 1; $_[0] + $_[1] } } } { - is_deeply([Foo::Overloaded->meta->get_overloaded_operators], ['+']); - my @overloads = Foo::Overloaded->meta->get_overload_list; + my $meta = Foo::Overloaded->meta; + + ok($meta->is_overloaded); + + ok($meta->has_overloaded_operator('+')); + ok(!$meta->has_overloaded_operator('-')); + + is_deeply([$meta->get_overload_list], ['+']); + + my @overloads = $meta->get_all_overloaded_operators; is(scalar(@overloads), 1); my $plus_meth = $overloads[0]; isa_ok($plus_meth, 'Class::MOP::Method::Overload'); @@ -32,7 +57,122 @@ BEGIN { $plus_impl = sub { $plus = 1; $_[0] + $_[1] } } is($plus_meth->name, '(+'); is($plus_meth->body, $plus_impl); is($plus_meth->package_name, 'Foo::Overloaded'); - is($plus_meth->associated_metaclass, Foo::Overloaded->meta); + is($plus_meth->associated_metaclass, $meta); + + my $plus_meth2 = $meta->get_overloaded_operator('+'); + { local $TODO = "we don't cache these yet"; + is($plus_meth2, $plus_meth); + } + is($plus_meth2->operator, '+'); + is($plus_meth2->body, $plus_impl); + is($meta->get_overloaded_operator('-'), undef); + + is($plus, 0); + is(Foo::Overloaded->new + Foo::Overloaded->new, "plus"); + is($plus, 1); + + my $minus = 0; + my $minus_impl = sub { $minus = 1; "minus" }; + + like(exception { Foo::Overloaded->new - Foo::Overloaded->new }, + qr/Operation $quote-$quote: no method found/); + + $meta->add_overloaded_operator('-' => $minus_impl); + + ok($meta->has_overloaded_operator('-')); + + is_deeply([sort $meta->get_overload_list], ['+', '-']); + + is(scalar($meta->get_all_overloaded_operators), 2); + + my $minus_meth = $meta->get_overloaded_operator('-'); + isa_ok($minus_meth, 'Class::MOP::Method::Overload'); + is($minus_meth->operator, '-'); + is($minus_meth->name, '(-'); + is($minus_meth->body, $minus_impl); + is($minus_meth->package_name, 'Foo::Overloaded'); + is($minus_meth->associated_metaclass, $meta); + + is($minus, 0); + is(Foo::Overloaded->new - Foo::Overloaded->new, "minus"); + is($minus, 1); + + $meta->remove_overloaded_operator('-'); + + like(exception { Foo::Overloaded->new - Foo::Overloaded->new }, + qr/Operation $quote-$quote: no method found/); +} + +my $times = 0; +my $divided = 0; +{ + package Foo::OverloadedMethod; + use Moose; + use overload '*' => 'times'; + + sub times { $times = 1; "times" } + sub divided { $divided = 1; "divided" } +} + +{ + my $meta = Foo::OverloadedMethod->meta; + + ok($meta->is_overloaded); + + ok($meta->has_overloaded_operator('*')); + ok(!$meta->has_overloaded_operator('/')); + + is_deeply([$meta->get_overload_list], ['*']); + + my @overloads = $meta->get_all_overloaded_operators; + is(scalar(@overloads), 1); + my $times_meth = $overloads[0]; + isa_ok($times_meth, 'Class::MOP::Method::Overload'); + is($times_meth->operator, '*'); + is($times_meth->name, '(*'); + is($times_meth->body, $meta->get_method('times')->body); + is($times_meth->package_name, 'Foo::OverloadedMethod'); + is($times_meth->associated_metaclass, $meta); + + my $times_meth2 = $meta->get_overloaded_operator('*'); + { local $TODO = "we don't cache these yet"; + is($times_meth2, $times_meth); + } + is($times_meth2->operator, '*'); + is($times_meth2->body, $meta->get_method('times')->body); + is($meta->get_overloaded_operator('/'), undef); + + is($times, 0); + is(Foo::OverloadedMethod->new * Foo::OverloadedMethod->new, "times"); + is($times, 1); + + like(exception { Foo::OverloadedMethod->new / Foo::OverloadedMethod->new }, + qr{Operation $quote/$quote: no method found}); + + $meta->add_overloaded_operator('/' => 'divided'); + + ok($meta->has_overloaded_operator('/')); + + is_deeply([sort $meta->get_overload_list], ['*', '/']); + + is(scalar($meta->get_all_overloaded_operators), 2); + + my $divided_meth = $meta->get_overloaded_operator('/'); + isa_ok($divided_meth, 'Class::MOP::Method::Overload'); + is($divided_meth->operator, '/'); + is($divided_meth->name, '(/'); + is($divided_meth->body, $meta->get_method('divided')->body); + is($divided_meth->package_name, 'Foo::OverloadedMethod'); + is($divided_meth->associated_metaclass, $meta); + + is($divided, 0); + is(Foo::OverloadedMethod->new / Foo::OverloadedMethod->new, "divided"); + is($divided, 1); + + $meta->remove_overloaded_operator('/'); + + like(exception { Foo::OverloadedMethod->new / Foo::OverloadedMethod->new }, + qr{Operation $quote/$quote: no method found}); } done_testing;