App-Wallflower
view release on metacpan or search on metacpan
bin/wallflower view on Meta::CPAN
among other things, it doesn't rewrite link URLs to match the pathnames of
the saved pages.
=head1 EXAMPLE
The web site created by C<dancer -a mywebapp> is the perfect example.
The complete list of URLs needed to view the site is:
/
/404.html
/500.html
/css/error.css
/css/style.css
/favicon.ico
/images/perldancer-bg.jpg
/images/perldancer.jpg
/javascripts/jquery.js
Passing this list to B<wallflower> gives the following result:
$ wallflower -a bin/app.pl -d /tmp -F urls.txt
200 / => /tmp/output/index.html [5367]
200 /404.html => /tmp/output/404.html [499]
200 /500.html => /tmp/output/500.html [510]
200 /css/error.css => /tmp/output/css/error.css [1210]
200 /css/style.css => /tmp/output/css/style.css [2850]
404 /favicon.ico
404 /images/perldancer-bg.jpg
404 /images/perldancer.jpg
200 /javascripts/jquery.js => /tmp/output/javascripts/jquery.js [248235]
Note that URLs with a path ending in a C</> are considered directories
and have the default I<index> filename appended, and that wallflower will
behave unpredictably if the site contains pages accessible through URLs
ending both in F<foo> and F<foo/>. This is arguably a bug, but it's
unclear where to fix it, or if it can be fixed at all. See
L<Wallflower::Tutorial/URI SEMANTICS COMPARED TO DIRECTORY SEMANTICS> for
background on this.
'Hello, World!'
],
];
push @tests, [
'status in the URL',
Path::Tiny->tempdir( CLEANUP => 1 ),
sub {
my $env = shift;
my ($status) = $env->{REQUEST_URI} =~ m{/(\d\d\d)$}g;
$status ||= 404;
[ $status,
[ 'Content-Type' => 'text/plain',
'Content-Length' => length $status
],
[$status]
];
},
[ "/200" => 200,
[ 'Content-Type' => 'text/plain', 'Content-Length' => 3 ],
'200', '200'
],
[ "/403" => 403,
[ 'Content-Type' => 'text/plain', 'Content-Length' => 3 ],
'', ''
],
[ "/blah" => 404,
[ 'Content-Type' => 'text/plain', 'Content-Length' => 3 ],
'', ''
],
];
push @tests, [
'app that dies',
Path::Tiny->tempdir( CLEANUP => 1 ),
sub {die},
[ '/' => 500,
t/40-mount.t view on Meta::CPAN
# - a list of test url for the app
# as [ url, status, headers, file, content ]
push @tests, [
'direct content',
Path::Tiny->tempdir,
sub {
my $env = shift;
if ($env->{PATH_INFO} !~ m!^/?$!) {
return [
404,
[ 'Content-Type' => 'text/plain', 'Content-Length' => 3 ],
[ '404' ]
];
}
[ 200,
[ 'Content-Type' => 'text/plain', 'Content-Length' => 13 ],
[ 'Hello,', ' ', 'World!' ]
];
},
[ '/mmm' => 200,
[ 'Content-Type' => 'text/plain', 'Content-Length' => 13 ],
'mmm',
'Hello, World!'
],
[ "/blah" => 404,
[ 'Content-Type' => 'text/plain' ], # Plack::App::URLMap returns this
'', ''
],
[ "/mmm/blah" => 404,
[ 'Content-Type' => 'text/plain', 'Content-Length' => 3 ],
'', ''
],
];
plan tests => sum map 2 * ( @$_ - 3 ), @tests;
for my $t (@tests) {
my ( $desc, $dir, $app, @urls ) = @$t;
t/50-smoke.t view on Meta::CPAN
use Wallflower;
use Plack::Request;
# basic response builder
sub build_response {
my $env = shift;
my $req = Plack::Request->new($env);
my $uri = $req->uri;
return $uri->path eq '/nope'
? [ 404, [ 'Content-Type' => 'text/plain', 'Content-Length' => 0 ], '' ]
: [
200,
[ 'Content-Type' => 'text/plain', 'Content-Length' => length($uri) ],
[$uri]
];
}
# test data is an array ref containing:
# - quick description of the app
# - the app itself
t/50-smoke.t view on Meta::CPAN
'/' => 200,
[ 'Content-Type' => 'text/plain', 'Content-Length' => 24 ],
'index.html',
'http://blah.example.com/'
],
[
'/clunk' => 200,
[ 'Content-Type' => 'text/plain', 'Content-Length' => 29 ],
'clunk', 'http://blah.example.com/clunk'
],
[ '/nope' => 404,
[ 'Content-Type' => 'text/plain', 'Content-Length' => 0 ],
'', ''
],
);
# setup test data
push @tests, [ 'direct content', \&build_response, @urls ];
push @tests, [
'delayed response',
t/test.psgi view on Meta::CPAN
my $res = $response{ $env->{REQUEST_URI} };
return [ 304, [ 'Content-Type' => $res->[0] ], [] ]
if ref $res
&& $env->{HTTP_IF_MODIFIED_SINCE}
&& ( $generated{ $env->{REQUEST_URI} } || 0 ) <
str2time( $env->{HTTP_IF_MODIFIED_SINCE} );
$generated{ $env->{REQUEST_URI} } = time;
return !defined $res
? [ 404, [ 'Content-Type' => 'text/plain', 'Content-Length' => 0 ], [''] ]
: ref $res ? [
200,
[
'Content-Type' => $res->[0],
'Content-Length' => length( $res->[1] )
],
[ $res->[1] ]
]
: [ 301, [ Location => $res ], [''] ];
};
( run in 1.630 second using v1.01-cache-2.11-cpan-39bf76dae61 )