back to a regular and registered Tuple that covers most of the requirements
[gitmo/MooseX-Types-Structured.git] / t / 02-constraints.t
CommitLineData
65748864 1BEGIN {
2 use strict;
3 use warnings;
335d9906 4 use Test::More tests=>47;
65748864 5 use Test::Exception;
6}
7
8{
bc64165b 9 package Test::MooseX::Meta::TypeConstraint::Structured;
65748864 10
11 use Moose;
13cf7c3b 12 use MooseX::Types::Structured qw(Tuple Dict Optional);
6c2f284c 13 use Moose::Util::TypeConstraints;
9a920d27 14
c3abf064 15 subtype 'MyString',
16 as 'Str',
17 where { $_=~m/abc/};
9a920d27 18
c3abf064 19 has 'tuple' => (is=>'rw', isa=>Tuple['Int', 'Str', 'MyString']);
bc64165b 20 has 'dict' => (is=>'rw', isa=>Dict[name=>'Str', age=>'Int']);
8b276dd4 21 has 'dict_with_maybe' => (is=>'rw', isa=>Dict[name=>'Str', age=>'Maybe[Int]']);
22 has 'tuple_with_param' => (is=>'rw', isa=>Tuple['Int', 'Str', 'ArrayRef[Int]']);
23 has 'tuple_with_maybe' => (is=>'rw', isa=>Tuple['Int', 'Str', 'Maybe[Int]']);
9a920d27 24 has 'dict_with_tuple' => (is=>'rw', isa=>Dict[key1=>'Str', key2=>Tuple['Int','Str']]);
13cf7c3b 25 has 'optional_tuple' => (is=>'rw', isa=>Tuple['Int', 'Int', Optional['Int']] );
26 has 'optional_dict' => (is=>'rw', isa=>Dict[key1=>'Int', Optional[key2=>'Int']] );
335d9906 27 has 'dict_with_tuple_with_union' => (is=>'rw', isa=>Dict[key1=>'Str|Object', key2=>Tuple['Int','Str|Object']] );
28
0f766471 29 has 'crazy' => (
30 is=>'rw',
d06d64c3 31 isa=>Tuple
0f766471 32 ## First ArrayRef Arg is the required type constraints for the top
33 ## level Tuple.
34 [
35 'Int',
36 'MyString',
37 ## The third required element is a Dict type constraint, which
38 ## itself has two required keys and a third optional key.
13cf7c3b 39 Dict[name=>'Str',age=>'Int', Optional[visits=>'Int']],
40 Optional[
41 'Int',
42 ## This Tuple has one required type constraint and two optional.
43 Tuple['Int', Optional['Int','HashRef']],
44 ],
45 ],
0f766471 46 );
65748864 47}
48
49## Instantiate a new test object
50
bc64165b 51ok my $record = Test::MooseX::Meta::TypeConstraint::Structured->new
65748864 52 => 'Instantiated new Record test class.';
53
bc64165b 54isa_ok $record => 'Test::MooseX::Meta::TypeConstraint::Structured'
65748864 55 => 'Created correct object type.';
0f766471 56
57## Test crazy
58
59lives_ok sub {
60 $record->crazy([1,'hello.abc.world', {name=>'John', age=>39}]);
61} => 'Set crazy attribute with no optionals used';
62
63is_deeply $record->crazy, [1, 'hello.abc.world', {name=>'John', age=>39}]
64 => 'correct values for crazy attributes no optionals';
65
66lives_ok sub {
67 $record->crazy([1,'hello.abc.world', {name=>'John', age=>39, visits=>10},10, [1,2,{key=>'value'}]]);
68} => 'Set crazy attribute with all optionals used';
69
70is_deeply $record->crazy, [1,'hello.abc.world', {name=>'John', age=>39, visits=>10},10, [1,2,{key=>'value'}]]
71 => 'correct values for crazy attributes all optionals';
b5f77bd3 72
0f766471 73lives_ok sub {
74 $record->crazy([1,'hello.abc.world', {name=>'John', age=>39},10, [1,2]]);
75} => 'Set crazy attribute with some optionals used';
76
77throws_ok sub {
78 $record->crazy([1,'hello', 'test.xxx.test']);
79}, qr/Validation failed for 'MyString'/
80 => 'Properly failed for bad value in crazy attribute 01';
81
82throws_ok sub {
83 $record->crazy([1,'hello.abc.world', {notname=>'John', notage=>39}]);
84}, qr/Validation failed for 'Str'/
85 => 'Properly failed for bad value in crazy attribute 02';
86
bc64165b 87## Test Tuple type constraint
88
65748864 89lives_ok sub {
c3abf064 90 $record->tuple([1,'hello', 'test.abc.test']);
65748864 91} => 'Set tuple attribute without error';
92
93is $record->tuple->[0], 1
94 => 'correct set the tuple attribute index 0';
95
96is $record->tuple->[1], 'hello'
97 => 'correct set the tuple attribute index 1';
98
c3abf064 99is $record->tuple->[2], 'test.abc.test'
100 => 'correct set the tuple attribute index 2';
101
102throws_ok sub {
103 $record->tuple([1,'hello', 'test.xxx.test']);
104}, qr/Validation failed for 'MyString'/
105 => 'Properly failed for bad value in custom type constraint';
106
65748864 107throws_ok sub {
c3abf064 108 $record->tuple(['asdasd',2, 'test.abc.test']);
65748864 109}, qr/Validation failed for 'Int'/
110 => 'Got Expected Error for violating constraints';
111
bc64165b 112## Test the Dictionary type constraint
113
114lives_ok sub {
115 $record->dict({name=>'frith', age=>23});
116} => 'Set dict attribute without error';
117
118is $record->dict->{name}, 'frith'
119 => 'correct set the dict attribute name';
120
121is $record->dict->{age}, 23
122 => 'correct set the dict attribute age';
123
124throws_ok sub {
125 $record->dict({name=>[1,2,3], age=>'sdfsdfsd'});
126}, qr/Validation failed for 'Str'/
127 => 'Got Expected Error for bad value in dict';
8b276dd4 128
129## Test tuple_with_maybe
130
131lives_ok sub {
132 $record->tuple_with_maybe([1,'hello', 1]);
133} => 'Set tuple attribute without error';
134
135throws_ok sub {
136 $record->tuple_with_maybe([1,'hello', 'a']);
137}, qr/Validation failed for 'Maybe\[Int\]'/
138 => 'Properly failed for bad value parameterized constraint';
139
140lives_ok sub {
141 $record->tuple_with_maybe([1,'hello']);
142} => 'Set tuple attribute without error skipping optional parameter';
143
144## Test Tuple with parameterized type
145
146lives_ok sub {
147 $record->tuple_with_param([1,'hello', [1,2,3]]);
148} => 'Set tuple attribute without error';
149
150throws_ok sub {
151 $record->tuple_with_param([1,'hello', [qw/a b c/]]);
152}, qr/Validation failed for 'ArrayRef\[Int\]'/
153 => 'Properly failed for bad value parameterized constraint';
154
155## Test dict_with_maybe
156
157lives_ok sub {
158 $record->dict_with_maybe({name=>'frith', age=>23});
159} => 'Set dict attribute without error';
160
161is $record->dict_with_maybe->{name}, 'frith'
162 => 'correct set the dict attribute name';
163
164is $record->dict_with_maybe->{age}, 23
165 => 'correct set the dict attribute age';
166
167throws_ok sub {
168 $record->dict_with_maybe({name=>[1,2,3], age=>'sdfsdfsd'});
169}, qr/Validation failed for 'Str'/
170 => 'Got Expected Error for bad value in dict';
171
172throws_ok sub {
173 $record->dict_with_maybe({age=>30});
174}, qr/Validation failed for 'Str'/
175 => 'Got Expected Error for missing named parameter';
176
177lives_ok sub {
178 $record->dict_with_maybe({name=>'usal'});
179} => 'Set dict attribute without error, skipping optional';
9a920d27 180
181## Test dict_with_tuple
182
183lives_ok sub {
184 $record->dict_with_tuple({key1=>'Hello', key2=>[1,'World']});
185} => 'Set tuple attribute without error';
186
187throws_ok sub {
188 $record->dict_with_tuple({key1=>'Hello', key2=>['World',2]});
189}, qr/Validation failed for 'Int'/
190 => 'Threw error on bad constraint';
191
b5f77bd3 192## Test optional_tuple
9a920d27 193
b5f77bd3 194lives_ok sub {
195 $record->optional_tuple([1,2,3]);
196} => 'Set tuple attribute with optional bits';
197
198is_deeply $record->optional_tuple, [1,2,3]
199 => 'correct values set';
200
201lives_ok sub {
202 $record->optional_tuple([4,5]);
203} => 'Set tuple attribute withOUT optional bits';
204
205is_deeply $record->optional_tuple, [4,5]
206 => 'correct values set again';
207
208throws_ok sub {
209 $record->optional_tuple([1,2,'bad']);
210}, qr/Validation failed for 'Int'/
211 => 'Properly failed for bad value in optional bit';
9a920d27 212
6479ca33 213# Test optional_dict
214
215lives_ok sub {
216 $record->optional_dict({key1=>1,key2=>2});
217} => 'Set tuple attribute with optional bits';
218
219is_deeply $record->optional_dict, {key1=>1,key2=>2}
220 => 'correct values set';
221
222lives_ok sub {
223 $record->optional_dict({key1=>3});
224} => 'Set tuple attribute withOUT optional bits';
225
226is_deeply $record->optional_dict, {key1=>3}
227 => 'correct values set again';
228
229throws_ok sub {
230 $record->optional_dict({key1=>1,key2=>'bad'});
231}, qr/Validation failed for 'Int'/
232 => 'Properly failed for bad value in optional bit';
335d9906 233
234
235## Test dict_with_tuple_with_union: Dict[key1=>'Str|Object', key2=>Tuple['Int','Str|Object']]
236
237lives_ok sub {
238 $record->dict_with_tuple_with_union({key1=>'Hello', key2=>[1,'World']});
239} => 'Set tuple attribute without error';
240
241throws_ok sub {
242 $record->dict_with_tuple_with_union({key1=>'Hello', key2=>['World',2]});
243}, qr/Validation failed for 'Int'/
244 => 'Threw error on bad constraint';
245
246lives_ok sub {
247 $record->dict_with_tuple_with_union({key1=>$record, key2=>[1,'World']});
248} => 'Set tuple attribute without error';
249
250lives_ok sub {
251 $record->dict_with_tuple_with_union({key1=>'Hello', key2=>[1,$record]});
252} => 'Set tuple attribute without error';
253
254throws_ok sub {
255 $record->dict_with_tuple_with_union({key1=>1, key2=>['World',2]});
256}, qr/Validation failed for 'Int'/
bfef1b30 257 => 'Threw error on bad constraint';