Standardize use of Test::Exception before converting to Test::Fatal
[gitmo/Moose.git] / t / 030_roles / 017_extending_role_attrs.t
CommitLineData
8d62bf6d 1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
a28e50e4 6use Test::More;
53a4d826 7use Test::Exception;
8d62bf6d 8
7ff56534 9
8d62bf6d 10=pod
11
d03bd989 12This basically just makes sure that using +name
dd14f8e8 13on role attributes works right.
8d62bf6d 14
15=cut
16
17{
18 package Foo::Role;
19 use Moose::Role;
d03bd989 20
8d62bf6d 21 has 'bar' => (
22 is => 'rw',
d03bd989 23 isa => 'Int',
8d62bf6d 24 default => sub { 10 },
25 );
d03bd989 26
8d62bf6d 27 package Foo;
28 use Moose;
d03bd989 29
8d62bf6d 30 with 'Foo::Role';
d03bd989 31
53a4d826 32 ::lives_ok {
8d62bf6d 33 has '+bar' => (default => sub { 100 });
53a4d826 34 } '... extended the attribute successfully';
8d62bf6d 35}
36
37my $foo = Foo->new;
38isa_ok($foo, 'Foo');
39
40is($foo->bar, 100, '... got the extended attribute');
41
b7835731 42
dd14f8e8 43{
44 package Bar::Role;
45 use Moose::Role;
46
47 has 'foo' => (
48 is => 'rw',
49 isa => 'Str | Int',
50 );
51
52 package Bar;
53 use Moose;
54
55 with 'Bar::Role';
56
53a4d826 57 ::lives_ok {
dd14f8e8 58 has '+foo' => (
59 isa => 'Int',
60 )
53a4d826 61 } "... narrowed the role's type constraint successfully";
dd14f8e8 62}
63
dd14f8e8 64my $bar = Bar->new(foo => 42);
65isa_ok($bar, 'Bar');
66is($bar->foo, 42, '... got the extended attribute');
67$bar->foo(100);
68is($bar->foo, 100, "... can change the attribute's value to an Int");
69
53a4d826 70throws_ok { $bar->foo("baz") } qr/^Attribute \(foo\) does not pass the type constraint because: Validation failed for 'Int' with value baz at /;
dd14f8e8 71is($bar->foo, 100, "... still has the old Int value");
72
b7835731 73
68e9fbfc 74{
75 package Baz::Role;
76 use Moose::Role;
77
78 has 'baz' => (
79 is => 'rw',
b7835731 80 isa => 'Value',
68e9fbfc 81 );
82
83 package Baz;
84 use Moose;
85
86 with 'Baz::Role';
87
53a4d826 88 ::lives_ok {
68e9fbfc 89 has '+baz' => (
b7835731 90 isa => 'Int | ClassName',
68e9fbfc 91 )
53a4d826 92 } "... narrowed the role's type constraint successfully";
68e9fbfc 93}
94
68e9fbfc 95my $baz = Baz->new(baz => 99);
96isa_ok($baz, 'Baz');
97is($baz->baz, 99, '... got the extended attribute');
b7835731 98$baz->baz('Foo');
99is($baz->baz, 'Foo', "... can change the attribute's value to a ClassName");
100
53a4d826 101throws_ok { $baz->baz("zonk") } qr/^Attribute \(baz\) does not pass the type constraint because: Validation failed for 'ClassName\|Int' with value zonk at /;
b7835731 102is_deeply($baz->baz, 'Foo', "... still has the old ClassName value");
68e9fbfc 103
68e9fbfc 104
657f212a 105{
106 package Quux::Role;
107 use Moose::Role;
108
109 has 'quux' => (
110 is => 'rw',
111 isa => 'Str | Int | Ref',
112 );
113
114 package Quux;
115 use Moose;
116 use Moose::Util::TypeConstraints;
117
118 with 'Quux::Role';
119
120 subtype 'Positive'
121 => as 'Int'
122 => where { $_ > 0 };
123
53a4d826 124 ::lives_ok {
657f212a 125 has '+quux' => (
126 isa => 'Positive | ArrayRef',
127 )
53a4d826 128 } "... narrowed the role's type constraint successfully";
657f212a 129}
130
657f212a 131my $quux = Quux->new(quux => 99);
132isa_ok($quux, 'Quux');
133is($quux->quux, 99, '... got the extended attribute');
134$quux->quux(100);
135is($quux->quux, 100, "... can change the attribute's value to an Int");
136$quux->quux(["hi"]);
137is_deeply($quux->quux, ["hi"], "... can change the attribute's value to an ArrayRef");
138
53a4d826 139throws_ok { $quux->quux("quux") } qr/^Attribute \(quux\) does not pass the type constraint because: Validation failed for 'ArrayRef\|Positive' with value quux at /;
657f212a 140is_deeply($quux->quux, ["hi"], "... still has the old ArrayRef value");
141
53a4d826 142throws_ok { $quux->quux({a => 1}) } qr/^Attribute \(quux\) does not pass the type constraint because: Validation failed for 'ArrayRef\|Positive' with value HASH\(\w+\) at /;
657f212a 143is_deeply($quux->quux, ["hi"], "... still has the old ArrayRef value");
144
b7835731 145
657f212a 146{
147 package Err::Role;
148 use Moose::Role;
149
5e98d2b6 150 for (1..3) {
151 has "err$_" => (
152 isa => 'Str | Int',
ccd4cff9 153 is => 'bare',
5e98d2b6 154 );
155 }
657f212a 156
157 package Err;
158 use Moose;
159
160 with 'Err::Role';
161
53a4d826 162 ::lives_ok {
5e98d2b6 163 has '+err1' => (isa => 'Defined');
53a4d826 164 } "can get less specific in the subclass";
657f212a 165
53a4d826 166 ::lives_ok {
5e98d2b6 167 has '+err2' => (isa => 'Bool');
53a4d826 168 } "or change the type completely";
657f212a 169
53a4d826 170 ::lives_ok {
5e98d2b6 171 has '+err3' => (isa => 'Str | ArrayRef');
53a4d826 172 } "or add new types to the union";
657f212a 173}
174
576cd474 175{
176 package Role::With::PlusAttr;
177 use Moose::Role;
178
179 with 'Foo::Role';
180
53a4d826 181 ::throws_ok {
576cd474 182 has '+bar' => ( is => 'ro' );
53a4d826 183 } qr/has '\+attr' is not supported in roles/,
576cd474 184 "Test has '+attr' in roles explodes";
185}
186
a28e50e4 187done_testing;