Commit | Line | Data |
013b1897 |
1 | use strict; |
2 | use warnings; |
3 | |
86a4d873 |
4 | use Test::More; |
871e9eb5 |
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 | { |
871e9eb5 |
13 | isnt( exception { |
148b4697 |
14 | Class::MOP::Attribute->new('$test' => ( |
15 | default => qr/hello (.*)/ |
16 | )); |
871e9eb5 |
17 | }, undef, '... no refs for defaults' ); |
1d68af04 |
18 | |
871e9eb5 |
19 | isnt( exception { |
148b4697 |
20 | Class::MOP::Attribute->new('$test' => ( |
21 | default => [] |
22 | )); |
871e9eb5 |
23 | }, undef, '... no refs for defaults' ); |
1d68af04 |
24 | |
871e9eb5 |
25 | isnt( exception { |
148b4697 |
26 | Class::MOP::Attribute->new('$test' => ( |
27 | default => {} |
28 | )); |
871e9eb5 |
29 | }, undef, '... no refs for defaults' ); |
1d68af04 |
30 | |
31 | |
871e9eb5 |
32 | isnt( exception { |
148b4697 |
33 | Class::MOP::Attribute->new('$test' => ( |
34 | default => \(my $var) |
35 | )); |
871e9eb5 |
36 | }, undef, '... no refs for defaults' ); |
148b4697 |
37 | |
871e9eb5 |
38 | isnt( exception { |
148b4697 |
39 | Class::MOP::Attribute->new('$test' => ( |
40 | default => bless {} => 'Foo' |
41 | )); |
871e9eb5 |
42 | }, undef, '... no refs for defaults' ); |
148b4697 |
43 | |
013b1897 |
44 | } |
45 | |
1d68af04 |
46 | { |
871e9eb5 |
47 | isnt( exception { |
1d68af04 |
48 | Class::MOP::Attribute->new('$test' => ( |
49 | builder => qr/hello (.*)/ |
50 | )); |
871e9eb5 |
51 | }, undef, '... no refs for builders' ); |
1d68af04 |
52 | |
871e9eb5 |
53 | isnt( exception { |
1d68af04 |
54 | Class::MOP::Attribute->new('$test' => ( |
55 | builder => [] |
56 | )); |
871e9eb5 |
57 | }, undef, '... no refs for builders' ); |
1d68af04 |
58 | |
871e9eb5 |
59 | isnt( exception { |
1d68af04 |
60 | Class::MOP::Attribute->new('$test' => ( |
61 | builder => {} |
62 | )); |
871e9eb5 |
63 | }, undef, '... no refs for builders' ); |
1d68af04 |
64 | |
65 | |
871e9eb5 |
66 | isnt( exception { |
1d68af04 |
67 | Class::MOP::Attribute->new('$test' => ( |
68 | builder => \(my $var) |
69 | )); |
871e9eb5 |
70 | }, undef, '... no refs for builders' ); |
1d68af04 |
71 | |
871e9eb5 |
72 | isnt( exception { |
1d68af04 |
73 | Class::MOP::Attribute->new('$test' => ( |
74 | builder => bless {} => 'Foo' |
75 | )); |
871e9eb5 |
76 | }, undef, '... no refs for builders' ); |
1d68af04 |
77 | |
871e9eb5 |
78 | isnt( exception { |
1d68af04 |
79 | Class::MOP::Attribute->new('$test' => ( |
80 | builder => 'Foo', default => 'Foo' |
81 | )); |
871e9eb5 |
82 | }, undef, '... no default AND builder' ); |
1d68af04 |
83 | |
8343d501 |
84 | my $undef_attr; |
871e9eb5 |
85 | is( exception { |
8343d501 |
86 | $undef_attr = Class::MOP::Attribute->new('$test' => ( |
87 | default => undef, |
88 | predicate => 'has_test', |
89 | )); |
871e9eb5 |
90 | }, undef, '... 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 | } |
871e9eb5 |
104 | is( exception { Foo->meta->make_immutable }, undef, '... and it can be inlined' ); |
8343d501 |
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 | |
1d68af04 |
111 | } |
112 | |
113 | |
013b1897 |
114 | { # bad construtor args |
871e9eb5 |
115 | isnt( exception { |
013b1897 |
116 | Class::MOP::Attribute->new(); |
871e9eb5 |
117 | }, undef, '... no name argument' ); |
013b1897 |
118 | |
dbd0814d |
119 | # These are no longer errors |
871e9eb5 |
120 | is( exception { |
013b1897 |
121 | Class::MOP::Attribute->new(''); |
871e9eb5 |
122 | }, undef, '... bad name argument' ); |
013b1897 |
123 | |
871e9eb5 |
124 | is( exception { |
013b1897 |
125 | Class::MOP::Attribute->new(0); |
871e9eb5 |
126 | }, undef, '... bad name argument' ); |
013b1897 |
127 | } |
128 | |
129 | { |
1d68af04 |
130 | my $attr = Class::MOP::Attribute->new('$test'); |
871e9eb5 |
131 | isnt( exception { |
013b1897 |
132 | $attr->attach_to_class(); |
871e9eb5 |
133 | }, undef, '... attach_to_class died as expected' ); |
1d68af04 |
134 | |
871e9eb5 |
135 | isnt( exception { |
013b1897 |
136 | $attr->attach_to_class('Fail'); |
871e9eb5 |
137 | }, undef, '... attach_to_class died as expected' ); |
1d68af04 |
138 | |
871e9eb5 |
139 | isnt( exception { |
013b1897 |
140 | $attr->attach_to_class(bless {} => 'Fail'); |
871e9eb5 |
141 | }, undef, '... attach_to_class died as expected' ); |
013b1897 |
142 | } |
143 | |
144 | { |
145 | my $attr = Class::MOP::Attribute->new('$test' => ( |
146 | reader => [ 'whoops, this wont work' ] |
147 | )); |
1d68af04 |
148 | |
013b1897 |
149 | $attr->attach_to_class(Class::MOP::Class->initialize('Foo')); |
150 | |
871e9eb5 |
151 | isnt( exception { |
013b1897 |
152 | $attr->install_accessors; |
871e9eb5 |
153 | }, undef, '... bad reader format' ); |
013b1897 |
154 | } |
155 | |
156 | { |
157 | my $attr = Class::MOP::Attribute->new('$test'); |
158 | |
871e9eb5 |
159 | isnt( exception { |
45a183fb |
160 | $attr->_process_accessors('fail', 'my_failing_sub'); |
871e9eb5 |
161 | }, undef, '... cannot find "fail" type generator' ); |
013b1897 |
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 | )); |
1d68af04 |
175 | |
871e9eb5 |
176 | isnt( exception { |
013b1897 |
177 | $attr->install_accessors; |
871e9eb5 |
178 | }, undef, '... failed to generate accessors correctly' ); |
013b1897 |
179 | } |
180 | |
181 | { |
182 | my $attr = Class::MOP::Attribute->new('$test' => ( |
183 | predicate => 'has_test' |
184 | )); |
1d68af04 |
185 | |
88dd563c |
186 | my $Bar = Class::MOP::Class->create('Bar'); |
013b1897 |
187 | isa_ok($Bar, 'Class::MOP::Class'); |
1d68af04 |
188 | |
013b1897 |
189 | $Bar->add_attribute($attr); |
1d68af04 |
190 | |
013b1897 |
191 | can_ok('Bar', 'has_test'); |
1d68af04 |
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'); |
013b1897 |
196 | } |
197 | |
198 | |
199 | { |
200 | # NOTE: |
1d68af04 |
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 |
013b1897 |
207 | # tests the API change, so I keep it. |
208 | |
871e9eb5 |
209 | is( exception { |
013b1897 |
210 | Class::MOP::Attribute->new('$foo', ( |
211 | accessor => 'foo', |
212 | reader => 'get_foo', |
213 | )); |
871e9eb5 |
214 | }, undef, '... can create accessors with reader/writers' ); |
013b1897 |
215 | |
871e9eb5 |
216 | is( exception { |
013b1897 |
217 | Class::MOP::Attribute->new('$foo', ( |
218 | accessor => 'foo', |
219 | writer => 'set_foo', |
220 | )); |
871e9eb5 |
221 | }, undef, '... can create accessors with reader/writers' ); |
013b1897 |
222 | |
871e9eb5 |
223 | is( exception { |
013b1897 |
224 | Class::MOP::Attribute->new('$foo', ( |
225 | accessor => 'foo', |
1d68af04 |
226 | reader => 'get_foo', |
013b1897 |
227 | writer => 'set_foo', |
228 | )); |
871e9eb5 |
229 | }, undef, '... can create accessors with reader/writers' ); |
013b1897 |
230 | } |
86a4d873 |
231 | |
232 | done_testing; |