getting close to a 0.07 release
[gitmo/Class-MOP.git] / t / 003_methods.t
CommitLineData
0882828e 1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
663f8198 6use Test::More tests => 40;
0882828e 7use Test::Exception;
8
9BEGIN {
10 use_ok('Class::MOP');
11 use_ok('Class::MOP::Class');
12}
13
bfe4d0fc 14{ # This package tries to test &has_method
15 # as exhaustively as possible. More corner
16 # cases are welcome :)
0882828e 17 package Foo;
18
19 # import a sub
20 use Scalar::Util 'blessed';
21
bfe4d0fc 22 use constant FOO_CONSTANT => 'Foo-CONSTANT';
23
0882828e 24 # define a sub in package
25 sub bar { 'Foo::bar' }
60d90bbc 26 *baz = \&bar;
bfe4d0fc 27
28 { # method named with Sub::Name inside the package scope
29 no strict 'refs';
30 *{'Foo::floob'} = Sub::Name::subname 'floob' => sub { '!floob!' };
31 }
32
60d90bbc 33 # We hateses the "used only once" warnings
34 { my $temp = \&Foo::baz }
35
36 package main;
37
38 sub Foo::blah { $_[0]->Foo::baz() }
39
40 {
41 no strict 'refs';
42 *{'Foo::bling'} = sub { '$$Bling$$' };
bfe4d0fc 43 *{'Foo::bang'} = Sub::Name::subname 'Foo::bang' => sub { '!BANG!' };
44 *{'Foo::boom'} = Sub::Name::subname 'boom' => sub { '!BOOM!' };
45
46 eval "package Foo; sub evaled_foo { 'Foo::evaled_foo' }";
60d90bbc 47 }
0882828e 48}
49
bfe4d0fc 50my $Foo = Class::MOP::Class->initialize('Foo');
0882828e 51
52my $foo = sub { 'Foo::foo' };
53
54lives_ok {
55 $Foo->add_method('foo' => $foo);
56} '... we added the method successfully';
57
58ok($Foo->has_method('foo'), '... Foo->has_method(foo) (defined with Sub::Name)');
bfe4d0fc 59
60is($Foo->get_method('foo'), $foo, '... Foo->get_method(foo) == \&foo');
61is(Foo->foo(), 'Foo::foo', '... Foo->foo() returns "Foo::foo"');
62
63# now check all our other items ...
64
65ok($Foo->has_method('FOO_CONSTANT'), '... Foo->has_method(FOO_CONSTANT) (defined w/ use constant)');
0882828e 66ok($Foo->has_method('bar'), '... Foo->has_method(bar) (defined in Foo)');
60d90bbc 67ok($Foo->has_method('baz'), '... Foo->has_method(baz) (typeglob aliased within Foo)');
bfe4d0fc 68ok($Foo->has_method('floob'), '... Foo->has_method(floob) (defined in Foo:: using symbol tables and Sub::Name w/out package name)');
60d90bbc 69ok($Foo->has_method('blah'), '... Foo->has_method(blah) (defined in main:: using fully qualified package name)');
bfe4d0fc 70ok($Foo->has_method('bling'), '... Foo->has_method(bling) (defined in main:: using symbol tables (no Sub::Name))');
60d90bbc 71ok($Foo->has_method('bang'), '... Foo->has_method(bang) (defined in main:: using symbol tables and Sub::Name)');
bfe4d0fc 72ok($Foo->has_method('evaled_foo'), '... Foo->has_method(evaled_foo) (evaled in main::)');
0882828e 73
663f8198 74{
75 package Foo::Aliasing;
76 use metaclass;
77 sub alias_me { '...' }
78}
79
80$Foo->alias_method('alias_me' => Foo::Aliasing->meta->get_method('alias_me'));
81
82ok(!$Foo->has_method('alias_me'), '... !Foo->has_method(alias_me) (aliased from Foo::Aliasing)');
83ok(defined &Foo::alias_me, '... Foo does have a symbol table slow for alias_me though');
84
bfe4d0fc 85ok(!$Foo->has_method('blessed'), '... !Foo->has_method(blessed) (imported into Foo)');
86ok(!$Foo->has_method('boom'), '... !Foo->has_method(boom) (defined in main:: using symbol tables and Sub::Name w/out package name)');
0882828e 87
bfe4d0fc 88ok(!$Foo->has_method('not_a_real_method'), '... !Foo->has_method(not_a_real_method) (does not exist)');
89is($Foo->get_method('not_a_real_method'), undef, '... Foo->get_method(not_a_real_method) == undef');
90
c9b8b7f9 91is_deeply(
92 [ sort $Foo->get_method_list ],
93 [ qw(FOO_CONSTANT bang bar baz blah bling evaled_foo floob foo) ],
94 '... got the right method list for Foo');
95
a5eca695 96is_deeply(
97 [ sort { $a->{name} cmp $b->{name} } $Foo->compute_all_applicable_methods() ],
98 [
99 map {
100 {
101 name => $_,
102 class => 'Foo',
103 code => $Foo->get_method($_)
104 }
105 } qw(
106 FOO_CONSTANT
107 bang
108 bar
109 baz
110 blah
111 bling
112 evaled_foo
113 floob
114 foo
115 )
116 ],
117 '... got the right list of applicable methods for Foo');
118
c9b8b7f9 119is($Foo->remove_method('foo'), $foo, '... removed the foo method');
120ok(!$Foo->has_method('foo'), '... !Foo->has_method(foo) we just removed it');
121dies_ok { Foo->foo } '... cannot call Foo->foo because it is not there';
122
123is_deeply(
124 [ sort $Foo->get_method_list ],
125 [ qw(FOO_CONSTANT bang bar baz blah bling evaled_foo floob) ],
126 '... got the right method list for Foo');
127
128ok($Foo->remove_method('FOO_CONSTANT'), '... removed the FOO_CONSTANT method');
129ok(!$Foo->has_method('FOO_CONSTANT'), '... !Foo->has_method(FOO_CONSTANT) we just removed it');
130dies_ok { Foo->FOO_CONSTANT } '... cannot call Foo->FOO_CONSTANT because it is not there';
131
132is_deeply(
133 [ sort $Foo->get_method_list ],
134 [ qw(bang bar baz blah bling evaled_foo floob) ],
135 '... got the right method list for Foo');
136
bfe4d0fc 137# ... test our class creator
138
139my $Bar = Class::MOP::Class->create(
140 'Bar' => '0.10' => (
c9b8b7f9 141 superclasses => [ 'Foo' ],
bfe4d0fc 142 methods => {
143 foo => sub { 'Bar::foo' },
144 bar => sub { 'Bar::bar' },
145 }
146 ));
147isa_ok($Bar, 'Class::MOP::Class');
148
149ok($Bar->has_method('foo'), '... Bar->has_method(foo)');
150ok($Bar->has_method('bar'), '... Bar->has_method(bar)');
151
152is(Bar->foo, 'Bar::foo', '... Bar->foo == Bar::foo');
153is(Bar->bar, 'Bar::bar', '... Bar->bar == Bar::bar');
154
155lives_ok {
156 $Bar->add_method('foo' => sub { 'Bar::foo v2' });
157} '... overwriting a method is fine';
158
159ok($Bar->has_method('foo'), '... Bar-> (still) has_method(foo)');
160is(Bar->foo, 'Bar::foo v2', '... Bar->foo == "Bar::foo v2"');
c9b8b7f9 161
162is_deeply(
163 [ sort $Bar->get_method_list ],
aa448b16 164 [ qw(bar foo meta) ],
a5eca695 165 '... got the right method list for Bar');
166
167is_deeply(
168 [ sort { $a->{name} cmp $b->{name} } $Bar->compute_all_applicable_methods() ],
169 [
170 {
171 name => 'bang',
172 class => 'Foo',
173 code => $Foo->get_method('bang')
174 },
175 {
176 name => 'bar',
177 class => 'Bar',
178 code => $Bar->get_method('bar')
179 },
180 (map {
181 {
182 name => $_,
183 class => 'Foo',
184 code => $Foo->get_method($_)
185 }
186 } qw(
187 baz
188 blah
189 bling
190 evaled_foo
191 floob
192 )),
193 {
194 name => 'foo',
195 class => 'Bar',
196 code => $Bar->get_method('foo')
197 },
aa448b16 198 {
199 name => 'meta',
200 class => 'Bar',
201 code => $Bar->get_method('meta')
202 }
a5eca695 203 ],
204 '... got the right list of applicable methods for Bar');
205
206