Commit | Line | Data |
013b1897 |
1 | use strict; |
2 | use warnings; |
3 | |
86a4d873 |
4 | use Test::More; |
13b8971f |
5 | use Test::Fatal; |
013b1897 |
6 | |
86a4d873 |
7 | use Class::MOP; |
8 | use Class::MOP::Attribute; |
013b1897 |
9 | |
148b4697 |
10 | # most values are static |
013b1897 |
11 | |
12 | { |
13b8971f |
13 | ok exception { |
148b4697 |
14 | Class::MOP::Attribute->new('$test' => ( |
15 | default => qr/hello (.*)/ |
16 | )); |
13b8971f |
17 | }, '... no refs for defaults'; |
1d68af04 |
18 | |
13b8971f |
19 | ok exception { |
148b4697 |
20 | Class::MOP::Attribute->new('$test' => ( |
21 | default => [] |
22 | )); |
13b8971f |
23 | }, '... no refs for defaults'; |
1d68af04 |
24 | |
13b8971f |
25 | ok exception { |
148b4697 |
26 | Class::MOP::Attribute->new('$test' => ( |
27 | default => {} |
28 | )); |
13b8971f |
29 | }, '... no refs for defaults'; |
1d68af04 |
30 | |
31 | |
13b8971f |
32 | ok exception { |
148b4697 |
33 | Class::MOP::Attribute->new('$test' => ( |
34 | default => \(my $var) |
35 | )); |
13b8971f |
36 | }, '... no refs for defaults'; |
148b4697 |
37 | |
13b8971f |
38 | ok exception { |
148b4697 |
39 | Class::MOP::Attribute->new('$test' => ( |
40 | default => bless {} => 'Foo' |
41 | )); |
13b8971f |
42 | }, '... no refs for defaults'; |
148b4697 |
43 | |
013b1897 |
44 | } |
45 | |
1d68af04 |
46 | { |
13b8971f |
47 | ok exception { |
1d68af04 |
48 | Class::MOP::Attribute->new('$test' => ( |
49 | builder => qr/hello (.*)/ |
50 | )); |
13b8971f |
51 | }, '... no refs for builders'; |
1d68af04 |
52 | |
13b8971f |
53 | ok exception { |
1d68af04 |
54 | Class::MOP::Attribute->new('$test' => ( |
55 | builder => [] |
56 | )); |
13b8971f |
57 | }, '... no refs for builders'; |
1d68af04 |
58 | |
13b8971f |
59 | ok exception { |
1d68af04 |
60 | Class::MOP::Attribute->new('$test' => ( |
61 | builder => {} |
62 | )); |
13b8971f |
63 | }, '... no refs for builders'; |
1d68af04 |
64 | |
65 | |
13b8971f |
66 | ok exception { |
1d68af04 |
67 | Class::MOP::Attribute->new('$test' => ( |
68 | builder => \(my $var) |
69 | )); |
13b8971f |
70 | }, '... no refs for builders'; |
1d68af04 |
71 | |
13b8971f |
72 | ok exception { |
1d68af04 |
73 | Class::MOP::Attribute->new('$test' => ( |
74 | builder => bless {} => 'Foo' |
75 | )); |
13b8971f |
76 | }, '... no refs for builders'; |
1d68af04 |
77 | |
13b8971f |
78 | ok exception { |
1d68af04 |
79 | Class::MOP::Attribute->new('$test' => ( |
80 | builder => 'Foo', default => 'Foo' |
81 | )); |
13b8971f |
82 | }, '... no default AND builder'; |
1d68af04 |
83 | |
8343d501 |
84 | my $undef_attr; |
13b8971f |
85 | ok ! exception { |
8343d501 |
86 | $undef_attr = Class::MOP::Attribute->new('$test' => ( |
87 | default => undef, |
88 | predicate => 'has_test', |
89 | )); |
13b8971f |
90 | }, '... undef as a default is okay'; |
8343d501 |
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 | } |
13b8971f |
104 | ok ! exception { Foo->meta->make_immutable }, |
8343d501 |
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 |
13b8971f |
116 | ok exception { |
013b1897 |
117 | Class::MOP::Attribute->new(); |
13b8971f |
118 | }, '... no name argument'; |
013b1897 |
119 | |
dbd0814d |
120 | # These are no longer errors |
13b8971f |
121 | ok ! exception { |
013b1897 |
122 | Class::MOP::Attribute->new(''); |
13b8971f |
123 | }, '... bad name argument'; |
013b1897 |
124 | |
13b8971f |
125 | ok ! exception { |
013b1897 |
126 | Class::MOP::Attribute->new(0); |
13b8971f |
127 | }, '... bad name argument'; |
013b1897 |
128 | } |
129 | |
130 | { |
1d68af04 |
131 | my $attr = Class::MOP::Attribute->new('$test'); |
13b8971f |
132 | ok exception { |
013b1897 |
133 | $attr->attach_to_class(); |
13b8971f |
134 | }, '... attach_to_class died as expected'; |
1d68af04 |
135 | |
13b8971f |
136 | ok exception { |
013b1897 |
137 | $attr->attach_to_class('Fail'); |
13b8971f |
138 | }, '... attach_to_class died as expected'; |
1d68af04 |
139 | |
13b8971f |
140 | ok exception { |
013b1897 |
141 | $attr->attach_to_class(bless {} => 'Fail'); |
13b8971f |
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 | |
13b8971f |
152 | ok exception { |
013b1897 |
153 | $attr->install_accessors; |
13b8971f |
154 | }, '... bad reader format'; |
013b1897 |
155 | } |
156 | |
157 | { |
158 | my $attr = Class::MOP::Attribute->new('$test'); |
159 | |
13b8971f |
160 | ok exception { |
45a183fb |
161 | $attr->_process_accessors('fail', 'my_failing_sub'); |
13b8971f |
162 | }, '... cannot find "fail" type generator'; |
013b1897 |
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 | |
13b8971f |
177 | ok exception { |
013b1897 |
178 | $attr->install_accessors; |
13b8971f |
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 | |
13b8971f |
210 | ok ! exception { |
013b1897 |
211 | Class::MOP::Attribute->new('$foo', ( |
212 | accessor => 'foo', |
213 | reader => 'get_foo', |
214 | )); |
13b8971f |
215 | }, '... can create accessors with reader/writers'; |
013b1897 |
216 | |
13b8971f |
217 | ok ! exception { |
013b1897 |
218 | Class::MOP::Attribute->new('$foo', ( |
219 | accessor => 'foo', |
220 | writer => 'set_foo', |
221 | )); |
13b8971f |
222 | }, '... can create accessors with reader/writers'; |
013b1897 |
223 | |
13b8971f |
224 | ok ! exception { |
013b1897 |
225 | Class::MOP::Attribute->new('$foo', ( |
226 | accessor => 'foo', |
1d68af04 |
227 | reader => 'get_foo', |
013b1897 |
228 | writer => 'set_foo', |
229 | )); |
13b8971f |
230 | }, '... can create accessors with reader/writers'; |
013b1897 |
231 | } |
86a4d873 |
232 | |
233 | done_testing; |