[Bps-public-commit] Path-Dispatcher branch, master, updated. 7fd79d2487d93bc880f76789abd06a6e935f0d74
sartak at bestpractical.com
sartak at bestpractical.com
Wed Jan 6 19:55:55 EST 2010
The branch, master has been updated
via 7fd79d2487d93bc880f76789abd06a6e935f0d74 (commit)
from c91a2f93d6e247575483b0a2b9e15a447c9c5ab7 (commit)
Summary of changes:
lib/Path/Dispatcher/Rule.pm | 1 +
lib/Path/Dispatcher/Rule/Sequence.pm | 44 +++++++++++
t/024-sequence.t | 136 ++++++++++++++++++++++++++++++++++
3 files changed, 181 insertions(+), 0 deletions(-)
create mode 100644 lib/Path/Dispatcher/Rule/Sequence.pm
create mode 100644 t/024-sequence.t
- Log -----------------------------------------------------------------
commit 7fd79d2487d93bc880f76789abd06a6e935f0d74
Author: Shawn M Moore <sartak at bestpractical.com>
Date: Wed Jan 6 19:55:43 2010 -0500
First cut of a generic Sequence rule (like Tokens but better)
diff --git a/lib/Path/Dispatcher/Rule.pm b/lib/Path/Dispatcher/Rule.pm
index b32dfaf..90ad4be 100644
--- a/lib/Path/Dispatcher/Rule.pm
+++ b/lib/Path/Dispatcher/Rule.pm
@@ -149,6 +149,7 @@ require Path::Dispatcher::Rule::Eq;
require Path::Dispatcher::Rule::Intersection;
require Path::Dispatcher::Rule::Metadata;
require Path::Dispatcher::Rule::Regex;
+require Path::Dispatcher::Rule::Sequence;
require Path::Dispatcher::Rule::Tokens;
require Path::Dispatcher::Rule::Under;
diff --git a/lib/Path/Dispatcher/Rule/Sequence.pm b/lib/Path/Dispatcher/Rule/Sequence.pm
new file mode 100644
index 0000000..1c800de
--- /dev/null
+++ b/lib/Path/Dispatcher/Rule/Sequence.pm
@@ -0,0 +1,44 @@
+package Path::Dispatcher::Rule::Sequence;
+use Any::Moose;
+use Any::Moose '::Util::TypeConstraints';
+
+extends 'Path::Dispatcher::Rule';
+with 'Path::Dispatcher::Role::Rules';
+
+has delimiter => (
+ is => 'rw',
+ isa => 'Str',
+ default => ' ',
+);
+
+sub _match {
+ my $self = shift;
+ my $path = shift;
+
+ my @rules = $self->rules;
+ my $delimiter = $self->delimiter;
+ my @matches;
+ my $leftover = $path->path; # start with everything leftover
+
+ for my $rule (@rules) {
+ my $match = $rule->match($path);
+ return if !$match;
+
+ $leftover = $match->leftover;
+
+ push @matches, substr($path, 0, length($path) - length($leftover));
+
+ $leftover =~ s/^\Q$delimiter\E+//;
+ return \@matches if length($leftover) == 0;
+
+ $path = $path->clone_path($leftover);
+ }
+
+ # leftover text
+ return \@matches, $leftover if $self->prefix;
+
+ return;
+}
+
+1;
+
diff --git a/t/024-sequence.t b/t/024-sequence.t
new file mode 100644
index 0000000..777bc02
--- /dev/null
+++ b/t/024-sequence.t
@@ -0,0 +1,136 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use Test::More tests => 10;
+use Path::Dispatcher;
+
+my @calls;
+
+my $dispatcher = Path::Dispatcher->new;
+$dispatcher->add_rule(
+ Path::Dispatcher::Rule::Sequence->new(
+ rules => [
+ Path::Dispatcher::Rule::Eq->new(
+ string => 'foo',
+ prefix => 1,
+ ),
+ Path::Dispatcher::Rule::Eq->new(
+ string => 'bar',
+ prefix => 1,
+ ),
+ ],
+ block => sub { push @calls, [$1, $2, $3] },
+ ),
+);
+
+$dispatcher->run('foo bar');
+is_deeply([splice @calls], [ ['foo', 'bar', undef] ], "correctly populated number vars from [str, str] token rule");
+
+$dispatcher->add_rule(
+ Path::Dispatcher::Rule::Sequence->new(
+ rules => [
+ Path::Dispatcher::Rule::Eq->new(
+ string => 'foo',
+ prefix => 1,
+ ),
+ Path::Dispatcher::Rule::Regex->new(
+ regex => qr/bar/,
+ ),
+ ],
+ block => sub { push @calls, [$1, $2, $3] },
+ ),
+);
+
+$dispatcher->run('foo bar');
+is_deeply([splice @calls], [ ['foo', 'bar', undef] ], "ran the first [str, str] rule");
+
+$dispatcher->run('foo barbaz');
+is_deeply([splice @calls], [ ['foo', 'barbaz', undef] ], "ran the second [str, regex] rule");
+
+$dispatcher->run('foo bar baz');
+is_deeply([splice @calls], [], "no matches");
+
+$dispatcher->add_rule(
+ Path::Dispatcher::Rule::Sequence->new(
+ rules => [
+ Path::Dispatcher::Rule::Alternation->new(
+ rules => [
+ Path::Dispatcher::Rule::Eq->new(
+ string => 'Bat',
+ prefix => 1,
+ ),
+ Path::Dispatcher::Rule::Eq->new(
+ string => 'Super',
+ prefix => 1,
+ ),
+ ],
+ ),
+ Path::Dispatcher::Rule::Eq->new(
+ string => 'Man',
+ ),
+ ],
+ block => sub { push @calls, [$1, $2, $3] },
+ ),
+);
+
+$dispatcher->run('Super Man');
+is_deeply([splice @calls], [ ['Super', 'Man', undef] ], "ran the [ [Str,Str], Str ] rule");
+
+$dispatcher->run('Bat Man');
+is_deeply([splice @calls], [ ['Bat', 'Man', undef] ], "ran the [ [Str,Str], Str ] rule");
+
+$dispatcher->run('Aqua Man');
+is_deeply([splice @calls], [ ], "no match");
+
+$dispatcher->add_rule(
+ Path::Dispatcher::Rule::Sequence->new(
+ rules => [
+ Path::Dispatcher::Rule::Alternation->new(
+ rules => [
+ Path::Dispatcher::Rule::Alternation->new(
+ rules => [
+ Path::Dispatcher::Rule::Alternation->new(
+ rules => [
+ Path::Dispatcher::Rule::Regex->new(
+ regex => qr/Deep/,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ Path::Dispatcher::Rule::Eq->new(
+ string => "Man",
+ ),
+ ],
+ block => sub { push @calls, [$1, $2, $3] },
+ ),
+);
+
+$dispatcher->run('Deep Man');
+is_deeply([splice @calls], [ ['Deep', 'Man', undef] ], "alternations can be arbitrarily deep");
+
+$dispatcher->run('Not Appearing in this Dispatcher Man');
+is_deeply([splice @calls], [ ], "no match");
+
+my $rule = Path::Dispatcher::Rule::Sequence->new(
+ rules => [
+ Path::Dispatcher::Rule::Eq->new(
+ string => 'path',
+ case_sensitive => 0,
+ prefix => 1,
+ ),
+ Path::Dispatcher::Rule::Eq->new(
+ string => 'dispatcher',
+ case_sensitive => 0,
+ prefix => 1,
+ ),
+ ],
+ prefix => 1,
+ delimiter => '::',
+);
+
+my $match = $rule->match(Path::Dispatcher::Path->new('Path::Dispatcher::Rule::Tokens'));
+is($match->leftover, 'Rule::Tokens');
+
-----------------------------------------------------------------------
More information about the Bps-public-commit
mailing list