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