package A; sub b { } 1; package Bar; sub foo { } 1; package Bar::Foo; sub baz { } 1; use strict; use warnings; BEGIN { my $DOWARN = 0; $SIG{'__WARN__'} = sub { warn $_[0] if $DOWARN } } use Test::More; use Kelp::Routes; my $r = Kelp::Routes->new; # Basic # { $r->add( '/a' => 'a#b' ); is_deeply _d( $r, qw/pattern to/ ), [ { pattern => '/a', to => 'A::b' } ]; } # Via method # { $r->clear; $r->add( [ POST => '/a' ] => 'a#b' ); is_deeply _d( $r, qw/method pattern to/ ), [ { method => 'POST', pattern => '/a', to => 'A::b' } ]; } # Odd method # { $r->clear; $r->add( [ MOST => '/a' ] => 'a#b' ); is_deeply _d( $r, qw/method pattern to/ ), [ { method => 'MOST', pattern => '/a', to => 'A::b' } ]; } # Sub # { $r->clear; $r->add( '/a' => sub { } ); is ref( $r->routes->[0]->to ), 'CODE'; } # Not hash # { $r->clear; $r->add( '/a' => [] ); is_deeply $r->routes, []; } # Weird key # { $r->clear; $r->add( { a => 1 }, 'a#b' ); is_deeply $r->routes, []; $r->add( [ POST => { a => 1 } ], 'a#b' ); is_deeply $r->routes, []; } # Missing destination # { $r->clear; $r->add( '/a' => { name => 'a' } ); is_deeply $r->routes, []; } # Key trumps method in the value { $r->clear; $r->add( [ POST => '/a' ] => { to => 'a', method => 'PUT' } ); is_deeply _d( $r, qw/method/ ), [ { method => 'POST' } ]; } # Regex # { $r->clear; my $re = qr{^/a/(\w+)$}; $r->add( $re, 'bar#foo' ); is_deeply _d( $r, qw/pattern/ ), [ { pattern => $re } ]; } # Hash # { $r->clear; my $hash = { name => 'james', check => { a => '\d' }, to => 'bar#foo' }; $r->add( '/:a' => $hash ); is_deeply _d( $r, qw/name check to/ ), [ { name => 'james', check => { a => '\d' }, to => 'Bar::foo' } ]; } # Base # { $r->clear; $r->base('Bar'); $r->add( '/a' => 'foo#baz' ); is_deeply _d( $r, qw/to/ ), [ { to => 'Bar::Foo::baz' } ]; $r->base(''); } # Base + fully qualified name { $r->clear; $r->base('Bar'); $r->add( '/a' => '+Plack::Util::load_class' ); is_deeply _d( $r, qw/to/ ), [ { to => 'Plack::Util::load_class' } ]; $r->clear; $r->add( '/a' => '+plack#util#load_class'); is_deeply _d( $r, qw/to/ ), [ { to => 'Plack::Util::load_class' } ]; $r->base(''); } # Tree # { # Tree not ARRAY $r->clear; $r->add( '/user' => { tree => { a => 1, b => 2 } } ); is_deeply $r->routes, []; # Tree no name $r->clear; $r->add( '/a' => { to => 'a', tree => [ '/b' => { name => 'b', to => 'a#b' }, '/c' => 'a#c' ] } ); is_deeply _d( $r, 'name' ), [ {}, { name => 'b' }, {} ]; # Good tree $r->clear; $r->add( '/user' => { name => 'user', to => 'bar#user', tree => [ '/id' => { to => 'bar#id', name => 'id' }, '/edit' => { to => 'bar#edit', name => 'edit' }, [ DELETE => '/id' ] => { to => 'bar#del' => name => 'delete' }, '/change' => { to => 'bar#change', name => 'change', tree => [ '/name' => { to => 'bar#change_name', name => 'name' }, [ PUT => '/email' ] => { to => 'bar#change_email', name => 'email' } ] } ] } ); is_deeply _d( $r, qw/pattern name to method/ ), [ { pattern => '/user', name => 'user', to => 'Bar::user', }, { pattern => '/user/id', name => 'user_id', to => 'Bar::id', }, { pattern => '/user/edit', name => 'user_edit', to => 'Bar::edit', }, { pattern => '/user/id', name => 'user_delete', to => 'Bar::del', method => 'DELETE' }, { pattern => '/user/change', name => 'user_change', to => 'Bar::change' }, { pattern => '/user/change/name', name => 'user_change_name', to => 'Bar::change_name' }, { pattern => '/user/change/email', name => 'user_change_email', to => 'Bar::change_email', method => 'PUT' } ]; } sub _d { my ( $r, @fields ) = @_; my @o = (); for my $route ( @{ $r->routes } ) { my @a = scalar(@fields) ? @fields : keys %{$route}; my %h = (); for my $k (@a) { $h{$k} = $route->{$k} if ( defined $route->{$k} ); } push @o, \%h; } return \@o; } done_testing;