sub begin :Private { }
+#
+# Simple parent/child action test
+#
sub foo :PathPart('childof/foo') :Captures(1) :ChildOf('/') { }
-sub foo2 :PathPart('childof/foo2') :Captures(2) :ChildOf('/') { }
-
-sub bar :PathPart('childof/bar') :ChildOf('/') { }
-
sub endpoint :PathPart('end') :ChildOf('/action/childof/foo') :Args(1) { }
+
+#
+# Parent/child test with two args each
+#
+sub foo2 :PathPart('childof/foo2') :Captures(2) :ChildOf('/') { }
sub endpoint2 :PathPart('end2') :ChildOf('/action/childof/foo2') :Args(2) { }
+#
+# Relative specification of parent action
+#
+sub bar :PathPart('childof/bar') :ChildOf('/') { }
sub finale :ChildOf('bar') :Args { }
+#
+# three chain with concurrent endpoints
+#
sub one :PathPart('childof/one') :ChildOf('/') :Captures(1) { }
sub two :PathPart('two') :ChildOf('/action/childof/one') :Captures(2) { }
-
sub three_end :PathPart('three') :ChildOf('two') :Args(3) { }
sub one_end :PathPart('childof/one') :ChildOf('/') :Args(1) { }
sub two_end :PathPart('two') :ChildOf('one') :Args(2) { }
+#
+# Dispatch on number of arguments
+#
sub multi1 :PathPart('childof/multi') :ChildOf('/') :Args(1) { }
sub multi2 :PathPart('childof/multi') :ChildOf('/') :Args(2) { }
+#
+# Roots in an action defined in a higher controller
+#
+sub higher_root :PathPart('bar') :ChildOf('/action/childof/foo/higher_root') :Args(1) { }
+
+#
+# Controller -> subcontroller -> controller
+#
+sub pcp1 :PathPart('childof/pcp1') :ChildOf('/') :Captures(1) { }
+sub pcp3 :PathPart :ChildOf('/action/childof/foo/pcp2') :Args(1) { }
+
+#
+# Dispatch on capture number
+#
+sub multi_cap1 :PathPart('childof/multi_cap') :ChildOf('/') :Captures(1) { }
+sub multi_cap2 :PathPart('childof/multi_cap') :ChildOf('/') :Captures(2) { }
+sub multi_cap_end1 :PathPart('baz') :ChildOf('multi_cap1') :Args(0) { }
+sub multi_cap_end2 :PathPart('baz') :ChildOf('multi_cap2') :Args(0) { }
+
+#
+# Priority: Slurpy args vs. chained actions
+#
+sub priority_a1 :PathPart('childof/priority_a') :ChildOf('/') :Args { }
+sub priority_a2 :PathPart('childof/priority_a') :ChildOf('/') :Captures(1) { }
+sub priority_a2_end :PathPart('end') :ChildOf('priority_a2') :Args(1) { }
+
+#
+# Priority: Fixed args vs. chained actions
+#
+sub priority_b1 :PathPart('childof/priority_b') :ChildOf('/') :Args(3) { }
+sub priority_b2 :PathPart('childof/priority_b') :ChildOf('/') :Captures(1) { }
+sub priority_b2_end :PathPart('end') :ChildOf('priority_b2') :Args(1) { }
+
sub end :Private {
my ($self, $c) = @_;
my $out = join('; ', map { join(', ', @$_) }
BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 2; }
-use Test::More tests => 27*$iters;
+use Test::More tests => 54*$iters;
use Catalyst::Test 'TestApp';
if ( $ENV{CAT_BENCHMARK} ) {
}
sub run_tests {
+
+ #
+ # This is a simple test where the parent and child actions are
+ # within the same controller.
+ #
{
my @expected = qw[
TestApp::Controller::Action::ChildOf->begin
$expected, 'Executed actions' );
is( $response->content, '1; 2', 'Content OK' );
}
+
+ #
+ # This makes sure the above isn't found if the argument for the
+ # end action isn't supplied.
+ #
+ {
+ my $expected = undef;
+
+ ok( my $response = request('http://localhost/childof/foo/1/end'),
+ 'childof + local endpoint; missing last argument' );
+ is( $response->header('X-Catalyst-Executed'),
+ $expected, 'Executed actions' );
+ is( $response->header('Status'), 500, 'Status OK' );
+ }
+
+ #
+ # Tests the case when the child action is placed in a subcontroller.
+ #
{
my @expected = qw[
TestApp::Controller::Action::ChildOf->begin
$expected, 'Executed actions' );
is( $response->content, '1; ', 'Content OK' );
}
+
+ #
+ # Tests if the relative specification (e.g.: ChildOf('bar') ) works
+ # as expected.
+ #
{
my @expected = qw[
TestApp::Controller::Action::ChildOf->begin
$expected, 'Executed actions' );
is( $response->content, '; 1, spoon', 'Content OK' );
}
+
+ #
+ # Just a test for multiple arguments.
+ #
{
my @expected = qw[
TestApp::Controller::Action::ChildOf->begin
$expected, 'Executed actions' );
is( $response->content, '10, 20; 15, 25', 'Content OK' );
}
+
+ #
+ # The first three-chain test tries to call the action with :Args(1)
+ # specification. There's also a one action with a :Captures(1)
+ # attribute, that should not be dispatched to.
+ #
{
my @expected = qw[
TestApp::Controller::Action::ChildOf->begin
$expected, 'Executed actions' );
is( $response->content, '; 23', 'Content OK' );
}
+
+ #
+ # This is the second three-chain test, it goes for the action that
+ # handles "/one/$cap/two/$arg1/$arg2" paths. Should be the two action
+ # having :Args(2), not the one having :Captures(2).
+ #
{
my @expected = qw[
TestApp::Controller::Action::ChildOf->begin
$expected, 'Executed actions' );
is( $response->content, '23; 23, 46', 'Content OK' );
}
+
+ #
+ # Last of the three-chain tests. Has no concurrent action with :Captures
+ # and is more thought to simply test the chain as a whole and the 'two'
+ # action specifying :Captures.
+ #
{
my @expected = qw[
TestApp::Controller::Action::ChildOf->begin
$expected, 'Executed actions' );
is( $response->content, '23, 23, 46; 1, 2, 3', 'Content OK' );
}
+
+ #
+ # Tests dispatching on number of arguments for :Args. This should be
+ # dispatched to the action expecting one argument.
+ #
{
my @expected = qw[
TestApp::Controller::Action::ChildOf->begin
$expected, 'Executed actions' );
is( $response->content, '; 23', 'Content OK' );
}
+
+ #
+ # Belongs to the former test and goes for the action expecting two arguments.
+ #
{
my @expected = qw[
TestApp::Controller::Action::ChildOf->begin
$expected, 'Executed actions' );
is( $response->content, '; 23, 46', 'Content OK' );
}
+
+ #
+ # Dispatching on argument count again, this time we provide too many
+ # arguments, so dispatching should fail.
+ #
+ {
+ my $expected = undef;
+
+ ok( my $response = request('http://localhost/childof/multi/23/46/67'),
+ 'multi-action (three args, should lead to error)' );
+ is( $response->header('X-Catalyst-Executed'),
+ $expected, 'Executed actions' );
+ is( $response->header('Status'), 500, 'Status OK' );
+ }
+
+ #
+ # This tests the case when an action says it's the child of an action in
+ # a subcontroller.
+ #
+ {
+ my @expected = qw[
+ TestApp::Controller::Action::ChildOf->begin
+ TestApp::Controller::Action::ChildOf::Foo->higher_root
+ TestApp::Controller::Action::ChildOf->higher_root
+ TestApp::Controller::Action::ChildOf->end
+ ];
+
+ my $expected = join( ", ", @expected );
+
+ ok( my $response = request('http://localhost/childof/higher_root/23/bar/11'),
+ 'root higher than child' );
+ is( $response->header('X-Catalyst-Executed'),
+ $expected, 'Executed actions' );
+ is( $response->content, '23; 11', 'Content OK' );
+ }
+
+ #
+ # Just a more complex version of the former test. It tests if a controller ->
+ # subcontroller -> controller dispatch works.
+ #
+ {
+ my @expected = qw[
+ TestApp::Controller::Action::ChildOf->begin
+ TestApp::Controller::Action::ChildOf->pcp1
+ TestApp::Controller::Action::ChildOf::Foo->pcp2
+ TestApp::Controller::Action::ChildOf->pcp3
+ TestApp::Controller::Action::ChildOf->end
+ ];
+
+ my $expected = join( ", ", @expected );
+
+ ok( my $response = request('http://localhost/childof/pcp1/1/pcp2/2/pcp3/3'),
+ 'parent -> child -> parent' );
+ is( $response->header('X-Catalyst-Executed'),
+ $expected, 'Executed actions' );
+ is( $response->content, '1, 2; 3', 'Content OK' );
+ }
+
+ #
+ # Tests dispatch on capture number. This test is for a one capture action.
+ #
+ {
+ my @expected = qw[
+ TestApp::Controller::Action::ChildOf->begin
+ TestApp::Controller::Action::ChildOf->multi_cap1
+ TestApp::Controller::Action::ChildOf->multi_cap_end1
+ TestApp::Controller::Action::ChildOf->end
+ ];
+
+ my $expected = join( ", ", @expected );
+
+ ok( my $response = request('http://localhost/childof/multi_cap/1/baz'),
+ 'dispatch on capture num 1' );
+ is( $response->header('X-Catalyst-Executed'),
+ $expected, 'Executed actions' );
+ is( $response->content, '1; ', 'Content OK' );
+ }
+
+ #
+ # Belongs to the former test. This one goes for the action expecting two
+ # captures.
+ #
+ {
+ my @expected = qw[
+ TestApp::Controller::Action::ChildOf->begin
+ TestApp::Controller::Action::ChildOf->multi_cap2
+ TestApp::Controller::Action::ChildOf->multi_cap_end2
+ TestApp::Controller::Action::ChildOf->end
+ ];
+
+ my $expected = join( ", ", @expected );
+
+ ok( my $response = request('http://localhost/childof/multi_cap/1/2/baz'),
+ 'dispatch on capture num 2' );
+ is( $response->header('X-Catalyst-Executed'),
+ $expected, 'Executed actions' );
+ is( $response->content, '1, 2; ', 'Content OK' );
+ }
+
+ #
+ # Tests the priority of a slurpy arguments action (with :Args) against
+ # two actions chained together. The two actions should win.
+ #
+ {
+ my @expected = qw[
+ TestApp::Controller::Action::ChildOf->begin
+ TestApp::Controller::Action::ChildOf->priority_a2
+ TestApp::Controller::Action::ChildOf->priority_a2_end
+ TestApp::Controller::Action::ChildOf->end
+ ];
+
+ my $expected = join( ", ", @expected );
+
+ ok( my $response = request('http://localhost/childof/priority_a/1/end/2'),
+ 'priority - slurpy args vs. parent/child' );
+ is( $response->header('X-Catalyst-Executed'),
+ $expected, 'Executed actions' );
+ is( $response->content, '1; 2', 'Content OK' );
+ }
+
+ #
+ # This belongs to the former test but tests if two chained actions have
+ # priority over an action with the exact arguments.
+ #
+ {
+ my @expected = qw[
+ TestApp::Controller::Action::ChildOf->begin
+ TestApp::Controller::Action::ChildOf->priority_b2
+ TestApp::Controller::Action::ChildOf->priority_b2_end
+ TestApp::Controller::Action::ChildOf->end
+ ];
+
+ my $expected = join( ", ", @expected );
+
+ ok( my $response = request('http://localhost/childof/priority_b/1/end/2'),
+ 'priority - fixed args vs. parent/child' );
+ is( $response->header('X-Catalyst-Executed'),
+ $expected, 'Executed actions' );
+ is( $response->content, '1; 2', 'Content OK' );
+ }
+
+ #
+ # Test dispatching between two controllers that are on the same level and
+ # therefor have no parent/child relationship.
+ #
+ {
+ my @expected = qw[
+ TestApp::Controller::Action::ChildOf->begin
+ TestApp::Controller::Action::ChildOf::Bar->cross1
+ TestApp::Controller::Action::ChildOf::Foo->cross2
+ TestApp::Controller::Action::ChildOf->end
+ ];
+
+ my $expected = join( ", ", @expected );
+
+ ok( my $response = request('http://localhost/childof/cross/1/end/2'),
+ 'cross controller w/o par/child relation' );
+ is( $response->header('X-Catalyst-Executed'),
+ $expected, 'Executed actions' );
+ is( $response->content, '1; 2', 'Content OK' );
+ }
}