Merge branch 'stable'
[gitmo/Class-MOP.git] / t / 021_attribute_errors_and_edge_cases.t
CommitLineData
013b1897 1use strict;
2use warnings;
3
86a4d873 4use Test::More;
871e9eb5 5use Test::Fatal;
013b1897 6
86a4d873 7use Class::MOP;
8use 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
232done_testing;