adding another test
[gitmo/Class-MOP.git] / t / 003_methods.t
CommitLineData
0882828e 1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
1a7ebbb3 6use Test::More tests => 38;
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
bfe4d0fc 74ok(!$Foo->has_method('blessed'), '... !Foo->has_method(blessed) (imported into Foo)');
75ok(!$Foo->has_method('boom'), '... !Foo->has_method(boom) (defined in main:: using symbol tables and Sub::Name w/out package name)');
0882828e 76
bfe4d0fc 77ok(!$Foo->has_method('not_a_real_method'), '... !Foo->has_method(not_a_real_method) (does not exist)');
78is($Foo->get_method('not_a_real_method'), undef, '... Foo->get_method(not_a_real_method) == undef');
79
c9b8b7f9 80is_deeply(
81 [ sort $Foo->get_method_list ],
82 [ qw(FOO_CONSTANT bang bar baz blah bling evaled_foo floob foo) ],
83 '... got the right method list for Foo');
84
a5eca695 85is_deeply(
86 [ sort { $a->{name} cmp $b->{name} } $Foo->compute_all_applicable_methods() ],
87 [
88 map {
89 {
90 name => $_,
91 class => 'Foo',
92 code => $Foo->get_method($_)
93 }
94 } qw(
95 FOO_CONSTANT
96 bang
97 bar
98 baz
99 blah
100 bling
101 evaled_foo
102 floob
103 foo
104 )
105 ],
106 '... got the right list of applicable methods for Foo');
107
c9b8b7f9 108is($Foo->remove_method('foo'), $foo, '... removed the foo method');
109ok(!$Foo->has_method('foo'), '... !Foo->has_method(foo) we just removed it');
110dies_ok { Foo->foo } '... cannot call Foo->foo because it is not there';
111
112is_deeply(
113 [ sort $Foo->get_method_list ],
114 [ qw(FOO_CONSTANT bang bar baz blah bling evaled_foo floob) ],
115 '... got the right method list for Foo');
116
117ok($Foo->remove_method('FOO_CONSTANT'), '... removed the FOO_CONSTANT method');
118ok(!$Foo->has_method('FOO_CONSTANT'), '... !Foo->has_method(FOO_CONSTANT) we just removed it');
119dies_ok { Foo->FOO_CONSTANT } '... cannot call Foo->FOO_CONSTANT because it is not there';
120
121is_deeply(
122 [ sort $Foo->get_method_list ],
123 [ qw(bang bar baz blah bling evaled_foo floob) ],
124 '... got the right method list for Foo');
125
bfe4d0fc 126# ... test our class creator
127
128my $Bar = Class::MOP::Class->create(
129 'Bar' => '0.10' => (
c9b8b7f9 130 superclasses => [ 'Foo' ],
bfe4d0fc 131 methods => {
132 foo => sub { 'Bar::foo' },
133 bar => sub { 'Bar::bar' },
134 }
135 ));
136isa_ok($Bar, 'Class::MOP::Class');
137
138ok($Bar->has_method('foo'), '... Bar->has_method(foo)');
139ok($Bar->has_method('bar'), '... Bar->has_method(bar)');
140
141is(Bar->foo, 'Bar::foo', '... Bar->foo == Bar::foo');
142is(Bar->bar, 'Bar::bar', '... Bar->bar == Bar::bar');
143
144lives_ok {
145 $Bar->add_method('foo' => sub { 'Bar::foo v2' });
146} '... overwriting a method is fine';
147
148ok($Bar->has_method('foo'), '... Bar-> (still) has_method(foo)');
149is(Bar->foo, 'Bar::foo v2', '... Bar->foo == "Bar::foo v2"');
c9b8b7f9 150
151is_deeply(
152 [ sort $Bar->get_method_list ],
153 [ qw(bar foo) ],
a5eca695 154 '... got the right method list for Bar');
155
156is_deeply(
157 [ sort { $a->{name} cmp $b->{name} } $Bar->compute_all_applicable_methods() ],
158 [
159 {
160 name => 'bang',
161 class => 'Foo',
162 code => $Foo->get_method('bang')
163 },
164 {
165 name => 'bar',
166 class => 'Bar',
167 code => $Bar->get_method('bar')
168 },
169 (map {
170 {
171 name => $_,
172 class => 'Foo',
173 code => $Foo->get_method($_)
174 }
175 } qw(
176 baz
177 blah
178 bling
179 evaled_foo
180 floob
181 )),
182 {
183 name => 'foo',
184 class => 'Bar',
185 code => $Bar->get_method('foo')
186 },
187 ],
188 '... got the right list of applicable methods for Bar');
189
190