From: Matt S Trout Date: Thu, 22 Jun 2006 14:50:28 +0000 (+0000) Subject: More tests for ChildOf X-Git-Tag: 5.7099_04~502 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=commitdiff_plain;h=d416846e8bfec3729c4846017649fb306838af67;hp=922c58d694a7e5a98f428332abac06587815de79 More tests for ChildOf r10003@cain (orig r4367): phaylon | 2006-06-11 19:39:13 +0000 --- diff --git a/t/lib/TestApp/Controller/Action/ChildOf.pm b/t/lib/TestApp/Controller/Action/ChildOf.pm index 377c3d8..8370582 100644 --- a/t/lib/TestApp/Controller/Action/ChildOf.pm +++ b/t/lib/TestApp/Controller/Action/ChildOf.pm @@ -7,26 +7,72 @@ use base qw/Catalyst::Controller/; 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(', ', @$_) } diff --git a/t/lib/TestApp/Controller/Action/ChildOf/Bar.pm b/t/lib/TestApp/Controller/Action/ChildOf/Bar.pm new file mode 100644 index 0000000..f83a882 --- /dev/null +++ b/t/lib/TestApp/Controller/Action/ChildOf/Bar.pm @@ -0,0 +1,14 @@ +package TestApp::Controller::Action::ChildOf::Bar; + +use strict; +use warnings; + +use base qw/Catalyst::Controller/; + +# +# Redispatching between controllers that are not in a parent/child +# relation. This is the root. +# +sub cross1 :PathPart('childof/cross') :Captures(1) :ChildOf('/') { } + +1; diff --git a/t/lib/TestApp/Controller/Action/ChildOf/Foo.pm b/t/lib/TestApp/Controller/Action/ChildOf/Foo.pm index ffba0b3..1e1ea0a 100644 --- a/t/lib/TestApp/Controller/Action/ChildOf/Foo.pm +++ b/t/lib/TestApp/Controller/Action/ChildOf/Foo.pm @@ -5,6 +5,24 @@ use warnings; use base qw/Catalyst::Controller/; +# +# Child of current namespace +# sub spoon :PathPart :ChildOf('') :Args(0) { } +# +# Root for a action in a "parent" controller +# +sub higher_root :PathPart('childof/higher_root') :ChildOf('/') :Captures(1) { } + +# +# Parent controller -> this subcontroller -> parent controller test +# +sub pcp2 :PathPart :ChildOf('/action/childof/pcp1') :Captures(1) { } + +# +# Controllers not in parent/child relation. This tests the end. +# +sub cross2 :PathPart('end') :ChildOf('/action/childof/bar/cross1') :Args(1) { } + 1; diff --git a/t/live_component_controller_action_childof.t b/t/live_component_controller_action_childof.t index 4e1de89..384f849 100644 --- a/t/live_component_controller_action_childof.t +++ b/t/live_component_controller_action_childof.t @@ -10,7 +10,7 @@ our $iters; 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} ) { @@ -24,6 +24,11 @@ else { } 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 @@ -39,6 +44,24 @@ sub run_tests { $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 @@ -54,6 +77,11 @@ sub run_tests { $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 @@ -69,6 +97,10 @@ sub run_tests { $expected, 'Executed actions' ); is( $response->content, '; 1, spoon', 'Content OK' ); } + + # + # Just a test for multiple arguments. + # { my @expected = qw[ TestApp::Controller::Action::ChildOf->begin @@ -85,6 +117,12 @@ sub run_tests { $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 @@ -100,6 +138,12 @@ sub run_tests { $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 @@ -116,6 +160,12 @@ sub run_tests { $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 @@ -133,6 +183,11 @@ sub run_tests { $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 @@ -148,6 +203,10 @@ sub run_tests { $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 @@ -163,4 +222,165 @@ sub run_tests { $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' ); + } }