Convert all tests to done_testing.
[gitmo/Moose.git] / t / 020_attributes / 012_misc_attribute_tests.t
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use Test::More;
7 use Test::Exception;
8
9
10 {
11     {
12         package Test::Attribute::Inline::Documentation;
13         use Moose;
14
15         has 'foo' => (
16             documentation => q{
17                 The 'foo' attribute is my favorite
18                 attribute in the whole wide world.
19             },
20             is => 'bare',
21         );
22     }
23
24     my $foo_attr = Test::Attribute::Inline::Documentation->meta->get_attribute('foo');
25
26     ok($foo_attr->has_documentation, '... the foo has docs');
27     is($foo_attr->documentation,
28             q{
29                 The 'foo' attribute is my favorite
30                 attribute in the whole wide world.
31             },
32     '... got the foo docs');
33 }
34
35 {
36     {
37         package Test::For::Lazy::TypeConstraint;
38         use Moose;
39         use Moose::Util::TypeConstraints;
40
41         has 'bad_lazy_attr' => (
42             is => 'rw',
43             isa => 'ArrayRef',
44             lazy => 1,
45             default => sub { "test" },
46         );
47
48         has 'good_lazy_attr' => (
49             is => 'rw',
50             isa => 'ArrayRef',
51             lazy => 1,
52             default => sub { [] },
53         );
54
55     }
56
57     my $test = Test::For::Lazy::TypeConstraint->new;
58     isa_ok($test, 'Test::For::Lazy::TypeConstraint');
59
60     dies_ok {
61         $test->bad_lazy_attr;
62     } '... this does not work';
63
64     lives_ok {
65         $test->good_lazy_attr;
66     } '... this does not work';
67 }
68
69 {
70     {
71         package Test::Arrayref::Attributes;
72         use Moose;
73
74         has [qw(foo bar baz)] => (
75             is => 'rw',
76         );
77
78     }
79
80     my $test = Test::Arrayref::Attributes->new;
81     isa_ok($test, 'Test::Arrayref::Attributes');
82     can_ok($test, qw(foo bar baz));
83
84 }
85
86 {
87     {
88         package Test::Arrayref::RoleAttributes::Role;
89         use Moose::Role;
90
91         has [qw(foo bar baz)] => (
92             is => 'rw',
93         );
94
95     }
96     {
97         package Test::Arrayref::RoleAttributes;
98         use Moose;
99         with 'Test::Arrayref::RoleAttributes::Role';
100     }
101
102     my $test = Test::Arrayref::RoleAttributes->new;
103     isa_ok($test, 'Test::Arrayref::RoleAttributes');
104     can_ok($test, qw(foo bar baz));
105
106 }
107
108 {
109     {
110         package Test::UndefDefault::Attributes;
111         use Moose;
112
113         has 'foo' => (
114             is      => 'ro',
115             isa     => 'Str',
116             default => sub { return }
117         );
118
119     }
120
121     dies_ok {
122         Test::UndefDefault::Attributes->new;
123     } '... default must return a value which passes the type constraint';
124
125 }
126
127 {
128     {
129         package OverloadedStr;
130         use Moose;
131         use overload '""' => sub { 'this is *not* a string' };
132
133         has 'a_str' => ( isa => 'Str' , is => 'rw' );
134     }
135
136     my $moose_obj = OverloadedStr->new;
137
138     is($moose_obj->a_str( 'foobar' ), 'foobar', 'setter took string');
139     ok($moose_obj, 'this is a *not* a string');
140
141     throws_ok {
142         $moose_obj->a_str( $moose_obj )
143     } qr/Attribute \(a_str\) does not pass the type constraint because\: Validation failed for 'Str' failed with value OverloadedStr=HASH\(0x.+?\)/,
144     '... dies without overloading the string';
145
146 }
147
148 {
149     {
150         package OverloadBreaker;
151         use Moose;
152
153         has 'a_num' => ( isa => 'Int' , is => 'rw', default => 7.5 );
154     }
155
156     throws_ok {
157         OverloadBreaker->new;
158     } qr/Attribute \(a_num\) does not pass the type constraint because\: Validation failed for 'Int' failed with value 7\.5/,
159     '... this doesnt trip overload to break anymore ';
160
161     lives_ok {
162         OverloadBreaker->new(a_num => 5);
163     } '... this works fine though';
164
165 }
166
167 {
168     {
169       package Test::Builder::Attribute;
170         use Moose;
171
172         has 'foo'  => ( required => 1, builder => 'build_foo', is => 'ro');
173         sub build_foo { return "works" };
174     }
175
176     my $meta = Test::Builder::Attribute->meta;
177     my $foo_attr  = $meta->get_attribute("foo");
178
179     ok($foo_attr->is_required, "foo is required");
180     ok($foo_attr->has_builder, "foo has builder");
181     is($foo_attr->builder, "build_foo",  ".. and it's named build_foo");
182
183     my $instance = Test::Builder::Attribute->new;
184     is($instance->foo, 'works', "foo builder works");
185 }
186
187 {
188     {
189         package Test::Builder::Attribute::Broken;
190         use Moose;
191
192         has 'foo'  => ( required => 1, builder => 'build_foo', is => 'ro');
193     }
194
195     dies_ok {
196         Test::Builder::Attribute::Broken->new;
197     } '... no builder, wtf';
198 }
199
200
201 {
202     {
203       package Test::LazyBuild::Attribute;
204         use Moose;
205
206         has 'foo'  => ( lazy_build => 1, is => 'ro');
207         has '_foo' => ( lazy_build => 1, is => 'ro');
208         has 'fool' => ( lazy_build => 1, is => 'ro');
209         sub _build_foo { return "works" };
210         sub _build__foo { return "works too" };
211     }
212
213     my $meta = Test::LazyBuild::Attribute->meta;
214     my $foo_attr  = $meta->get_attribute("foo");
215     my $_foo_attr = $meta->get_attribute("_foo");
216
217     ok($foo_attr->is_lazy, "foo is lazy");
218     ok($foo_attr->is_lazy_build, "foo is lazy_build");
219
220     ok($foo_attr->has_clearer, "foo has clearer");
221     is($foo_attr->clearer, "clear_foo",  ".. and it's named clear_foo");
222
223     ok($foo_attr->has_builder, "foo has builder");
224     is($foo_attr->builder, "_build_foo",  ".. and it's named build_foo");
225
226     ok($foo_attr->has_predicate, "foo has predicate");
227     is($foo_attr->predicate, "has_foo",  ".. and it's named has_foo");
228
229     ok($_foo_attr->is_lazy, "_foo is lazy");
230     ok(!$_foo_attr->is_required, "lazy_build attributes are no longer automatically required");
231     ok($_foo_attr->is_lazy_build, "_foo is lazy_build");
232
233     ok($_foo_attr->has_clearer, "_foo has clearer");
234     is($_foo_attr->clearer, "_clear_foo",  ".. and it's named _clear_foo");
235
236     ok($_foo_attr->has_builder, "_foo has builder");
237     is($_foo_attr->builder, "_build__foo",  ".. and it's named _build_foo");
238
239     ok($_foo_attr->has_predicate, "_foo has predicate");
240     is($_foo_attr->predicate, "_has_foo",  ".. and it's named _has_foo");
241
242     my $instance = Test::LazyBuild::Attribute->new;
243     ok(!$instance->has_foo, "noo foo value yet");
244     ok(!$instance->_has_foo, "noo _foo value yet");
245     is($instance->foo, 'works', "foo builder works");
246     is($instance->_foo, 'works too', "foo builder works too");
247     throws_ok { $instance->fool }
248         qr/Test::LazyBuild::Attribute does not support builder method \'_build_fool\' for attribute \'fool\'/,
249             "Correct error when a builder method is not present";
250
251 }
252
253 {
254     package OutOfClassTest;
255
256     use Moose;
257 }
258
259 lives_ok { OutOfClassTest::has('foo', is => 'bare'); } 'create attr via direct sub call';
260 lives_ok { OutOfClassTest->can('has')->('bar', is => 'bare'); } 'create attr via can';
261
262 ok(OutOfClassTest->meta->get_attribute('foo'), 'attr created from sub call');
263 ok(OutOfClassTest->meta->get_attribute('bar'), 'attr created from can');
264
265
266 {
267     {
268         package Foo;
269         use Moose;
270
271         ::throws_ok { has 'foo' => ( 'ro', isa => 'Str' ) }
272             qr/^Usage/, 'has throws error with odd number of attribute options';
273     }
274
275 }
276
277 done_testing;