Skip Alien-Ditaa
[gitmo/Moose.git] / t / cmop / attribute_errors_and_edge_cases.t
CommitLineData
38bf2a25 1use strict;
2use warnings;
3
4use Test::More;
5use Test::Fatal;
6
7use Class::MOP;
8use Class::MOP::Attribute;
9
10# most values are static
11
12{
13 isnt( exception {
14 Class::MOP::Attribute->new('$test' => (
15 default => qr/hello (.*)/
16 ));
17 }, undef, '... no refs for defaults' );
18
19 isnt( exception {
20 Class::MOP::Attribute->new('$test' => (
21 default => []
22 ));
23 }, undef, '... no refs for defaults' );
24
25 isnt( exception {
26 Class::MOP::Attribute->new('$test' => (
27 default => {}
28 ));
29 }, undef, '... no refs for defaults' );
30
31
32 isnt( exception {
33 Class::MOP::Attribute->new('$test' => (
34 default => \(my $var)
35 ));
36 }, undef, '... no refs for defaults' );
37
38 isnt( exception {
39 Class::MOP::Attribute->new('$test' => (
40 default => bless {} => 'Foo'
41 ));
42 }, undef, '... no refs for defaults' );
43
44}
45
46{
47 isnt( exception {
48 Class::MOP::Attribute->new('$test' => (
49 builder => qr/hello (.*)/
50 ));
51 }, undef, '... no refs for builders' );
52
53 isnt( exception {
54 Class::MOP::Attribute->new('$test' => (
55 builder => []
56 ));
57 }, undef, '... no refs for builders' );
58
59 isnt( exception {
60 Class::MOP::Attribute->new('$test' => (
61 builder => {}
62 ));
63 }, undef, '... no refs for builders' );
64
65
66 isnt( exception {
67 Class::MOP::Attribute->new('$test' => (
68 builder => \(my $var)
69 ));
70 }, undef, '... no refs for builders' );
71
72 isnt( exception {
73 Class::MOP::Attribute->new('$test' => (
74 builder => bless {} => 'Foo'
75 ));
76 }, undef, '... no refs for builders' );
77
78 isnt( exception {
79 Class::MOP::Attribute->new('$test' => (
80 builder => 'Foo', default => 'Foo'
81 ));
82 }, undef, '... no default AND builder' );
83
84 my $undef_attr;
85 is( exception {
86 $undef_attr = Class::MOP::Attribute->new('$test' => (
87 default => undef,
88 predicate => 'has_test',
89 ));
90 }, undef, '... undef as a default is okay' );
91 ok($undef_attr->has_default, '... and it counts as an actual default');
92 ok(!Class::MOP::Attribute->new('$test')->has_default,
93 '... but attributes with no default have no default');
94
95 Class::MOP::Class->create(
96 'Foo',
97 attributes => [$undef_attr],
98 );
99 {
100 my $obj = Foo->meta->new_object;
101 ok($obj->has_test, '... and the default is populated');
102 is($obj->meta->get_attribute('$test')->get_value($obj), undef, '... with the right value');
103 }
104 is( exception { Foo->meta->make_immutable }, undef, '... and it can be inlined' );
105 {
106 my $obj = Foo->new;
107 ok($obj->has_test, '... and the default is populated');
108 is($obj->meta->get_attribute('$test')->get_value($obj), undef, '... with the right value');
109 }
110
111}
112
113
114{ # bad construtor args
115 isnt( exception {
116 Class::MOP::Attribute->new();
117 }, undef, '... no name argument' );
118
119 # These are no longer errors
120 is( exception {
121 Class::MOP::Attribute->new('');
122 }, undef, '... bad name argument' );
123
124 is( exception {
125 Class::MOP::Attribute->new(0);
126 }, undef, '... bad name argument' );
127}
128
129{
130 my $attr = Class::MOP::Attribute->new('$test');
131 isnt( exception {
132 $attr->attach_to_class();
133 }, undef, '... attach_to_class died as expected' );
134
135 isnt( exception {
136 $attr->attach_to_class('Fail');
137 }, undef, '... attach_to_class died as expected' );
138
139 isnt( exception {
140 $attr->attach_to_class(bless {} => 'Fail');
141 }, undef, '... attach_to_class died as expected' );
142}
143
144{
145 my $attr = Class::MOP::Attribute->new('$test' => (
146 reader => [ 'whoops, this wont work' ]
147 ));
148
149 $attr->attach_to_class(Class::MOP::Class->initialize('Foo'));
150
151 isnt( exception {
152 $attr->install_accessors;
153 }, undef, '... bad reader format' );
154}
155
156{
157 my $attr = Class::MOP::Attribute->new('$test');
158
159 isnt( exception {
160 $attr->_process_accessors('fail', 'my_failing_sub');
161 }, undef, '... cannot find "fail" type generator' );
162}
163
164
165{
166 {
167 package My::Attribute;
168 our @ISA = ('Class::MOP::Attribute');
169 sub generate_reader_method { eval { die } }
170 }
171
172 my $attr = My::Attribute->new('$test' => (
173 reader => 'test'
174 ));
175
176 isnt( exception {
177 $attr->install_accessors;
178 }, undef, '... failed to generate accessors correctly' );
179}
180
181{
182 my $attr = Class::MOP::Attribute->new('$test' => (
183 predicate => 'has_test'
184 ));
185
186 my $Bar = Class::MOP::Class->create('Bar');
187 isa_ok($Bar, 'Class::MOP::Class');
188
189 $Bar->add_attribute($attr);
190
191 can_ok('Bar', 'has_test');
192
193 is($attr, $Bar->remove_attribute('$test'), '... removed the $test attribute');
194
195 ok(!Bar->can('has_test'), '... Bar no longer has the "has_test" method');
196}
197
198
199{
200 # NOTE:
201 # the next three tests once tested that
202 # the code would fail, but we lifted the
203 # restriction so you can have an accessor
204 # along with a reader/writer pair (I mean
205 # why not really). So now they test that
206 # it works, which is kinda silly, but it
207 # tests the API change, so I keep it.
208
209 is( exception {
210 Class::MOP::Attribute->new('$foo', (
211 accessor => 'foo',
212 reader => 'get_foo',
213 ));
214 }, undef, '... can create accessors with reader/writers' );
215
216 is( exception {
217 Class::MOP::Attribute->new('$foo', (
218 accessor => 'foo',
219 writer => 'set_foo',
220 ));
221 }, undef, '... can create accessors with reader/writers' );
222
223 is( exception {
224 Class::MOP::Attribute->new('$foo', (
225 accessor => 'foo',
226 reader => 'get_foo',
227 writer => 'set_foo',
228 ));
229 }, undef, '... can create accessors with reader/writers' );
230}
231
232done_testing;