Permalink
Browse files

added match method to Mojolicious::Routes

  • Loading branch information...
1 parent 0794b38 commit 50afa0d04dd6358809e3a34d09b47e34c441bf7f @kraih committed Mar 9, 2014
Showing with 68 additions and 52 deletions.
  1. +1 −0 Changes
  2. +42 −38 lib/Mojolicious/Routes.pm
  3. +25 −14 t/mojolicious/dispatch.t
View
@@ -1,6 +1,7 @@
4.88 2014-03-09
- Added build_controller method to Mojolicious.
+ - Added match method to Mojolicious::Routes.
- Improved Mojo::Server::Daemon to handle setuid/setgid errors more
gracefully.
- Improved Mojo::Server::Prefork to handle lock file errors more gracefully.
View
@@ -48,41 +48,8 @@ sub continue {
sub dispatch {
my ($self, $c) = @_;
-
- # Path (partial path gets priority)
- my $req = $c->req;
- my $path = $c->stash->{path};
- if (defined $path) { $path = "/$path" if $path !~ m!^/! }
- else { $path = $req->url->path->to_route }
-
- # Method (HEAD will be treated as GET)
- my $method = uc $req->method;
- $method = 'GET' if $method eq 'HEAD';
-
- # Check cache
- my $cache = $self->cache;
- my $ws = $c->tx->is_websocket ? 1 : 0;
- my $match = Mojolicious::Routes::Match->new(root => $self);
- $c->match($match);
- if ($cache && (my $cached = $cache->get("$method:$path:$ws"))) {
- $match->endpoint($cached->{endpoint})->stack($cached->{stack});
- }
-
- # Check routes
- else {
- my $options = {method => $method, path => $path, websocket => $ws};
- $match->match($c => $options);
-
- # Cache routes without conditions
- if ($cache && (my $endpoint = $match->endpoint)) {
- my $result = {endpoint => $endpoint, stack => $match->stack};
- $cache->set("$method:$path:$ws" => $result)
- unless $endpoint->has_conditions;
- }
- }
-
- return undef unless @{$c->match->stack};
- $self->continue($c);
+ $self->match($c);
+ @{$c->match->stack} ? $self->continue($c) : return undef;
return 1;
}
@@ -102,6 +69,37 @@ sub lookup {
return $reverse->{$name} = $route;
}
+sub match {
+ my ($self, $c) = @_;
+
+ # Path (partial path gets priority)
+ my $req = $c->req;
+ my $path = $c->stash->{path};
+ if (defined $path) { $path = "/$path" if $path !~ m!^/! }
+ else { $path = $req->url->path->to_route }
+
+ # Method (HEAD will be treated as GET)
+ my $method = uc $req->method;
+ $method = 'GET' if $method eq 'HEAD';
+
+ # Check cache
+ my $ws = $c->tx->is_websocket ? 1 : 0;
+ my $match = Mojolicious::Routes::Match->new(root => $self);
+ $c->match($match);
+ my $cache = $self->cache;
+ my $cached = $cache ? $cache->get("$method:$path:$ws") : undef;
+ return $match->endpoint($cached->{endpoint})->stack($cached->{stack})
+ if $cached;
+
+ # Check routes
+ $match->match($c => {method => $method, path => $path, websocket => $ws});
+
+ # Cache routes without conditions
+ return unless $cache && (my $endpoint = $match->endpoint);
+ my $result = {endpoint => $endpoint, stack => $match->stack};
+ $cache->set("$method:$path:$ws" => $result) unless $endpoint->has_conditions;
+}
+
sub route {
shift->add_child(Mojolicious::Routes::Route->new(@_))->children->[-1];
}
@@ -327,14 +325,14 @@ Automatic rendering.
$r->continue(Mojolicious::Controller->new);
-Continue dispatch chain.
+Continue dispatch chain and emit the hook L<Mojolicious/"around_action"> for
+every action.
=head2 dispatch
my $bool = $r->dispatch(Mojolicious::Controller->new);
-Match routes with L<Mojolicious::Routes::Match> and dispatch, emits the hook
-L<Mojolicious/"around_action"> for every action.
+Match routes with L</"match"> and dispatch with L</"continue">.
=head2 hide
@@ -355,6 +353,12 @@ Check if controller attribute or method is hidden from router.
Find route by name with L<Mojolicious::Routes::Route/"find"> and cache all
results for future lookups.
+=head2 match
+
+ $r->match(Mojolicious::Controller->new);
+
+Match routes with L<Mojolicious::Routes::Match>.
+
=head2 route
my $route = $r->route;
View
@@ -9,15 +9,12 @@ use Mojo::Base 'Mojolicious::Controller';
has 'render_called';
-sub render { shift->render_called(1) }
-
-sub reset_state {
- my $self = shift;
- $self->render_called(0);
- my $stash = $self->stash;
- delete @$stash{keys %$stash};
+sub new {
+ shift->SUPER::new(@_)->tap(sub { $_->app->log->level('fatal') });
}
+sub render { shift->render_called(1) }
+
package main;
use Mojo::Base -strict;
@@ -104,38 +101,52 @@ is_deeply [$c->param], [], 'values are hidden';
# Controller with application and routes
$c = Test::Controller->new;
-$c->app->log->level('fatal');
my $d = $c->app->routes;
ok $d, 'initialized';
$d->namespaces(['Test']);
$d->route('/')->over([])->to(controller => 'foo', action => 'home');
$d->route('/foo/(capture)')->to(controller => 'foo', action => 'bar');
# Cache
-$c->reset_state;
+$c = Test::Controller->new;
my $tx = Mojo::Transaction::HTTP->new;
$tx->req->method('GET');
$tx->req->url->parse('/');
$c->tx($tx);
ok $d->dispatch($c), 'dispatched';
is $c->stash->{controller}, 'foo', 'right value';
is $c->stash->{action}, 'home', 'right value';
+is $c->match->stack->[0]{controller}, 'foo', 'right value';
+is $c->match->stack->[0]{action}, 'home', 'right value';
ok $c->render_called, 'rendered';
my $cache = $d->cache->get('GET:/:0');
ok $cache, 'route has been cached';
-$c->reset_state;
+$c = Test::Controller->new;
+$tx = Mojo::Transaction::HTTP->new;
+$tx->req->method('GET');
+$tx->req->url->parse('/');
+$c->tx($tx);
+$d->match($c);
+is $c->stash->{controller}, undef, 'no value';
+is $c->stash->{action}, undef, 'no value';
+is $c->match->stack->[0]{controller}, 'foo', 'right value';
+is $c->match->stack->[0]{action}, 'home', 'right value';
+ok !$c->render_called, 'not rendered';
+$c = Test::Controller->new;
$tx = Mojo::Transaction::HTTP->new;
$tx->req->method('GET');
$tx->req->url->parse('/');
$c->tx($tx);
ok $d->dispatch($c), 'dispatched';
is $c->stash->{controller}, 'foo', 'right value';
is $c->stash->{action}, 'home', 'right value';
+is $c->match->stack->[0]{controller}, 'foo', 'right value';
+is $c->match->stack->[0]{action}, 'home', 'right value';
ok $c->render_called, 'rendered';
is_deeply $d->cache->get('GET:/:0'), $cache, 'cached route has been reused';
# 404 clean stash
-$c->reset_state;
+$c = Test::Controller->new;
$tx = Mojo::Transaction::HTTP->new;
$tx->req->method('GET');
$tx->req->url->parse('/not_found');
@@ -145,7 +156,7 @@ is_deeply $c->stash, {}, 'empty stash';
ok !$c->render_called, 'nothing rendered';
# No escaping
-$c->reset_state;
+$c = Test::Controller->new;
$tx = Mojo::Transaction::HTTP->new;
$tx->req->method('POST');
$tx->req->url->parse('/foo/hello');
@@ -193,7 +204,7 @@ is_deeply [$c->param], [qw(action bar capture foo)], 'right names';
ok $c->render_called, 'rendered';
# Escaping
-$c->reset_state;
+$c = Test::Controller->new;
$tx = Mojo::Transaction::HTTP->new;
$tx->req->method('GET');
$tx->req->url->parse('/foo/hello%20there');
@@ -208,7 +219,7 @@ is $c->param('capture'), 'hello there', 'right value';
ok $c->render_called, 'rendered';
# Escaping UTF-8
-$c->reset_state;
+$c = Test::Controller->new;
$tx = Mojo::Transaction::HTTP->new;
$tx->req->method('GET');
$tx->req->url->parse('/foo/%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82');

0 comments on commit 50afa0d

Please sign in to comment.