4ef0554b12229a773e49f53df4f0c91e4f116c4b
[gitmo/Class-MOP.git] / t / 080_meta_package.t
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use Test::More tests => 97;
7 use Test::Exception;
8
9 use Class::MOP;
10 use Class::MOP::Package;
11
12
13 dies_ok { Class::MOP::Package->get_all_package_symbols } q{... can't call get_all_package_symbols() as a class method};
14 dies_ok { Class::MOP::Package->name } q{... can't call name() as a class method};
15
16 {
17     package Foo;
18
19     use constant SOME_CONSTANT => 1;
20     
21     sub meta { Class::MOP::Package->initialize('Foo') }
22 }
23
24 # ----------------------------------------------------------------------
25 ## tests adding a HASH
26
27 ok(!defined($Foo::{foo}), '... the %foo slot has not been created yet');
28 ok(!Foo->meta->has_package_symbol('%foo'), '... the meta agrees');
29 ok(!defined($Foo::{foo}), '... checking doesn\' vivify');
30
31 lives_ok {
32     Foo->meta->add_package_symbol('%foo' => { one => 1 });
33 } '... created %Foo::foo successfully';
34
35 # ... scalar should NOT be created here 
36
37 ok(!Foo->meta->has_package_symbol('$foo'), '... SCALAR shouldnt have been created too');
38 ok(!Foo->meta->has_package_symbol('@foo'), '... ARRAY shouldnt have been created too');
39 ok(!Foo->meta->has_package_symbol('&foo'), '... CODE shouldnt have been created too');
40
41 ok(defined($Foo::{foo}), '... the %foo slot was created successfully');
42 ok(Foo->meta->has_package_symbol('%foo'), '... the meta agrees');
43
44 # check the value ...
45
46 {
47     no strict 'refs';
48     ok(exists ${'Foo::foo'}{one}, '... our %foo was initialized correctly');
49     is(${'Foo::foo'}{one}, 1, '... our %foo was initialized correctly');
50 }
51
52 my $foo = Foo->meta->get_package_symbol('%foo');
53 is_deeply({ one => 1 }, $foo, '... got the right package variable back');
54
55 # ... make sure changes propogate up
56
57 $foo->{two} = 2;
58
59 {
60     no strict 'refs';
61     is(\%{'Foo::foo'}, Foo->meta->get_package_symbol('%foo'), '... our %foo is the same as the metas');
62     
63     ok(exists ${'Foo::foo'}{two}, '... our %foo was updated correctly');
64     is(${'Foo::foo'}{two}, 2, '... our %foo was updated correctly');    
65 }
66
67 # ----------------------------------------------------------------------
68 ## test adding an ARRAY
69
70 ok(!defined($Foo::{bar}), '... the @bar slot has not been created yet');
71
72 lives_ok {
73     Foo->meta->add_package_symbol('@bar' => [ 1, 2, 3 ]);
74 } '... created @Foo::bar successfully';
75
76 ok(defined($Foo::{bar}), '... the @bar slot was created successfully');
77 ok(Foo->meta->has_package_symbol('@bar'), '... the meta agrees');
78
79 # ... why does this not work ... 
80
81 ok(!Foo->meta->has_package_symbol('$bar'), '... SCALAR shouldnt have been created too');
82 ok(!Foo->meta->has_package_symbol('%bar'), '... HASH shouldnt have been created too');
83 ok(!Foo->meta->has_package_symbol('&bar'), '... CODE shouldnt have been created too');
84
85 # check the value itself
86
87 {
88     no strict 'refs';
89     is(scalar @{'Foo::bar'}, 3, '... our @bar was initialized correctly');
90     is(${'Foo::bar'}[1], 2, '... our @bar was initialized correctly');
91 }
92
93 # ----------------------------------------------------------------------
94 ## test adding a SCALAR
95
96 ok(!defined($Foo::{baz}), '... the $baz slot has not been created yet');
97
98 lives_ok {
99     Foo->meta->add_package_symbol('$baz' => 10);
100 } '... created $Foo::baz successfully';
101
102 ok(defined($Foo::{baz}), '... the $baz slot was created successfully');
103 ok(Foo->meta->has_package_symbol('$baz'), '... the meta agrees');
104
105 ok(!Foo->meta->has_package_symbol('@baz'), '... ARRAY shouldnt have been created too');
106 ok(!Foo->meta->has_package_symbol('%baz'), '... HASH shouldnt have been created too');
107 ok(!Foo->meta->has_package_symbol('&baz'), '... CODE shouldnt have been created too');
108
109 is(${Foo->meta->get_package_symbol('$baz')}, 10, '... got the right value back');   
110
111 {
112     no strict 'refs';
113     ${'Foo::baz'} = 1;
114
115     is(${'Foo::baz'}, 1, '... our $baz was assigned to correctly');
116     is(${Foo->meta->get_package_symbol('$baz')}, 1, '... the meta agrees');    
117 }
118
119 # ----------------------------------------------------------------------
120 ## test adding a CODE
121
122 ok(!defined($Foo::{funk}), '... the &funk slot has not been created yet');
123
124 lives_ok {
125     Foo->meta->add_package_symbol('&funk' => sub { "Foo::funk" });
126 } '... created &Foo::funk successfully';
127
128 ok(defined($Foo::{funk}), '... the &funk slot was created successfully');
129 ok(Foo->meta->has_package_symbol('&funk'), '... the meta agrees');
130
131 ok(!Foo->meta->has_package_symbol('$funk'), '... SCALAR shouldnt have been created too');
132 ok(!Foo->meta->has_package_symbol('@funk'), '... ARRAY shouldnt have been created too');
133 ok(!Foo->meta->has_package_symbol('%funk'), '... HASH shouldnt have been created too');
134
135 {
136     no strict 'refs';
137     ok(defined &{'Foo::funk'}, '... our &funk exists');
138 }
139
140 is(Foo->funk(), 'Foo::funk', '... got the right value from the function');
141
142 # ----------------------------------------------------------------------
143 ## test multiple slots in the glob
144
145 my $ARRAY = [ 1, 2, 3 ];
146 my $CODE = sub { "Foo::foo" };
147
148 lives_ok {
149     Foo->meta->add_package_symbol('@foo' => $ARRAY);
150 } '... created @Foo::foo successfully';
151
152 ok(Foo->meta->has_package_symbol('@foo'), '... the @foo slot was added successfully');
153 is(Foo->meta->get_package_symbol('@foo'), $ARRAY, '... got the right values for @Foo::foo');
154
155 lives_ok {
156     Foo->meta->add_package_symbol('&foo' => $CODE);
157 } '... created &Foo::foo successfully';
158
159 ok(Foo->meta->has_package_symbol('&foo'), '... the meta agrees');
160 is(Foo->meta->get_package_symbol('&foo'), $CODE, '... got the right value for &Foo::foo');
161
162 lives_ok {
163     Foo->meta->add_package_symbol('$foo' => 'Foo::foo');
164 } '... created $Foo::foo successfully';
165
166 ok(Foo->meta->has_package_symbol('$foo'), '... the meta agrees');
167 my $SCALAR = Foo->meta->get_package_symbol('$foo');
168 is($$SCALAR, 'Foo::foo', '... got the right scalar value back');
169
170 {
171     no strict 'refs';
172     is(${'Foo::foo'}, 'Foo::foo', '... got the right value from the scalar');
173 }
174
175 lives_ok {
176     Foo->meta->remove_package_symbol('%foo');
177 } '... removed %Foo::foo successfully';
178
179 ok(!Foo->meta->has_package_symbol('%foo'), '... the %foo slot was removed successfully');
180 ok(Foo->meta->has_package_symbol('@foo'), '... the @foo slot still exists');
181 ok(Foo->meta->has_package_symbol('&foo'), '... the &foo slot still exists');
182 ok(Foo->meta->has_package_symbol('$foo'), '... the $foo slot still exists');
183
184 is(Foo->meta->get_package_symbol('@foo'), $ARRAY, '... got the right values for @Foo::foo');
185 is(Foo->meta->get_package_symbol('&foo'), $CODE, '... got the right value for &Foo::foo');
186 is(Foo->meta->get_package_symbol('$foo'), $SCALAR, '... got the right value for $Foo::foo');
187
188 {
189     no strict 'refs';
190     ok(!defined(*{"Foo::foo"}{HASH}), '... the %foo slot has been removed successfully');
191     ok(defined(*{"Foo::foo"}{ARRAY}), '... the @foo slot has NOT been removed');   
192     ok(defined(*{"Foo::foo"}{CODE}), '... the &foo slot has NOT been removed');   
193     ok(defined(${"Foo::foo"}), '... the $foo slot has NOT been removed');            
194 }
195
196 lives_ok {
197     Foo->meta->remove_package_symbol('&foo');
198 } '... removed &Foo::foo successfully';
199
200 ok(!Foo->meta->has_package_symbol('&foo'), '... the &foo slot no longer exists');
201
202 ok(Foo->meta->has_package_symbol('@foo'), '... the @foo slot still exists');
203 ok(Foo->meta->has_package_symbol('$foo'), '... the $foo slot still exists');
204
205 is(Foo->meta->get_package_symbol('@foo'), $ARRAY, '... got the right values for @Foo::foo');
206 is(Foo->meta->get_package_symbol('$foo'), $SCALAR, '... got the right value for $Foo::foo');
207
208 {
209     no strict 'refs';
210     ok(!defined(*{"Foo::foo"}{HASH}), '... the %foo slot has been removed successfully');    
211     ok(!defined(*{"Foo::foo"}{CODE}), '... the &foo slot has now been removed');       
212     ok(defined(*{"Foo::foo"}{ARRAY}), '... the @foo slot has NOT been removed');   
213     ok(defined(${"Foo::foo"}), '... the $foo slot has NOT been removed');            
214 }
215
216 lives_ok {
217     Foo->meta->remove_package_symbol('$foo');
218 } '... removed $Foo::foo successfully';
219
220 ok(!Foo->meta->has_package_symbol('$foo'), '... the $foo slot no longer exists');
221
222 ok(Foo->meta->has_package_symbol('@foo'), '... the @foo slot still exists');
223
224 is(Foo->meta->get_package_symbol('@foo'), $ARRAY, '... got the right values for @Foo::foo');
225
226 {
227     no strict 'refs';
228     ok(!defined(*{"Foo::foo"}{HASH}), '... the %foo slot has been removed successfully');    
229     ok(!defined(*{"Foo::foo"}{CODE}), '... the &foo slot has now been removed');   
230     ok(!defined(${"Foo::foo"}), '... the $foo slot has now been removed');                           
231     ok(defined(*{"Foo::foo"}{ARRAY}), '... the @foo slot has NOT been removed');    
232 }
233
234 # get_all_package_symbols
235
236 {
237     my $syms = Foo->meta->get_all_package_symbols;
238     is_deeply(
239         [ sort keys %{ $syms } ],
240         [ sort Foo->meta->list_all_package_symbols ],
241         '... the fetched symbols are the same as the listed ones'
242     ); 
243 }
244
245 {
246     my $syms = Foo->meta->get_all_package_symbols('CODE');
247
248     is_deeply(
249         [ sort keys %{ $syms } ],
250         [ sort Foo->meta->list_all_package_symbols('CODE') ],
251         '... the fetched symbols are the same as the listed ones'
252     );
253     
254     foreach my $symbol (keys %{ $syms }) {
255         is($syms->{$symbol}, Foo->meta->get_package_symbol('&' . $symbol), '... got the right symbol');
256     } 
257 }
258
259 {
260     Foo->meta->add_package_symbol('%zork');
261
262     my $syms = Foo->meta->get_all_package_symbols('HASH');
263
264     is_deeply(
265         [ sort keys %{ $syms } ],
266         [ sort Foo->meta->list_all_package_symbols('HASH') ],
267         '... the fetched symbols are the same as the listed ones'
268     );
269
270     foreach my $symbol (keys %{ $syms }) {
271         is($syms->{$symbol}, Foo->meta->get_package_symbol('%' . $symbol), '... got the right symbol');
272     }
273
274     no warnings 'once';
275     is_deeply(
276         $syms,
277         { zork => \%Foo::zork },
278         "got the right ones",
279     );
280 }
281 # check some errors
282
283 dies_ok {
284     Foo->meta->add_package_symbol('bar');
285 } '... no sigil for bar';
286
287 dies_ok {
288     Foo->meta->remove_package_symbol('bar');
289 } '... no sigil for bar';
290
291 dies_ok {
292     Foo->meta->get_package_symbol('bar');
293 } '... no sigil for bar';
294
295 dies_ok {
296     Foo->meta->has_package_symbol('bar');
297 } '... no sigil for bar';