Remove mention of compute_all_applicable_attributes
[gitmo/Class-MOP.git] / t / 073_make_mutable.t
CommitLineData
0ac992ee 1use strict;
2use warnings;
3
070cb0d6 4use Test::More tests => 101;
0ac992ee 5use Test::Exception;
6
7use Scalar::Util;
8
efd3d14c 9use Class::MOP;
0ac992ee 10
11{
12 package Foo;
13
14 use strict;
15 use warnings;
16 use metaclass;
17
18 __PACKAGE__->meta->add_attribute('bar');
19
20 package Bar;
21
22 use strict;
23 use warnings;
24 use metaclass;
25
26 __PACKAGE__->meta->superclasses('Foo');
27
28 __PACKAGE__->meta->add_attribute('baz');
29
30 package Baz;
31
32 use strict;
33 use warnings;
34 use metaclass;
35
36 __PACKAGE__->meta->superclasses('Bar');
37
38 __PACKAGE__->meta->add_attribute('bah');
39}
40
41{
42 my $meta = Baz->meta;
43 is($meta->name, 'Baz', '... checking the Baz metaclass');
44d6ea77 44 my %orig_keys = map { $_ => 1 } grep { !/^_/ } keys %$meta;
45 # Since this has no default it won't be present yet, but it will
46 # be after the class is made immutable.
47 $orig_keys{immutable_transformer} = 1;
0ac992ee 48
04dd7510 49 lives_ok {$meta->make_immutable; } '... changed Baz to be immutable';
0ac992ee 50 ok(!$meta->is_mutable, '... our class is no longer mutable');
51 ok($meta->is_immutable, '... our class is now immutable');
52 ok(!$meta->make_immutable, '... make immutable now returns nothing');
229910b5 53 ok($meta->get_method_map->{new}, '... inlined constructor created');
46b23b44 54 ok($meta->has_method('new'), '... inlined constructor created for sure');
44d6ea77 55 ok($meta->immutable_transformer->inlined_constructor,
c1809cb1 56 '... transformer says it did inline the constructor');
0ac992ee 57
04dd7510 58 lives_ok { $meta->make_mutable; } '... changed Baz to be mutable';
0ac992ee 59 ok($meta->is_mutable, '... our class is mutable');
60 ok(!$meta->is_immutable, '... our class is not immutable');
61 ok(!$meta->make_mutable, '... make mutable now returns nothing');
229910b5 62 ok(!$meta->get_method_map->{new}, '... inlined constructor removed');
46b23b44 63 ok(!$meta->has_method('new'), '... inlined constructor removed for sure');
44d6ea77 64 ok(!$meta->immutable_transformer->inlined_constructor,
c1809cb1 65 '... transformer says it did not inline the constructor');
0ac992ee 66
44d6ea77 67 my %new_keys = map { $_ => 1 } grep { !/^_/ } keys %$meta;
68 is_deeply(\%orig_keys, \%new_keys, '... no extraneous hashkeys');
0ac992ee 69
70 isa_ok($meta, 'Class::MOP::Class', '... Baz->meta isa Class::MOP::Class');
71
72 ok( $meta->add_method('xyz', sub{'xxx'}), '... added method');
73 is( Baz->xyz, 'xxx', '... method xyz works');
46b23b44 74
0ac992ee 75 ok($meta->add_attribute('fickle', accessor => 'fickle'), '... added attribute');
76 ok(Baz->can('fickle'), '... Baz can fickle');
77 ok($meta->remove_attribute('fickle'), '... removed attribute');
78
79 my $reef = \ 'reef';
80 ok($meta->add_package_symbol('$ref', $reef), '... added package symbol');
81 is($meta->get_package_symbol('$ref'), $reef, '... values match');
82 lives_ok { $meta->remove_package_symbol('$ref') } '... removed it';
83 isnt($meta->get_package_symbol('$ref'), $reef, '... values match');
84
85 ok( my @supers = $meta->superclasses, '... got the superclasses okay');
86 ok( $meta->superclasses('Foo'), '... set the superclasses');
87 is_deeply(['Foo'], [$meta->superclasses], '... set the superclasses okay');
88 ok( $meta->superclasses( @supers ), '... reset superclasses');
89 is_deeply([@supers], [$meta->superclasses], '... reset the superclasses okay');
90
91 ok( $meta->$_ , "... ${_} works")
92 for qw(get_meta_instance compute_all_applicable_attributes
93 class_precedence_list get_method_map );
229910b5 94
95 lives_ok {$meta->make_immutable; } '... changed Baz to be immutable again';
96 ok($meta->get_method_map->{new}, '... inlined constructor recreated');
0ac992ee 97}
98
99{
100 my $meta = Baz->meta;
101
102 lives_ok { $meta->make_immutable() } 'Changed Baz to be immutable';
103 lives_ok { $meta->make_mutable() } '... changed Baz to be mutable';
104 lives_ok { $meta->make_immutable() } '... changed Baz to be immutable';
105
106 dies_ok{ $meta->add_method('xyz', sub{'xxx'}) } '... exception thrown as expected';
0ac992ee 107
108 dies_ok {
109 $meta->add_attribute('fickle', accessor => 'fickle')
110 } '... exception thrown as expected';
111 dies_ok { $meta->remove_attribute('fickle') } '... exception thrown as expected';
112
113 my $reef = \ 'reef';
114 dies_ok { $meta->add_package_symbol('$ref', $reef) } '... exception thrown as expected';
115 dies_ok { $meta->remove_package_symbol('$ref') } '... exception thrown as expected';
116
117 ok( my @supers = $meta->superclasses, '... got the superclasses okay');
118 dies_ok { $meta->superclasses('Foo') } '... set the superclasses';
119
120 ok( $meta->$_ , "... ${_} works")
121 for qw(get_meta_instance compute_all_applicable_attributes
122 class_precedence_list get_method_map );
123}
124
0ac992ee 125{
126
d9586da2 127 ok(Baz->meta->is_immutable, 'Superclass is immutable');
0ac992ee 128 my $meta = Baz->meta->create_anon_class(superclasses => ['Baz']);
44d6ea77 129 my %orig_keys = map { $_ => 1 } grep { !/^_/ } keys %$meta;
130 $orig_keys{immutable_transformer} = 1;
070cb0d6 131 my @orig_meths = sort { $a->name cmp $b->name }
132 $meta->get_all_methods;
0ac992ee 133 ok($meta->is_anon_class, 'We have an anon metaclass');
d9586da2 134 ok($meta->is_mutable, '... our anon class is mutable');
135 ok(!$meta->is_immutable, '... our anon class is not immutable');
136
0ac992ee 137 lives_ok {$meta->make_immutable(
138 inline_accessor => 1,
139 inline_destructor => 0,
140 inline_constructor => 1,
141 )
142 } '... changed class to be immutable';
143 ok(!$meta->is_mutable, '... our class is no longer mutable');
144 ok($meta->is_immutable, '... our class is now immutable');
145 ok(!$meta->make_immutable, '... make immutable now returns nothing');
146
147 lives_ok { $meta->make_mutable } '... changed Baz to be mutable';
148 ok($meta->is_mutable, '... our class is mutable');
149 ok(!$meta->is_immutable, '... our class is not immutable');
150 ok(!$meta->make_mutable, '... make mutable now returns nothing');
151 ok($meta->is_anon_class, '... still marked as an anon class');
152 my $instance = $meta->new_object;
153
44d6ea77 154 my %new_keys = map { $_ => 1 } grep { !/^_/ } keys %$meta;
070cb0d6 155 my @new_meths = sort { $a->name cmp $b->name }
156 $meta->get_all_methods;
44d6ea77 157 is_deeply(\%orig_keys, \%new_keys, '... no extraneous hashkeys');
0ac992ee 158 is_deeply(\@orig_meths, \@new_meths, '... no straneous methods');
159
160 isa_ok($meta, 'Class::MOP::Class', '... Anon class isa Class::MOP::Class');
161
162 ok( $meta->add_method('xyz', sub{'xxx'}), '... added method');
163 is( $instance->xyz , 'xxx', '... method xyz works');
0ac992ee 164 ok( $meta->remove_method('xyz'), '... removed method');
0ac992ee 165
166 ok($meta->add_attribute('fickle', accessor => 'fickle'), '... added attribute');
167 ok($instance->can('fickle'), '... instance can fickle');
168 ok($meta->remove_attribute('fickle'), '... removed attribute');
169
170 my $reef = \ 'reef';
171 ok($meta->add_package_symbol('$ref', $reef), '... added package symbol');
172 is($meta->get_package_symbol('$ref'), $reef, '... values match');
173 lives_ok { $meta->remove_package_symbol('$ref') } '... removed it';
174 isnt($meta->get_package_symbol('$ref'), $reef, '... values match');
175
176 ok( my @supers = $meta->superclasses, '... got the superclasses okay');
177 ok( $meta->superclasses('Foo'), '... set the superclasses');
178 is_deeply(['Foo'], [$meta->superclasses], '... set the superclasses okay');
179 ok( $meta->superclasses( @supers ), '... reset superclasses');
180 is_deeply([@supers], [$meta->superclasses], '... reset the superclasses okay');
181
182 ok( $meta->$_ , "... ${_} works")
183 for qw(get_meta_instance compute_all_applicable_attributes
184 class_precedence_list get_method_map );
185};
186
187
188#rerun the same tests on an anon class.. just cause we can.
189{
190 my $meta = Baz->meta->create_anon_class(superclasses => ['Baz']);
191
192 lives_ok {$meta->make_immutable(
193 inline_accessor => 1,
194 inline_destructor => 0,
195 inline_constructor => 1,
196 )
197 } '... changed class to be immutable';
198 lives_ok { $meta->make_mutable() } '... changed class to be mutable';
199 lives_ok {$meta->make_immutable } '... changed class to be immutable';
200
201 dies_ok{ $meta->add_method('xyz', sub{'xxx'}) } '... exception thrown as expected';
0ac992ee 202
203 dies_ok {
204 $meta->add_attribute('fickle', accessor => 'fickle')
205 } '... exception thrown as expected';
206 dies_ok { $meta->remove_attribute('fickle') } '... exception thrown as expected';
207
208 my $reef = \ 'reef';
209 dies_ok { $meta->add_package_symbol('$ref', $reef) } '... exception thrown as expected';
210 dies_ok { $meta->remove_package_symbol('$ref') } '... exception thrown as expected';
211
212 ok( my @supers = $meta->superclasses, '... got the superclasses okay');
213 dies_ok { $meta->superclasses('Foo') } '... set the superclasses';
214
215 ok( $meta->$_ , "... ${_} works")
216 for qw(get_meta_instance compute_all_applicable_attributes
217 class_precedence_list get_method_map );
218}
d89108ab 219
220{
221 Foo->meta->make_immutable;
222 Bar->meta->make_immutable;
223 Bar->meta->make_mutable;
224
44d6ea77 225 isnt( Foo->meta->immutable_transformer, Bar->meta->immutable_transformer,
d89108ab 226 'Foo and Bar should have different immutable transformer objects' );
227}