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