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