package Test::Path::Router; use strict; use warnings; use Test::Builder (); use Test::Deep (); use Data::Dumper (); use Sub::Exporter; our $VERSION = '0.01'; our $AUTHORITY = 'cpan:STEVAN'; my @exports = qw/ routes_ok path_ok path_not_ok path_is mapping_ok mapping_not_ok mapping_is /; Sub::Exporter::setup_exporter({ exports => \@exports, groups => { default => \@exports } }); our $Test = Test::Builder->new; sub routes_ok { my ($router, $routes, $message) = @_; my ($passed, $reason); foreach my $path (keys %$routes) { my $mapping = $routes->{$path}; my $generated_path = $router->uri_for(%{$mapping}); # the path generated from the hash # is the same as the path supplied if ($path ne $generated_path) { $Test->ok(0, $message); $Test->diag("... paths do not match\n" . " got: '" . $path . "'\n" . " expected: '" . $generated_path . "'"); return; } my $generated_mapping = $router->match($path)->mapping; # the path supplied produces the # same match as the hash supplied unless (Test::Deep::eq_deeply($generated_mapping, $mapping)) { $Test->ok(0, $message); $Test->diag("... mappings do not match for '$path'\n" . " got: '" . _dump_mapping_info($generated_mapping) . "'\n" . " expected: '" . _dump_mapping_info($mapping) . "'"); return; } } $Test->ok(1, $message); } sub path_ok { my ($router, $path, $message) = @_; if ($router->match($path)) { $Test->ok(1, $message); } else { $Test->ok(0, $message); } } sub path_not_ok { my ($router, $path, $message) = @_; unless ($router->match($path)) { $Test->ok(1, $message); } else { $Test->ok(0, $message); } } sub path_is { my ($router, $path, $expected, $message) = @_; my $generated_mapping = $router->match($path)->mapping; # the path supplied produces the # same match as the hash supplied unless (Test::Deep::eq_deeply($generated_mapping, $expected)) { $Test->ok(0, $message); $Test->diag("... mappings do not match for '$path'\n" . " got: '" . _dump_mapping_info($generated_mapping) . "'\n" . " expected: '" . _dump_mapping_info($expected) . "'"); } else { $Test->ok(1, $message); } } sub mapping_ok { my ($router, $mapping, $message) = @_; if ($router->uri_for($mapping)) { $Test->ok(1, $message); } else { $Test->ok(0, $message); } } sub mapping_not_ok { my ($router, $mapping, $message) = @_; unless ($router->uri_for($mapping)) { $Test->ok(1, $message); } else { $Test->ok(0, $message); } } sub mapping_is { my ($router, $mapping, $expected, $message) = @_; my $generated_path = $router->uri_for(%{$mapping}); # the path generated from the hash # is the same as the path supplied if ($generated_path ne $expected) { $Test->ok(0, $message); $Test->diag("... paths do not match\n" . " got: '" . $generated_path . "'\n" . " expected: '" . $expected . "'"); } else { $Test->ok(1, $message); } } ## helper function sub _dump_mapping_info { my ($mapping) = @_; local $Data::Dumper::Indent = 0; my $out = Data::Dumper::Dumper($mapping); $out =~ s/\$VAR\d//; return $out; } 1; __END__ =pod =head1 NAME Test::Path::Router - A testing module for testing routes =head1 SYNOPSIS use Test::More plan => 1; use Test::Path::Router; my $router = Path::Router->new; # ... define some routes path_ok($router, 'admin/remove_user/56', '... this is a valid path'); path_is($router, 'admin/edit_user/5', { controller => 'admin', action => 'edit_user', id => 5, }, '... the path and mapping match'); mapping_ok($router, { controller => 'admin', action => 'edit_user', id => 5, }, '... this maps to a valid path'); mapping_is($router, { controller => 'admin', action => 'edit_user', id => 5, }, 'admin/edit_user/5', '... the mapping and path match'); routes_ok($router, { 'admin' => { controller => 'admin', action => 'index', }, 'admin/add_user' => { controller => 'admin', action => 'add_user', }, 'admin/edit_user/5' => { controller => 'admin', action => 'edit_user', id => 5, } }, "... our routes are valid"); =head1 DESCRIPTION This module helps in testing out your path routes, to make sure they are valid. =head1 EXPORTED FUNCTIONS =over 4 =item B =item B =item B =item B =item B =item B =item B This test function will accept a set of C<%test_routes> which will get checked against your C<$router> instance. This will check to be sure that all paths in C<%test_routes> procude the expected mappings, and that all mappings also produce the expected paths. It basically assures you that your paths are roundtrippable, so that you can be confident in them. =back =head1 BUGS All complex software has bugs lurking in it, and this module is no exception. If you find a bug please either email me, or add the bug to cpan-RT. =head1 AUTHOR Stevan Little Estevan.little@iinteractive.comE =head1 COPYRIGHT AND LICENSE Copyright 2008 Infinity Interactive, Inc. L This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut