62571ceebe50bd83f05d2ee1626db31e19aeef15
[catagits/Catalyst-Runtime.git] / t / arg_constraints.t
1 use warnings;
2 use strict;
3
4 BEGIN {
5   use Test::More;
6   eval "use Types::Standard; 1;" || do {
7     plan skip_all => "Trouble loading Types::Standard => $@";
8   };
9
10   package MyApp::Types;
11   $INC{'MyApp/Types.pm'} = __FILE__;
12
13   use strict;
14   use warnings;
15  
16   use Type::Utils -all;
17   use Types::Standard -types;
18   use Type::Library
19    -base,
20    -declare => qw( UserId User ContextLike );
21
22   extends "Types::Standard"; 
23
24   class_type User, { class => "MyApp::Model::User::user" };
25   duck_type ContextLike, [qw/model/];
26
27   declare UserId,
28    as Int,
29    where { $_ < 5 };
30
31   # Tests using this are skipped pending deeper thought
32   coerce User,
33    from ContextLike,
34      via { $_->model('User')->find( $_->req->args->[0] ) };
35 }
36
37 {
38   package MyApp::Model::User;
39   $INC{'MyApp/Model/User.pm'} = __FILE__;
40
41   use base 'Catalyst::Model';
42
43   our %users = (
44     1 => { name => 'john', age => 46 },
45     2 => { name => 'mary', age => 36 },
46     3 => { name => 'ian', age => 25 },
47     4 => { name => 'visha', age => 18 },
48   );
49
50   sub find {
51     my ($self, $id) = @_;
52     my $user = $users{$id} || return;
53     return bless $user, "MyApp::Model::User::user";
54   }
55
56   package MyApp::Controller::Root;
57   $INC{'MyApp/Controller/Root.pm'} = __FILE__;
58
59   use Moose;
60   use MooseX::MethodAttributes;
61   use MyApp::Types qw/Tuple Int Str StrMatch ArrayRef UserId User/;
62
63   extends 'Catalyst::Controller';
64
65   sub user :Local Args(UserId) {
66     my ($self, $c, $int) = @_;
67     my $user = $c->model("User")->find($int);
68     $c->res->body("name: $user->{name}, age: $user->{age}");
69   }
70
71   # Tests using this are current skipped pending coercion rethink
72   sub user_object :Local Args(User) Coerce(1) {
73     my ($self, $c, $user) = @_;
74     $c->res->body("name: $user->{name}, age: $user->{age}");
75   }
76
77   sub an_int :Local Args(Int) {
78     my ($self, $c, $int) = @_;
79     $c->res->body('an_int');
80   }
81
82   sub two_ints :Local Args(Int,Int) {
83     my ($self, $c, $int) = @_;
84     $c->res->body('two_ints');
85   }
86
87   sub many_ints :Local Args(ArrayRef[Int]) {
88     my ($self, $c, $int) = @_;
89     $c->res->body('many_ints');
90   }
91
92   sub tuple :Local Args(Tuple[Str,Int]) {
93     my ($self, $c, $str, $int) = @_;
94     $c->res->body('tuple');
95   }
96
97   sub match :Local Args(StrMatch[qr{\d\d-\d\d-\d\d}]) {
98     my ($self, $c, $int) = @_;
99     $c->res->body('match');
100   }
101
102   sub any_priority :Path('priority_test') Args(1) { $_[1]->res->body('any_priority') }
103
104   sub int_priority :Path('priority_test') Args(Int) { $_[1]->res->body('int_priority') }
105
106   sub chain_base :Chained(/) CaptureArgs(1) { }
107
108     sub any_priority_chain :Chained(chain_base) PathPart('') Args(1) { $_[1]->res->body('any_priority_chain') }
109
110     sub int_priority_chain :Chained(chain_base) PathPart('') Args(Int) { $_[1]->res->body('int_priority_chain') }
111
112     sub link_any :Chained(chain_base) PathPart('') CaptureArgs(1) { }
113
114       sub any_priority_link_any :Chained(link_any) PathPart('') Args(1) { $_[1]->res->body('any_priority_link_any') }
115
116       sub int_priority_link_any :Chained(link_any) PathPart('') Args(Int) { $_[1]->res->body('int_priority_link_any') }
117     
118     sub link_int :Chained(chain_base) PathPart('') CaptureArgs(Int) { }
119
120       sub any_priority_link :Chained(link_int) PathPart('') Args(1) { $_[1]->res->body('any_priority_link') }
121
122       sub int_priority_link :Chained(link_int) PathPart('') Args(Int) { $_[1]->res->body('int_priority_link') }
123
124     sub link_int_int :Chained(chain_base) PathPart('') CaptureArgs(Int,Int) { }
125
126       sub any_priority_link2 :Chained(link_int_int) PathPart('') Args(1) { $_[1]->res->body('any_priority_link2') }
127
128       sub int_priority_link2 :Chained(link_int_int) PathPart('') Args(Int) { $_[1]->res->body('int_priority_link2') }
129
130     sub link_tuple :Chained(chain_base) PathPart('') CaptureArgs(Tuple[Int,Int,Int]) { }
131
132       sub any_priority_link3 :Chained(link_tuple) PathPart('') Args(1) { $_[1]->res->body('any_priority_link3') }
133
134       sub int_priority_link3 :Chained(link_tuple) PathPart('') Args(Int) { $_[1]->res->body('int_priority_link3') }
135
136
137   sub default :Default {
138     my ($self, $c, $int) = @_;
139     $c->res->body('default');
140   }
141
142   MyApp::Controller::Root->config(namespace=>'');
143
144   package MyApp;
145   use Catalyst;
146
147   MyApp->setup;
148 }
149
150 use Catalyst::Test 'MyApp';
151
152 {
153   my $res = request '/an_int/1';
154   is $res->content, 'an_int';
155 }
156
157 {
158   my $res = request '/an_int/aa';
159   is $res->content, 'default';
160 }
161
162 {
163   my $res = request '/many_ints/1';
164   is $res->content, 'many_ints';
165 }
166
167 {
168   my $res = request '/many_ints/1/2';
169   is $res->content, 'many_ints';
170 }
171
172 {
173   my $res = request '/many_ints/1/2/3';
174   is $res->content, 'many_ints';
175 }
176
177 {
178   my $res = request '/priority_test/1';
179   is $res->content, 'int_priority';
180 }
181
182 {
183   my $res = request '/priority_test/a';
184   is $res->content, 'any_priority';
185 }
186
187 {
188   my $res = request '/match/11-22-33';
189   is $res->content, 'match';
190 }
191
192 {
193   my $res = request '/match/aaa';
194   is $res->content, 'default';
195 }
196
197 {
198   my $res = request '/user/2';
199   is $res->content, 'name: mary, age: 36';
200 }
201
202 {
203   my $res = request '/user/20';
204   is $res->content, 'default';
205 }
206
207
208 SKIP: {
209   skip "coercion support needs more thought", 1;
210   my $res = request '/user_object/20';
211   is $res->content, 'default';
212 }
213
214 SKIP: {
215   skip "coercion support needs more thought", 1;
216   my $res = request '/user_object/2';
217   is $res->content, 'name: mary, age: 36';
218 }
219
220 {
221   my $res = request '/chain_base/capture/arg';
222   is $res->content, 'any_priority_chain';
223 }
224
225 {
226   my $res = request '/chain_base/cap1/100/arg';
227   is $res->content, 'any_priority_link';
228 }
229
230 {
231   my $res = request '/chain_base/cap1/101/102';
232   is $res->content, 'int_priority_link';
233 }
234
235 {
236   my $res = request '/chain_base/capture/100';
237   is $res->content, 'int_priority_chain', 'got expected';
238 }
239
240 {
241   my $res = request '/chain_base/cap1/a/arg';
242   is $res->content, 'any_priority_link_any';
243 }
244
245 {
246   my $res = request '/chain_base/cap1/a/102';
247   is $res->content, 'int_priority_link_any';
248 }
249
250 {
251   my $res = request '/two_ints/1/2';
252   is $res->content, 'two_ints';
253 }
254
255 {
256   my $res = request '/two_ints/aa/111';
257   is $res->content, 'default';
258 }
259
260 {
261   my $res = request '/tuple/aaa/aaa';
262   is $res->content, 'default';
263 }
264
265 {
266   my $res = request '/tuple/aaa/111';
267   is $res->content, 'tuple';
268 }
269
270 {
271   my $res = request '/many_ints/1/2/a';
272   is $res->content, 'default';
273 }
274
275 {
276   my $res = request '/chain_base/100/100/100/100';
277   is $res->content, 'int_priority_link2';
278 }
279
280 {
281   my $res = request '/chain_base/100/ss/100/100';
282   is $res->content, 'default';
283 }
284
285 {
286   my $res = request '/chain_base/100/100/100/100/100';
287   is $res->content, 'int_priority_link3';
288 }
289
290 {
291   my $res = request '/chain_base/100/ss/100/100/100';
292   is $res->content, 'default';
293 }
294
295 #{
296   # URI testing
297   #my ($res, $c) = ctx_request '/';
298
299
300 #}
301
302 done_testing;