7 use lib "$FindBin::Bin/lib";
11 BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 2; }
13 use Test::More tests => 66*$iters;
14 use Catalyst::Test 'TestApp';
16 if ( $ENV{CAT_BENCHMARK} ) {
18 Benchmark::timethis( $iters, \&run_tests );
29 # This is a simple test where the parent and child actions are
30 # within the same controller.
34 TestApp::Controller::Action::Chained->begin
35 TestApp::Controller::Action::Chained->foo
36 TestApp::Controller::Action::Chained->endpoint
37 TestApp::Controller::Action::Chained->end
40 my $expected = join( ", ", @expected );
42 ok( my $response = request('http://localhost/chained/foo/1/end/2'), 'chained + local endpoint' );
43 is( $response->header('X-Catalyst-Executed'),
44 $expected, 'Executed actions' );
45 is( $response->content, '1; 2', 'Content OK' );
49 # This makes sure the above isn't found if the argument for the
50 # end action isn't supplied.
55 ok( my $response = request('http://localhost/chained/foo/1/end'),
56 'chained + local endpoint; missing last argument' );
57 is( $response->header('X-Catalyst-Executed'),
58 $expected, 'Executed actions' );
59 is( $response->header('Status'), 500, 'Status OK' );
63 # Tests the case when the child action is placed in a subcontroller.
67 TestApp::Controller::Action::Chained->begin
68 TestApp::Controller::Action::Chained->foo
69 TestApp::Controller::Action::Chained::Foo->spoon
70 TestApp::Controller::Action::Chained->end
73 my $expected = join( ", ", @expected );
75 ok( my $response = request('http://localhost/chained/foo/1/spoon'), 'chained + subcontroller endpoint' );
76 is( $response->header('X-Catalyst-Executed'),
77 $expected, 'Executed actions' );
78 is( $response->content, '1; ', 'Content OK' );
82 # Tests if the relative specification (e.g.: Chained('bar') ) works
87 TestApp::Controller::Action::Chained->begin
88 TestApp::Controller::Action::Chained->bar
89 TestApp::Controller::Action::Chained->finale
90 TestApp::Controller::Action::Chained->end
93 my $expected = join( ", ", @expected );
95 ok( my $response = request('http://localhost/chained/bar/1/spoon'), 'chained + relative endpoint' );
96 is( $response->header('X-Catalyst-Executed'),
97 $expected, 'Executed actions' );
98 is( $response->content, '; 1, spoon', 'Content OK' );
102 # Just a test for multiple arguments.
106 TestApp::Controller::Action::Chained->begin
107 TestApp::Controller::Action::Chained->foo2
108 TestApp::Controller::Action::Chained->endpoint2
109 TestApp::Controller::Action::Chained->end
112 my $expected = join( ", ", @expected );
114 ok( my $response = request('http://localhost/chained/foo2/10/20/end2/15/25'),
115 'chained + local (2 args each)' );
116 is( $response->header('X-Catalyst-Executed'),
117 $expected, 'Executed actions' );
118 is( $response->content, '10, 20; 15, 25', 'Content OK' );
122 # The first three-chain test tries to call the action with :Args(1)
123 # specification. There's also a one action with a :Captures(1)
124 # attribute, that should not be dispatched to.
128 TestApp::Controller::Action::Chained->begin
129 TestApp::Controller::Action::Chained->one_end
130 TestApp::Controller::Action::Chained->end
133 my $expected = join( ", ", @expected );
135 ok( my $response = request('http://localhost/chained/one/23'),
136 'three-chain (only first)' );
137 is( $response->header('X-Catalyst-Executed'),
138 $expected, 'Executed actions' );
139 is( $response->content, '; 23', 'Content OK' );
143 # This is the second three-chain test, it goes for the action that
144 # handles "/one/$cap/two/$arg1/$arg2" paths. Should be the two action
145 # having :Args(2), not the one having :Captures(2).
149 TestApp::Controller::Action::Chained->begin
150 TestApp::Controller::Action::Chained->one
151 TestApp::Controller::Action::Chained->two_end
152 TestApp::Controller::Action::Chained->end
155 my $expected = join( ", ", @expected );
157 ok( my $response = request('http://localhost/chained/one/23/two/23/46'),
158 'three-chain (up to second)' );
159 is( $response->header('X-Catalyst-Executed'),
160 $expected, 'Executed actions' );
161 is( $response->content, '23; 23, 46', 'Content OK' );
165 # Last of the three-chain tests. Has no concurrent action with :Captures
166 # and is more thought to simply test the chain as a whole and the 'two'
167 # action specifying :Captures.
171 TestApp::Controller::Action::Chained->begin
172 TestApp::Controller::Action::Chained->one
173 TestApp::Controller::Action::Chained->two
174 TestApp::Controller::Action::Chained->three_end
175 TestApp::Controller::Action::Chained->end
178 my $expected = join( ", ", @expected );
180 ok( my $response = request('http://localhost/chained/one/23/two/23/46/three/1/2/3'),
181 'three-chain (all three)' );
182 is( $response->header('X-Catalyst-Executed'),
183 $expected, 'Executed actions' );
184 is( $response->content, '23, 23, 46; 1, 2, 3', 'Content OK' );
188 # Tests dispatching on number of arguments for :Args. This should be
189 # dispatched to the action expecting one argument.
193 TestApp::Controller::Action::Chained->begin
194 TestApp::Controller::Action::Chained->multi1
195 TestApp::Controller::Action::Chained->end
198 my $expected = join( ", ", @expected );
200 ok( my $response = request('http://localhost/chained/multi/23'),
201 'multi-action (one arg)' );
202 is( $response->header('X-Catalyst-Executed'),
203 $expected, 'Executed actions' );
204 is( $response->content, '; 23', 'Content OK' );
208 # Belongs to the former test and goes for the action expecting two arguments.
212 TestApp::Controller::Action::Chained->begin
213 TestApp::Controller::Action::Chained->multi2
214 TestApp::Controller::Action::Chained->end
217 my $expected = join( ", ", @expected );
219 ok( my $response = request('http://localhost/chained/multi/23/46'),
220 'multi-action (two args)' );
221 is( $response->header('X-Catalyst-Executed'),
222 $expected, 'Executed actions' );
223 is( $response->content, '; 23, 46', 'Content OK' );
227 # Dispatching on argument count again, this time we provide too many
228 # arguments, so dispatching should fail.
231 my $expected = undef;
233 ok( my $response = request('http://localhost/chained/multi/23/46/67'),
234 'multi-action (three args, should lead to error)' );
235 is( $response->header('X-Catalyst-Executed'),
236 $expected, 'Executed actions' );
237 is( $response->header('Status'), 500, 'Status OK' );
241 # This tests the case when an action says it's the child of an action in
246 TestApp::Controller::Action::Chained->begin
247 TestApp::Controller::Action::Chained::Foo->higher_root
248 TestApp::Controller::Action::Chained->higher_root
249 TestApp::Controller::Action::Chained->end
252 my $expected = join( ", ", @expected );
254 ok( my $response = request('http://localhost/chained/higher_root/23/bar/11'),
255 'root higher than child' );
256 is( $response->header('X-Catalyst-Executed'),
257 $expected, 'Executed actions' );
258 is( $response->content, '23; 11', 'Content OK' );
262 # Just a more complex version of the former test. It tests if a controller ->
263 # subcontroller -> controller dispatch works.
267 TestApp::Controller::Action::Chained->begin
268 TestApp::Controller::Action::Chained->pcp1
269 TestApp::Controller::Action::Chained::Foo->pcp2
270 TestApp::Controller::Action::Chained->pcp3
271 TestApp::Controller::Action::Chained->end
274 my $expected = join( ", ", @expected );
276 ok( my $response = request('http://localhost/chained/pcp1/1/pcp2/2/pcp3/3'),
277 'parent -> child -> parent' );
278 is( $response->header('X-Catalyst-Executed'),
279 $expected, 'Executed actions' );
280 is( $response->content, '1, 2; 3', 'Content OK' );
284 # Tests dispatch on capture number. This test is for a one capture action.
288 TestApp::Controller::Action::Chained->begin
289 TestApp::Controller::Action::Chained->multi_cap1
290 TestApp::Controller::Action::Chained->multi_cap_end1
291 TestApp::Controller::Action::Chained->end
294 my $expected = join( ", ", @expected );
296 ok( my $response = request('http://localhost/chained/multi_cap/1/baz'),
297 'dispatch on capture num 1' );
298 is( $response->header('X-Catalyst-Executed'),
299 $expected, 'Executed actions' );
300 is( $response->content, '1; ', 'Content OK' );
304 # Belongs to the former test. This one goes for the action expecting two
309 TestApp::Controller::Action::Chained->begin
310 TestApp::Controller::Action::Chained->multi_cap2
311 TestApp::Controller::Action::Chained->multi_cap_end2
312 TestApp::Controller::Action::Chained->end
315 my $expected = join( ", ", @expected );
317 ok( my $response = request('http://localhost/chained/multi_cap/1/2/baz'),
318 'dispatch on capture num 2' );
319 is( $response->header('X-Catalyst-Executed'),
320 $expected, 'Executed actions' );
321 is( $response->content, '1, 2; ', 'Content OK' );
325 # Tests the priority of a slurpy arguments action (with :Args) against
326 # two actions chained together. The two actions should win.
330 TestApp::Controller::Action::Chained->begin
331 TestApp::Controller::Action::Chained->priority_a2
332 TestApp::Controller::Action::Chained->priority_a2_end
333 TestApp::Controller::Action::Chained->end
336 my $expected = join( ", ", @expected );
338 ok( my $response = request('http://localhost/chained/priority_a/1/end/2'),
339 'priority - slurpy args vs. parent/child' );
340 is( $response->header('X-Catalyst-Executed'),
341 $expected, 'Executed actions' );
342 is( $response->content, '1; 2', 'Content OK' );
346 # This belongs to the former test but tests if two chained actions have
347 # priority over an action with the exact arguments.
351 TestApp::Controller::Action::Chained->begin
352 TestApp::Controller::Action::Chained->priority_b2
353 TestApp::Controller::Action::Chained->priority_b2_end
354 TestApp::Controller::Action::Chained->end
357 my $expected = join( ", ", @expected );
359 ok( my $response = request('http://localhost/chained/priority_b/1/end/2'),
360 'priority - fixed args vs. parent/child' );
361 is( $response->header('X-Catalyst-Executed'),
362 $expected, 'Executed actions' );
363 is( $response->content, '1; 2', 'Content OK' );
367 # Test dispatching between two controllers that are on the same level and
368 # therefor have no parent/child relationship.
372 TestApp::Controller::Action::Chained->begin
373 TestApp::Controller::Action::Chained::Bar->cross1
374 TestApp::Controller::Action::Chained::Foo->cross2
375 TestApp::Controller::Action::Chained->end
378 my $expected = join( ", ", @expected );
380 ok( my $response = request('http://localhost/chained/cross/1/end/2'),
381 'cross controller w/o par/child relation' );
382 is( $response->header('X-Catalyst-Executed'),
383 $expected, 'Executed actions' );
384 is( $response->content, '1; 2', 'Content OK' );
388 # This is for testing if the arguments got passed to the actions
393 TestApp::Controller::Action::Chained->begin
394 TestApp::Controller::Action::Chained::PassedArgs->first
395 TestApp::Controller::Action::Chained::PassedArgs->second
396 TestApp::Controller::Action::Chained::PassedArgs->third
397 TestApp::Controller::Action::Chained::PassedArgs->end
400 my $expected = join( ", ", @expected );
402 ok( my $response = request('http://localhost/chained/passedargs/a/1/b/2/c/3'),
403 'Correct arguments passed to actions' );
404 is( $response->header('X-Catalyst-Executed'),
405 $expected, 'Executed actions' );
406 is( $response->content, '1; 2; 3', 'Content OK' );
410 # The :Args attribute is optional, we check the action not specifying
411 # it with these tests.
415 TestApp::Controller::Action::Chained->begin
416 TestApp::Controller::Action::Chained->opt_args
417 TestApp::Controller::Action::Chained->end
420 my $expected = join( ", ", @expected );
422 ok( my $response = request('http://localhost/chained/opt_args/1/2/3'),
423 'Optional :Args attribute working' );
424 is( $response->header('X-Catalyst-Executed'),
425 $expected, 'Executed actions' );
426 is( $response->content, '; 1, 2, 3', 'Content OK' );
430 # Tests for optional PathPart attribute.
434 TestApp::Controller::Action::Chained->begin
435 TestApp::Controller::Action::Chained->opt_pp_start
436 TestApp::Controller::Action::Chained->opt_pathpart
437 TestApp::Controller::Action::Chained->end
440 my $expected = join( ", ", @expected );
442 ok( my $response = request('http://localhost/chained/optpp/1/opt_pathpart/2'),
443 'Optional :PathName attribute working' );
444 is( $response->header('X-Catalyst-Executed'),
445 $expected, 'Executed actions' );
446 is( $response->content, '1; 2', 'Content OK' );
450 # Tests for optional PathPart *and* Args attributes.
454 TestApp::Controller::Action::Chained->begin
455 TestApp::Controller::Action::Chained->opt_all_start
456 TestApp::Controller::Action::Chained->oa
457 TestApp::Controller::Action::Chained->end
460 my $expected = join( ", ", @expected );
462 ok( my $response = request('http://localhost/chained/optall/1/oa/2/3'),
463 'Optional :PathName *and* :Args attributes working' );
464 is( $response->header('X-Catalyst-Executed'),
465 $expected, 'Executed actions' );
466 is( $response->content, '1; 2, 3', 'Content OK' );