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