add tests for wrapping a method metaobject
[gitmo/Class-MOP.git] / t / 031_method_modifiers.t
CommitLineData
de19f115 1use strict;
2use warnings;
3
779ca3d2 4use Test::More tests => 28;
de19f115 5use Test::Exception;
6
e5698763 7use Class::MOP;
8use Class::MOP::Method;
de19f115 9
855d2774 10# test before and afters
11{
3d269564 12 my $trace = '';
13
14 my $method = Class::MOP::Method->wrap(
15 body => sub { $trace .= 'primary' },
16 package_name => 'main',
17 name => '__ANON__',
18 );
19 isa_ok( $method, 'Class::MOP::Method' );
20
21 $method->();
22 is( $trace, 'primary', '... got the right return value from method' );
23 $trace = '';
24
25 my $wrapped = Class::MOP::Method::Wrapped->wrap($method);
26 isa_ok( $wrapped, 'Class::MOP::Method::Wrapped' );
27 isa_ok( $wrapped, 'Class::MOP::Method' );
28
29 $wrapped->();
30 is( $trace, 'primary',
31 '... got the right return value from the wrapped method' );
32 $trace = '';
33
34 lives_ok {
35 $wrapped->add_before_modifier( sub { $trace .= 'before -> ' } );
36 }
37 '... added the before modifier okay';
38
39 $wrapped->();
40 is( $trace, 'before -> primary',
41 '... got the right return value from the wrapped method (w/ before)'
42 );
43 $trace = '';
44
45 lives_ok {
46 $wrapped->add_after_modifier( sub { $trace .= ' -> after' } );
47 }
48 '... added the after modifier okay';
49
50 $wrapped->();
51 is( $trace, 'before -> primary -> after',
52 '... got the right return value from the wrapped method (w/ before)'
53 );
54 $trace = '';
855d2774 55}
56
57# test around method
58{
3d269564 59 my $method = Class::MOP::Method->wrap(
60 sub {4},
61 package_name => 'main',
62 name => '__ANON__',
63 );
64 isa_ok( $method, 'Class::MOP::Method' );
65
66 is( $method->(), 4, '... got the right value from the wrapped method' );
67
68 my $wrapped = Class::MOP::Method::Wrapped->wrap($method);
69 isa_ok( $wrapped, 'Class::MOP::Method::Wrapped' );
70 isa_ok( $wrapped, 'Class::MOP::Method' );
71
72 is( $wrapped->(), 4, '... got the right value from the wrapped method' );
73
74 lives_ok {
75 $wrapped->add_around_modifier( sub { ( 3, $_[0]->() ) } );
76 $wrapped->add_around_modifier( sub { ( 2, $_[0]->() ) } );
77 $wrapped->add_around_modifier( sub { ( 1, $_[0]->() ) } );
78 $wrapped->add_around_modifier( sub { ( 0, $_[0]->() ) } );
79 }
80 '... added the around modifier okay';
81
82 is_deeply(
83 [ $wrapped->() ],
84 [ 0, 1, 2, 3, 4 ],
85 '... got the right results back from the around methods (in list context)'
86 );
87
88 is( scalar $wrapped->(), 4,
89 '... got the right results back from the around methods (in scalar context)'
90 );
855d2774 91}
de19f115 92
ee5e71d4 93{
3d269564 94 my @tracelog;
95
96 my $method = Class::MOP::Method->wrap(
97 sub { push @tracelog => 'primary' },
98 package_name => 'main',
99 name => '__ANON__',
100 );
101 isa_ok( $method, 'Class::MOP::Method' );
102
103 my $wrapped = Class::MOP::Method::Wrapped->wrap($method);
104 isa_ok( $wrapped, 'Class::MOP::Method::Wrapped' );
105 isa_ok( $wrapped, 'Class::MOP::Method' );
106
107 lives_ok {
108 $wrapped->add_before_modifier( sub { push @tracelog => 'before 1' } );
109 $wrapped->add_before_modifier( sub { push @tracelog => 'before 2' } );
110 $wrapped->add_before_modifier( sub { push @tracelog => 'before 3' } );
111 }
112 '... added the before modifier okay';
113
114 lives_ok {
115 $wrapped->add_around_modifier(
116 sub { push @tracelog => 'around 1'; $_[0]->(); } );
117 $wrapped->add_around_modifier(
118 sub { push @tracelog => 'around 2'; $_[0]->(); } );
119 $wrapped->add_around_modifier(
120 sub { push @tracelog => 'around 3'; $_[0]->(); } );
121 }
122 '... added the around modifier okay';
123
124 lives_ok {
125 $wrapped->add_after_modifier( sub { push @tracelog => 'after 1' } );
126 $wrapped->add_after_modifier( sub { push @tracelog => 'after 2' } );
127 $wrapped->add_after_modifier( sub { push @tracelog => 'after 3' } );
128 }
129 '... added the after modifier okay';
130
131 $wrapped->();
132 is_deeply(
133 \@tracelog,
134 [
135 'before 3', 'before 2', 'before 1', # last-in-first-out order
136 'around 3', 'around 2', 'around 1', # last-in-first-out order
137 'primary',
138 'after 1', 'after 2', 'after 3', # first-in-first-out order
139 ],
140 '... got the right tracelog from all our before/around/after methods'
141 );
ee5e71d4 142}
de19f115 143
b88aa2e8 144# test introspection
145{
146 sub before1 {
147 }
148
149 sub before2 {
150 }
151
152 sub before3 {
153 }
154
155 sub after1 {
156 }
157
158 sub after2 {
159 }
160
161 sub after3 {
162 }
163
164 sub around1 {
165 }
166
167 sub around2 {
168 }
169
170 sub around3 {
171 }
172
173 sub orig {
174 }
175
176 my $method = Class::MOP::Method->wrap(
177 body => \&orig,
178 package_name => 'main',
179 name => '__ANON__',
180 );
181
182 my $wrapped = Class::MOP::Method::Wrapped->wrap($method);
183
184 $wrapped->add_before_modifier($_)
185 for \&before1, \&before2, \&before3;
186
187 $wrapped->add_after_modifier($_)
188 for \&after1, \&after2, \&after3;
189
190 $wrapped->add_around_modifier($_)
191 for \&around1, \&around2, \&around3;
192
193 is( $wrapped->get_original_method, $method,
194 'check get_original_method' );
195
196 is_deeply( [ $wrapped->before_modifiers ],
197 [ \&before3, \&before2, \&before1 ],
198 'check before_modifiers' );
199
200 is_deeply( [ $wrapped->after_modifiers ],
201 [ \&after1, \&after2, \&after3 ],
202 'check after_modifiers' );
203
204 is_deeply( [ $wrapped->around_modifiers ],
205 [ \&around3, \&around2, \&around1 ],
206 'check around_modifiers' );
207}
208