bunch of stuff
[gitmo/Class-MOP.git] / t / 003_methods.t
CommitLineData
0882828e 1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
de19f115 6use Test::More tests => 52;
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
de19f115 54ok(!UNIVERSAL::isa($foo, 'Class::MOP::Method'), '... our method is not yet blessed');
55
0882828e 56lives_ok {
57 $Foo->add_method('foo' => $foo);
58} '... we added the method successfully';
59
de19f115 60isa_ok($foo, 'Class::MOP::Method');
61
62is($foo->name, 'foo', '... got the right name for the method');
63is($foo->package_name, 'Foo', '... got the right package name for the method');
64
0882828e 65ok($Foo->has_method('foo'), '... Foo->has_method(foo) (defined with Sub::Name)');
bfe4d0fc 66
67is($Foo->get_method('foo'), $foo, '... Foo->get_method(foo) == \&foo');
68is(Foo->foo(), 'Foo::foo', '... Foo->foo() returns "Foo::foo"');
69
70# now check all our other items ...
71
72ok($Foo->has_method('FOO_CONSTANT'), '... Foo->has_method(FOO_CONSTANT) (defined w/ use constant)');
0882828e 73ok($Foo->has_method('bar'), '... Foo->has_method(bar) (defined in Foo)');
60d90bbc 74ok($Foo->has_method('baz'), '... Foo->has_method(baz) (typeglob aliased within Foo)');
bfe4d0fc 75ok($Foo->has_method('floob'), '... Foo->has_method(floob) (defined in Foo:: using symbol tables and Sub::Name w/out package name)');
60d90bbc 76ok($Foo->has_method('blah'), '... Foo->has_method(blah) (defined in main:: using fully qualified package name)');
bfe4d0fc 77ok($Foo->has_method('bling'), '... Foo->has_method(bling) (defined in main:: using symbol tables (no Sub::Name))');
60d90bbc 78ok($Foo->has_method('bang'), '... Foo->has_method(bang) (defined in main:: using symbol tables and Sub::Name)');
bfe4d0fc 79ok($Foo->has_method('evaled_foo'), '... Foo->has_method(evaled_foo) (evaled in main::)');
0882828e 80
de19f115 81# calling get_method blessed them all
82isa_ok($_, 'Class::MOP::Method') for (
83 \&Foo::FOO_CONSTANT,
84 \&Foo::bar,
85 \&Foo::baz,
86 \&Foo::floob,
87 \&Foo::blah,
88 \&Foo::bling,
89 \&Foo::bang,
90 \&Foo::evaled_foo,
91 );
92
663f8198 93{
94 package Foo::Aliasing;
95 use metaclass;
96 sub alias_me { '...' }
97}
98
99$Foo->alias_method('alias_me' => Foo::Aliasing->meta->get_method('alias_me'));
100
101ok(!$Foo->has_method('alias_me'), '... !Foo->has_method(alias_me) (aliased from Foo::Aliasing)');
102ok(defined &Foo::alias_me, '... Foo does have a symbol table slow for alias_me though');
103
bfe4d0fc 104ok(!$Foo->has_method('blessed'), '... !Foo->has_method(blessed) (imported into Foo)');
105ok(!$Foo->has_method('boom'), '... !Foo->has_method(boom) (defined in main:: using symbol tables and Sub::Name w/out package name)');
0882828e 106
bfe4d0fc 107ok(!$Foo->has_method('not_a_real_method'), '... !Foo->has_method(not_a_real_method) (does not exist)');
108is($Foo->get_method('not_a_real_method'), undef, '... Foo->get_method(not_a_real_method) == undef');
109
c9b8b7f9 110is_deeply(
111 [ sort $Foo->get_method_list ],
112 [ qw(FOO_CONSTANT bang bar baz blah bling evaled_foo floob foo) ],
113 '... got the right method list for Foo');
114
a5eca695 115is_deeply(
116 [ sort { $a->{name} cmp $b->{name} } $Foo->compute_all_applicable_methods() ],
117 [
118 map {
119 {
120 name => $_,
121 class => 'Foo',
122 code => $Foo->get_method($_)
123 }
124 } qw(
125 FOO_CONSTANT
126 bang
127 bar
128 baz
129 blah
130 bling
131 evaled_foo
132 floob
133 foo
134 )
135 ],
136 '... got the right list of applicable methods for Foo');
137
c9b8b7f9 138is($Foo->remove_method('foo'), $foo, '... removed the foo method');
139ok(!$Foo->has_method('foo'), '... !Foo->has_method(foo) we just removed it');
140dies_ok { Foo->foo } '... cannot call Foo->foo because it is not there';
141
142is_deeply(
143 [ sort $Foo->get_method_list ],
144 [ qw(FOO_CONSTANT bang bar baz blah bling evaled_foo floob) ],
145 '... got the right method list for Foo');
146
147ok($Foo->remove_method('FOO_CONSTANT'), '... removed the FOO_CONSTANT method');
148ok(!$Foo->has_method('FOO_CONSTANT'), '... !Foo->has_method(FOO_CONSTANT) we just removed it');
149dies_ok { Foo->FOO_CONSTANT } '... cannot call Foo->FOO_CONSTANT because it is not there';
150
151is_deeply(
152 [ sort $Foo->get_method_list ],
153 [ qw(bang bar baz blah bling evaled_foo floob) ],
154 '... got the right method list for Foo');
155
bfe4d0fc 156# ... test our class creator
157
158my $Bar = Class::MOP::Class->create(
159 'Bar' => '0.10' => (
c9b8b7f9 160 superclasses => [ 'Foo' ],
bfe4d0fc 161 methods => {
162 foo => sub { 'Bar::foo' },
163 bar => sub { 'Bar::bar' },
164 }
165 ));
166isa_ok($Bar, 'Class::MOP::Class');
167
168ok($Bar->has_method('foo'), '... Bar->has_method(foo)');
169ok($Bar->has_method('bar'), '... Bar->has_method(bar)');
170
171is(Bar->foo, 'Bar::foo', '... Bar->foo == Bar::foo');
172is(Bar->bar, 'Bar::bar', '... Bar->bar == Bar::bar');
173
174lives_ok {
175 $Bar->add_method('foo' => sub { 'Bar::foo v2' });
176} '... overwriting a method is fine';
177
178ok($Bar->has_method('foo'), '... Bar-> (still) has_method(foo)');
179is(Bar->foo, 'Bar::foo v2', '... Bar->foo == "Bar::foo v2"');
c9b8b7f9 180
181is_deeply(
182 [ sort $Bar->get_method_list ],
aa448b16 183 [ qw(bar foo meta) ],
a5eca695 184 '... got the right method list for Bar');
185
186is_deeply(
187 [ sort { $a->{name} cmp $b->{name} } $Bar->compute_all_applicable_methods() ],
188 [
189 {
190 name => 'bang',
191 class => 'Foo',
192 code => $Foo->get_method('bang')
193 },
194 {
195 name => 'bar',
196 class => 'Bar',
197 code => $Bar->get_method('bar')
198 },
199 (map {
200 {
201 name => $_,
202 class => 'Foo',
203 code => $Foo->get_method($_)
204 }
205 } qw(
206 baz
207 blah
208 bling
209 evaled_foo
210 floob
211 )),
212 {
213 name => 'foo',
214 class => 'Bar',
215 code => $Bar->get_method('foo')
216 },
aa448b16 217 {
218 name => 'meta',
219 class => 'Bar',
220 code => $Bar->get_method('meta')
221 }
a5eca695 222 ],
223 '... got the right list of applicable methods for Bar');
224
225