[Catalyst-commits] r11510 - in Catalyst-View-TD: . trunk trunk/lib
trunk/lib/Catalyst trunk/lib/Catalyst/Helper
trunk/lib/Catalyst/Helper/View trunk/lib/Catalyst/View
trunk/t trunk/t/lib trunk/t/lib/TestApp
trunk/t/lib/TestApp/TD trunk/t/lib/TestApp/Template
trunk/t/lib/TestApp/View
theory at dev.catalyst.perl.org
theory at dev.catalyst.perl.org
Fri Oct 9 06:19:26 GMT 2009
Author: theory
Date: 2009-10-09 06:19:26 +0000 (Fri, 09 Oct 2009)
New Revision: 11510
Added:
Catalyst-View-TD/trunk/
Catalyst-View-TD/trunk/Changes
Catalyst-View-TD/trunk/MANIFEST.SKIP
Catalyst-View-TD/trunk/Makefile.PL
Catalyst-View-TD/trunk/lib/
Catalyst-View-TD/trunk/lib/Catalyst/
Catalyst-View-TD/trunk/lib/Catalyst/Helper/
Catalyst-View-TD/trunk/lib/Catalyst/Helper/View/
Catalyst-View-TD/trunk/lib/Catalyst/Helper/View/TD.pm
Catalyst-View-TD/trunk/lib/Catalyst/View/
Catalyst-View-TD/trunk/lib/Catalyst/View/TD.pm
Catalyst-View-TD/trunk/t/
Catalyst-View-TD/trunk/t/01use.t
Catalyst-View-TD/trunk/t/02pod.t
Catalyst-View-TD/trunk/t/03podcoverage.t
Catalyst-View-TD/trunk/t/04pkgconfig.t
Catalyst-View-TD/trunk/t/05appconfig.t
Catalyst-View-TD/trunk/t/06includepath.t
Catalyst-View-TD/trunk/t/07render.t
Catalyst-View-TD/trunk/t/08cycle.t
Catalyst-View-TD/trunk/t/11norequest.t
Catalyst-View-TD/trunk/t/lib/
Catalyst-View-TD/trunk/t/lib/TestApp.pm
Catalyst-View-TD/trunk/t/lib/TestApp/
Catalyst-View-TD/trunk/t/lib/TestApp/TD/
Catalyst-View-TD/trunk/t/lib/TestApp/TD/Appconfig.pm
Catalyst-View-TD/trunk/t/lib/TestApp/Template/
Catalyst-View-TD/trunk/t/lib/TestApp/Template/Pkgconfig.pm
Catalyst-View-TD/trunk/t/lib/TestApp/View/
Catalyst-View-TD/trunk/t/lib/TestApp/View/Appconfig.pm
Catalyst-View-TD/trunk/t/lib/TestApp/View/Pkgconfig.pm
Log:
First stab at new Template::Declare view. I copied most of the code from
View::TT. There are way too few tests! Over the next week, I'll get things
working really well, including support for modifying template roots at
runtime. I'll also add a lot more tests. All the relevant tests copied from
View::TT pass (all 29 of them).
Added: Catalyst-View-TD/trunk/Changes
===================================================================
--- Catalyst-View-TD/trunk/Changes (rev 0)
+++ Catalyst-View-TD/trunk/Changes 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,4 @@
+Revision history for Perl extension Catalyst::View::TD.
+
+0.01 XXXX-XX-XX
+ - first release
Added: Catalyst-View-TD/trunk/MANIFEST.SKIP
===================================================================
--- Catalyst-View-TD/trunk/MANIFEST.SKIP (rev 0)
+++ Catalyst-View-TD/trunk/MANIFEST.SKIP 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,34 @@
+# Avoid version control files.
+\bRCS\b
+\bCVS\b
+,v$
+\B\.svn\b
+\B\.git\b
+\B\.gitignore\b
+
+# Avoid Makemaker generated and utility files.
+\bMakefile$
+\bblib
+\bMakeMaker-\d
+\bpm_to_blib$
+\bblibdirs$
+^MANIFEST\.SKIP$
+
+# Avoid Module::Build generated and utility files.
+\bBuild$
+\b_build
+
+# Avoid temp and backup files.
+~$
+\.tmp$
+\.old$
+\.bak$
+\#$
+\b\.#
+\.DS_Store$
+
+# No tarballs!
+\.gz$
+
+# Avoid spelling test.
+pod-spelling.t$
Added: Catalyst-View-TD/trunk/Makefile.PL
===================================================================
--- Catalyst-View-TD/trunk/Makefile.PL (rev 0)
+++ Catalyst-View-TD/trunk/Makefile.PL 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,25 @@
+use inc::Module::Install 0.87;
+
+if ( -e 'MANIFEST.SKIP' ) {
+ system( 'pod2text lib/Catalyst/View/TD.pm > README' );
+}
+
+perl_version '5.008001';
+
+name 'Catalyst-View-TD';
+all_from 'lib/Catalyst/View/TD.pm';
+
+requires 'Catalyst' => '5.7';
+requires 'Template::Declare' => '0.41';
+requires 'File::Find' => 0;
+# requires 'Class::Accessor' => 0;
+# requires 'Template::Timer' => 0;
+# requires 'Path::Class' => 0;
+# requires 'MRO::Compat' => 0;
+
+test_requires 'Test::More';
+
+auto_install;
+resources repository => 'http://dev.catalyst.perl.org/repos/Catalyst/trunk/Catalyst-View-TD/';
+
+WriteAll;
Added: Catalyst-View-TD/trunk/lib/Catalyst/Helper/View/TD.pm
===================================================================
--- Catalyst-View-TD/trunk/lib/Catalyst/Helper/View/TD.pm (rev 0)
+++ Catalyst-View-TD/trunk/lib/Catalyst/Helper/View/TD.pm 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,97 @@
+package Catalyst::Helper::View::TD;
+
+use strict;
+
+=head1 Name
+
+Catalyst::Helper::View::TD - Helper for TD Views
+
+=head1 Synopsis
+
+ myapp_create.pl view HTML TD
+
+=head1 Description
+
+Helper for TD Views.
+
+=head2 Methods
+
+=head3 mk_compclass
+
+=cut
+
+sub mk_compclass {
+ my ( $self, $helper ) = @_;
+ my $file = $helper->{file};
+ $helper->render_file( 'compclass', $file );
+}
+
+=head1 SEE ALSO
+
+L<Catalyst::View::TD>, L<Catalyst::Manual>, L<Catalyst::Test>,
+L<Catalyst::Request>, L<Catalyst::Response>, L<Catalyst::Helper>
+
+=head1 Author
+
+David E. Wheeler <david at justatheory.com>
+
+=head1 License
+
+This library is free software. You can redistribute it and/or modify it under
+the same terms as perl itself.
+
+=cut
+
+1;
+
+__DATA__
+
+__compclass__
+[% PERL %]
+(my $tclass = $stash->get('class')) =~ s/::View::/::TD::/;
+$stash->set(tclass => $tclass );
+[% END %]
+package [% class %];
+
+use strict;
+use warnings;
+
+use parent 'Catalyst::View::TD';
+
+# If roots is not specified, Catalyst::View::TD will automatically load all
+# modules below the [% class %]::* namespace. It's simplest to create
+# your template modules there. See the Template::Declare documentation for a
+# complete description of its init() parameters, all of which are supported
+# here.
+
+__PACKAGE__->config(
+ # dispatch_to => [qw([% tclass %])],
+ # postprocessor => sub { ... },
+ # around_template => sub { ... },
+);
+
+=head1 NAME
+
+[% class %] - TD View for [% app %]
+
+=head1 DESCRIPTION
+
+TD View for [% app %]. Templates are written in the
+[% tclass %] namespace.
+
+=head1 SEE ALSO
+
+L<[% app %]>
+
+=head1 AUTHOR
+
+[% author %]
+
+=head1 LICENSE
+
+This library is free software. You can redistribute it and/or modify it under
+the same terms as Perl itself.
+
+=cut
+
+1;
Added: Catalyst-View-TD/trunk/lib/Catalyst/View/TD.pm
===================================================================
--- Catalyst-View-TD/trunk/lib/Catalyst/View/TD.pm (rev 0)
+++ Catalyst-View-TD/trunk/lib/Catalyst/View/TD.pm 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,448 @@
+package Catalyst::View::TD;
+
+use strict;
+use warnings;
+
+use base qw/Catalyst::View/;
+
+our $VERSION = '0.01';
+
+__PACKAGE__->mk_accessors('init');
+
+=head1 Name
+
+Catalyst::View::TD - Catalyst Template::Declare View Class
+
+=head1 Synopsis
+
+Use the helper to create your view:
+
+ myapp_create.pl view HTML TD
+
+Configure in F<lib/MyApp.pm> (could be set from configfile instead):
+
+ MyApp->config(
+ name => 'MyApp',
+ root => MyApp->path_to('root'),
+ 'View::TD' => {
+ dispatch_to => ['MyApp::View::TD::Root'], # Default
+ preprocessor => sub { ... },
+ around_template => sub { ... },
+ },
+ );
+
+Create a template in F<lib/MyApp/TD/HTML.pm>:
+
+ package TestApp::TD::HTML;
+
+ use strict;
+ use warnings;
+ use Template::Declare::Tags;
+
+ template hello => sub {
+ my ($self, $vars) = @_;
+ html {
+ head { title { "Hello, $vars->{user}" } };
+ body { h1 { "Hello, $vars->{user}" } };
+ };
+ };
+
+Render the view from MyApp::Controller::SomeController:
+
+ sub message : Global {
+ my ( $self, $c ) = @_;
+ $c->stash->{template} = 'hello';
+ $c->stash->{user} = 'Slim Shady';
+ $c->forward( $c->view('TD') );
+ }
+
+=cut
+
+sub new {
+ my ( $class, $c, $args ) = @_;
+ my $config = {
+ %{ $class->config },
+ %{ $args },
+ };
+
+ if (my $roots = $config->{dispatch_to}) {
+ for my $root (@{ $roots }) {
+ eval "require $root" or die $@ || "$root did not return a true value";
+ }
+ } else {
+ $config->{dispatch_to} = _load_templates( $class );
+ }
+
+ $class->next::method( $c, { init => $config } );
+}
+
+sub _load_templates {
+ my $class = shift;
+
+ (my $root = $class) =~ s/::View::/::TD::/;
+
+ my $classes = [
+ Module::Pluggable::Object->new(
+ require => 0,
+ search_path => $root,
+ )->plugins
+ ];
+
+ for my $mod ($root, $@{ $classes }) {
+ next unless $mod;
+ # Load it.
+ eval "require $mod" or die $@ || "$mod did not return a true value";
+
+ # Make the module a subclass of TD (required by TD)
+ unless ( $mod->isa('Template::Declare::Catalyst') ) {
+ no strict 'refs';
+ push @{ "$mod\::ISA" }, 'Template::Declare::Catalyst'
+ }
+
+ next if $mod eq $root;
+
+ # Mix it in.
+ (my $sub = $mod) =~ s/\Q$root\E:://;
+ my $path = join '/', map {
+ s{(?!^)([[:upper:]])+}{_$1}g; lc
+ } split /::/ => $sub;
+ $mod->mix($root, $path);
+ }
+ return [$root];
+}
+
+sub process {
+ my ( $self, $c ) = @_;
+
+ my $template = $c->stash->{template} || $c->action;
+
+ unless (defined $template) {
+ $c->log->debug('No template specified for rendering') if $c->debug;
+ return 0;
+ }
+
+ my $output = eval { $self->render($c, $template) };
+
+ if (my $error = $@) {
+ my $error = qq/Couldn't render template: "$error"/;
+ $c->log->error($error);
+ $c->error($error);
+ return 0;
+ }
+
+ unless ( $c->response->content_type ) {
+ $c->response->content_type('text/html; charset=utf-8');
+ }
+
+ $c->response->body($output);
+
+ return 1;
+}
+
+sub render {
+ my ($self, $c, $template, $args) = @_;
+
+ $c->log->debug(qq/Rendering template "$template"/) if $c && $c->debug;
+
+ my $vars = {
+ ref $args eq 'HASH' ? %{ $args || {} } : $c ? %{ $c->stash } : {},
+ };
+ Template::Declare->init( %{ $self->init } );
+ Template::Declare::Catalyst->context($c);
+ my $output = eval { Template::Declare->show($template, $vars) };
+ if (my $err = $@) {
+ return $err if ref $err;
+ die $err;
+ }
+ return $output;
+}
+
+package Template::Declare::Catalyst;
+
+use strict;
+use warnings;
+use lib '/Users/david/dev/perl/Template-Declare/mixmaster/lib';
+use base qw/Template::Declare/;
+
+__PACKAGE__->mk_classdata('context');
+
+*c = \&context;
+
+# XXX Not sure if this is the best way to do things.
+TAGS: {
+ use Template::Declare::Tags ();
+ no warnings 'redefine';
+ *Template::Declare::Tags::carp = sub { die \join '', @_ };
+}
+
+1;
+__END__
+
+=head1 Description
+
+This is the Catalyst view class for L<Template::Declare|Template::Declare>.
+Your application should defined a view class which is a subclass of this
+module. The easiest way to achieve this is using the F<myapp_create.pl> script
+(where F<myapp> should be replaced with whatever your application is called).
+This script is created as part of the Catalyst setup.
+
+ $ script/myapp_create.pl view HTML TD
+
+This creates a C<MyApp::View::HTML> module in the F<lib> directory (again,
+replacing C<MyApp> with the name of your application) which looks something
+like this:
+
+ package MyApp::View::HTML;
+
+ use strict;
+ use warnings;
+
+ use base 'Catalyst::View::TD';
+
+ __PACKAGE__->config->{DEBUG} = 'all';
+
+Now you can modify your action handlers in the main application and/or
+controllers to forward to your view class. You might choose to do this in the
+C<end()> method, for example, to automatically forward all actions to the TD
+view class.
+
+ # In MyApp or MyApp::Controller::SomeController
+
+ sub end : Private {
+ my( $self, $c ) = @_;
+ $c->forward( $c->view('HTML') );
+ }
+
+=head2 Configuration
+
+There are a three different ways to configure your view class. The first way
+is to call the C<config()> method in the view subclass. This happens when the
+module is first loaded.
+
+ package MyApp::View::TD;
+
+ use strict;
+ use base 'Catalyst::View::TD';
+
+ MyApp::View::TD->config({
+ dispatch_to => [ 'MyApp::TD::HTML' ],
+ postprocessor => sub { ... },
+ around_template => sub { ... },
+ });
+
+The second way is to define a C<new()> method in your view subclass. This
+performs the configuration when the view object is created, shortly after
+being loaded. Remember to delegate to the base class C<new()> method (via
+C<< $self->next::method() >> in the example below) after performing any
+configuration.
+
+ sub new {
+ my $self = shift;
+ $self->config({
+ dispatch_to => [ 'MyApp::TD::HTML' ],
+ postprocessor => sub { ... },
+ around_template => sub { ... },
+ });
+ return $self->next::method(@_);
+ }
+
+The final, and perhaps most direct way, is to define a class item in your main
+application configuration, again by calling the ubiquitous C<config()> method.
+The items in the class hash are added to those already defined by the above
+two methods. This happens in the base class C<new()> method (which is one
+reason why you must remember to call it via C<MRO::Compat> if you redefine the
+C<new()> method in a subclass).
+
+ package MyApp;
+
+ use strict;
+ use Catalyst;
+
+ MyApp->config({
+ name => 'MyApp',
+ 'View::HTML' => {
+ dispatch_to => [ 'MyApp::TD::HTML' ],
+ postprocessor => sub { ... },
+ around_template => sub { ... },
+ },
+ });
+
+Note that any configuration items defined by one of the earlier methods will
+be overwritten by items of the same name provided by the latter methods.
+
+=begin comment
+
+Implement this?
+
+=head2 Dynamic C<dispatch_to>
+
+Sometimes it is desirable to modify C<dispatch_to> for your templates at
+runtime.
+
+Additional paths can be added to the start of C<dispatch_to> via the stash as
+follows:
+
+ $c->stash->{additional_template_classes} = [
+ 'MyApp::Other::Templates'
+ ];
+
+If you need to add template classes paths to the end of C<dispatch_to>, there
+is also a C<include_path()> accessor:
+
+ push( @{ $c->view('HTML')->dispatch_to }, 'My::Templates' );
+
+Note that if you use C<dispatch_to()> to add extra paths to C<dispatch_to>,
+you B<must> check for duplicate paths. Without such checking, the above code
+will add "My::Templates" to C<dispatch_to> for every request, leading to a
+memory leak.
+
+A safer approach is to use C<dispatch_to()> to overwrite the array of template
+classes rather than adding to it. This eliminates both the need to perform
+duplicate checking and the chance of a memory leak:
+
+ $c->view('HTML')->dispatch_to( ['My::Templates', 'Your::Templates'] );
+
+If you are calling C<render> directly then you can specify dynamic paths by
+having a C<additional_template_classes> key with a value of additonal
+directories to search. See L</"Capturing Template Output"> for an example of
+this.
+
+=end comment
+
+=head2 Rendering Views
+
+The Catlyst C<view()> method renders the template specified in the C<template>
+item in the stash.
+
+ sub message : Global {
+ my ( $self, $c ) = @_;
+ $c->stash->{template} = 'message';
+ $c->forward( $c->view('HTML') );
+ }
+
+If a stash item isn't defined, then it instead uses the stringification of the
+action dispatched to (as defined by C<< $c->action >>). In the above example,
+this would be C<message>.
+
+The items defined in the stash are passed to the the Template::Declare template
+as a hash reference. Thus, for this controller action:
+
+ sub default : Private {
+ my ( $self, $c ) = @_;
+ $c->stash->{template} = 'message';
+ $c->stash->{message} = 'Hello World!';
+ $c->forward( $c->view('TD') );
+ }
+
+Your template can use access the C<message> key like so:
+
+ template message => sub {
+ my ($self, $args) = @_;
+ h1 { $args->{message} };
+ };
+
+Template classes are automatically subclasses of Template::Declare::Catalyst,
+which is itself a subclass of L<Template::Declare|Template::Declare>.
+Template::Declare::Catalyst provides a few extra accessors for use in your
+templates:
+
+=over
+
+=item C<context>
+
+A reference to the context object, C<$c>
+
+=item C<c>
+
+An alias for C<context()>
+
+=begin comment
+
+Add these?
+
+=item C<base>
+
+The URL base, from C<< $c->req->base >>.
+
+=item C<name>
+
+The application name, from C<< $c->config->{ name } >>.
+
+=end comment
+
+=back
+
+These can be accessed from the template like so:
+
+ template message => sub {
+ my ($self, $args) = @_;
+ p { "The message is $args->{message}" };
+ p { "The base is " . $self->base };
+ p { "The name is " . $self->name };
+ };
+
+The output generated by the template is stored in C<< $c->response->body >>.
+
+=head2 Capturing Template Output
+
+If you wish to use the output of a template for some purpose other than
+displaying in the response, e.g. for sending an email, use
+L<Catalyst::Plugin::Email|Catalyst::Plugin::Email> and the L<render> method:
+
+ sub send_email : Local {
+ my ($self, $c) = @_;
+
+ $c->email(
+ header => [
+ To => 'me at localhost',
+ Subject => 'A TD Email',
+ ],
+ body => $c->view('TD')->render($c, 'email', {
+ additional_template_classes => [ 'My::EmailTemplates' ],
+ email_tmpl_param1 => 'foo'
+ }),
+ );
+ # Redirect or display a message
+ }
+
+=head2 Methods
+
+=head2 C<new>
+
+The constructor for the TD view. Sets up the template provider and reads the
+application config.
+
+=head2 C<process>
+
+Renders the template specified in C<< $c->stash->{template} >> or
+C<< $c->action >> (the private name of the matched action). Calls L<render()>
+to perform actual rendering. Output is stored in C<< $c->response->body >>.
+
+=head2 C<render>
+
+Renders the given template and returns output, or a L<Template::Exception>
+object upon error.
+
+The template variables are set to C<$args> if $args is a hashref, or
+C<< $c->stash >> otherwise.
+
+=head2 C<config>
+
+This method allows your view subclass to pass additional settings to the TD
+configuration hash, or to set the options as below:
+
+=head1 SEE ALSO
+
+L<Catalyst>, L<Catalyst::View::TT>, L<Catalyst::Helper::View::TD>,
+L<Catalyst::Helper::View::TDSite>, L<Template::Manual>
+
+=head1 Author
+
+David E. Wheeler <david at justatheory.com>
+
+=head1 Copyright
+
+This program is free software. You can redistribute it and/or modify it under
+the same terms as Perl itself.
+
+=cut
Added: Catalyst-View-TD/trunk/t/01use.t
===================================================================
--- Catalyst-View-TD/trunk/t/01use.t (rev 0)
+++ Catalyst-View-TD/trunk/t/01use.t 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,5 @@
+use strict;
+use Test::More tests => 2;
+
+BEGIN { use_ok('Catalyst::View::TD') }
+BEGIN { use_ok('Catalyst::Helper::View::TD') }
Added: Catalyst-View-TD/trunk/t/02pod.t
===================================================================
--- Catalyst-View-TD/trunk/t/02pod.t (rev 0)
+++ Catalyst-View-TD/trunk/t/02pod.t 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,6 @@
+use Test::More;
+
+eval "use Test::Pod 1.14";
+plan skip_all => 'Test::Pod 1.14 required' if $@;
+
+all_pod_files_ok();
Added: Catalyst-View-TD/trunk/t/03podcoverage.t
===================================================================
--- Catalyst-View-TD/trunk/t/03podcoverage.t (rev 0)
+++ Catalyst-View-TD/trunk/t/03podcoverage.t 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,6 @@
+use Test::More;
+
+eval "use Test::Pod::Coverage 1.04";
+plan skip_all => 'Test::Pod::Coverage 1.04 required' if $@;
+
+all_pod_coverage_ok();
Added: Catalyst-View-TD/trunk/t/04pkgconfig.t
===================================================================
--- Catalyst-View-TD/trunk/t/04pkgconfig.t (rev 0)
+++ Catalyst-View-TD/trunk/t/04pkgconfig.t 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,21 @@
+use strict;
+use warnings;
+use Test::More tests => 7;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use_ok('Catalyst::Test', 'TestApp');
+
+my $view = 'Pkgconfig';
+
+my $response;
+ok(($response = request("/test?view=$view"))->is_success, 'request ok');
+is($response->content, TestApp->config->{default_message}, 'default message ok');
+
+my $message = scalar localtime;
+ok(($response = request("/test?view=$view&message=$message"))->is_success, 'request with message ok');
+is($response->content, $message, 'message ok');
+
+ok(($response = request("/test?view=$view&message=override"))->is_success, 'request with override message ok');
+is($response->content, 'Shoved in by around_template', 'override message ok');
Added: Catalyst-View-TD/trunk/t/05appconfig.t
===================================================================
--- Catalyst-View-TD/trunk/t/05appconfig.t (rev 0)
+++ Catalyst-View-TD/trunk/t/05appconfig.t 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,18 @@
+use strict;
+use warnings;
+use Test::More tests => 5;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use_ok('Catalyst::Test', 'TestApp');
+
+my $view = 'Appconfig';
+
+my $response;
+ok(($response = request("/test?view=$view"))->is_success, 'request ok');
+is($response->content, TestApp->config->{default_message}, 'message ok');
+
+my $message = scalar localtime;
+ok(($response = request("/test?view=$view&message=$message"))->is_success, 'request with message ok');
+is($response->content, $message, 'message ok');
Added: Catalyst-View-TD/trunk/t/06includepath.t
===================================================================
--- Catalyst-View-TD/trunk/t/06includepath.t (rev 0)
+++ Catalyst-View-TD/trunk/t/06includepath.t 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,30 @@
+use strict;
+use warnings;
+use Test::More skip_all => 'Not sure we will need this feature with TD';
+
+use Test::More tests => 10;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use_ok('Catalyst::Test', 'TestApp');
+my $response;
+
+my $inital_dispatch_to = [ @{ TestApp->view('Appconfig')->dispatch_to } ];
+
+ok(($response = request("/test_includepath?view=Appconfig&template=testpath&additionalpath=test_dispatch_to"))->is_success, 'additional_template_path request');
+is($response->content, TestApp->config->{default_message}, 'additional_template_path message');
+
+is_deeply($inital_dispatch_to,
+ TestApp->view('Appconfig')->dispatch_to,
+ 'Include path is unchanged');
+
+ok(($response = request("/test_includepath?view=Includepath&template=testpath"))->is_success, 'scalar include path from config request');
+is($response->content, TestApp->config->{default_message}, 'scalar include path with delimiter from config message');
+
+ok(($response = request("/test_includepath?view=Includepath2&template=testpath"))->is_success, 'object ref (that stringifys to the path) include path from config request');
+is($response->content, TestApp->config->{default_message}, 'object ref (that stringifys to the path) include path from config message');
+
+ok(($response = request("/test_includepath?view=Includepath3&template=testpath&addpath=test_dispatch_to"))->is_success, 'array ref include path from config not replaced by another array request');
+is($response->content, TestApp->config->{default_message}, 'array ref include path from config not replaced by another array message');
+
Added: Catalyst-View-TD/trunk/t/07render.t
===================================================================
--- Catalyst-View-TD/trunk/t/07render.t (rev 0)
+++ Catalyst-View-TD/trunk/t/07render.t 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,22 @@
+use strict;
+use warnings;
+use Test::More tests => 5;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use_ok('Catalyst::Test', 'TestApp');
+
+my $response;
+ok(($response = request("/test_render?template=specified_template¶m=parameterized"))->is_success, 'request ok');
+is($response->content, "I should be a parameterized test in @{[TestApp->config->{name}]}", 'message ok');
+
+# TD does not support template text passed as a code ref.
+# my $message = 'Dynamic message';
+# ok(($response = request("/test_msg?msg=$message"))->is_success, 'request ok');
+# is($response->content, "$message", 'message ok');
+
+$response = request("/test_render?template=non_existant_template");
+
+is (403, $response->code, 'request returned error');
+is($response->content, q{The template 'non_existant_template' could not be found (it might be private)}, 'Error from non-existant-template');
Added: Catalyst-View-TD/trunk/t/08cycle.t
===================================================================
--- Catalyst-View-TD/trunk/t/08cycle.t (rev 0)
+++ Catalyst-View-TD/trunk/t/08cycle.t 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,31 @@
+use strict;
+use warnings;
+use Test::More;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+plan tests => 3;
+
+use_ok('Catalyst::View::TD');
+use_ok('Catalyst::Test', 'TestApp');
+
+my $copy;
+{
+ my $view = Catalyst::View::TD->new(
+ "TestApp",
+ { dispatch_to => ['TestApp::TD::Appconfig'] },
+ );
+
+ # Can't Test::Memory::Cycle test since it doesn't detect
+ # [ sub { $copy->paths } ]
+ # as a cycle, but the above does prevent it getting garbage collected.
+ #
+ # memory_cycle_ok($view, 'No cycles in View');
+
+ $copy = $view;
+ Scalar::Util::weaken($copy);
+}
+
+ok(!defined $copy, 'Copy went out of scope');
+
Added: Catalyst-View-TD/trunk/t/11norequest.t
===================================================================
--- Catalyst-View-TD/trunk/t/11norequest.t (rev 0)
+++ Catalyst-View-TD/trunk/t/11norequest.t 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,12 @@
+use strict;
+use warnings;
+use Test::More tests => 3;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+BEGIN { use_ok 'TestApp' or die }
+
+ok my $td = TestApp->view('Appconfig'), 'Get Appconfig view object';
+is $td->render(undef, 'test', { message => 'hello' }), 'hello',
+ 'render() should return the template output';
Added: Catalyst-View-TD/trunk/t/lib/TestApp/TD/Appconfig.pm
===================================================================
--- Catalyst-View-TD/trunk/t/lib/TestApp/TD/Appconfig.pm (rev 0)
+++ Catalyst-View-TD/trunk/t/lib/TestApp/TD/Appconfig.pm 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,17 @@
+package TestApp::TD::Appconfig;
+
+use strict;
+use warnings;
+use Template::Declare::Tags;
+
+template test => sub {
+ my ($self, $args) = @_;
+ outs $args->{message};
+};
+
+template specified_template => sub {
+ my ($self, $args) = @_;
+ outs "I should be a $args->{param} test in ", $self->c->config->{name};
+};
+
+1;
Added: Catalyst-View-TD/trunk/t/lib/TestApp/Template/Pkgconfig.pm
===================================================================
--- Catalyst-View-TD/trunk/t/lib/TestApp/Template/Pkgconfig.pm (rev 0)
+++ Catalyst-View-TD/trunk/t/lib/TestApp/Template/Pkgconfig.pm 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,12 @@
+package TestApp::Template::Pkgconfig;
+
+use strict;
+use Template::Declare::Tags;
+use base 'Template::Declare::Catalyst';
+
+template test => sub {
+ my ($self, $msg, $args) = @_;
+ outs $args->{message} eq 'override' ? $msg : $args->{message};
+};
+
+1;
Added: Catalyst-View-TD/trunk/t/lib/TestApp/View/Appconfig.pm
===================================================================
--- Catalyst-View-TD/trunk/t/lib/TestApp/View/Appconfig.pm (rev 0)
+++ Catalyst-View-TD/trunk/t/lib/TestApp/View/Appconfig.pm 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,6 @@
+package TestApp::View::Appconfig;
+
+use strict;
+use base 'Catalyst::View::TD';
+
+1;
Property changes on: Catalyst-View-TD/trunk/t/lib/TestApp/View/Appconfig.pm
___________________________________________________________________
Name: svn:executable
+ *
Added: Catalyst-View-TD/trunk/t/lib/TestApp/View/Pkgconfig.pm
===================================================================
--- Catalyst-View-TD/trunk/t/lib/TestApp/View/Pkgconfig.pm (rev 0)
+++ Catalyst-View-TD/trunk/t/lib/TestApp/View/Pkgconfig.pm 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,21 @@
+package TestApp::View::Pkgconfig;
+
+use strict;
+use base 'Catalyst::View::TD';
+
+__PACKAGE__->config(
+ dispatch_to => [qw(TestApp::Template::Pkgconfig)],
+ postprocessor => sub {
+ local $_ = shift;
+ s/^\s+//msg;
+ s/\s+$//msg;
+ $_;
+ },
+ around_template => sub {
+ my ($orig, $path, $args, $code) = @_;
+ unshift @{ $args }, 'Shoved in by around_template';
+ $orig->();
+ },
+);
+
+1;
Property changes on: Catalyst-View-TD/trunk/t/lib/TestApp/View/Pkgconfig.pm
___________________________________________________________________
Name: svn:executable
+ *
Added: Catalyst-View-TD/trunk/t/lib/TestApp.pm
===================================================================
--- Catalyst-View-TD/trunk/t/lib/TestApp.pm (rev 0)
+++ Catalyst-View-TD/trunk/t/lib/TestApp.pm 2009-10-09 06:19:26 UTC (rev 11510)
@@ -0,0 +1,90 @@
+package TestApp;
+
+use strict;
+use warnings;
+
+use Catalyst; # qw/-Debug/;
+use Path::Class;
+
+our $VERSION = '0.01';
+
+__PACKAGE__->config(
+ name => 'TestApp',
+ default_message => 'hi',
+ default_view => 'Appconfig',
+ 'View::TD::Appconfig' => {
+ postprocessor => sub { $_[0] =~ s/\s+$//; $_[0] },
+ },
+);
+
+__PACKAGE__->setup;
+
+1;
+
+# package TestApp::Controller::Root;
+# use base 'Catalyst::Controller';
+# BEGIN { $INC{'TestApp/Controller/Root.pm'} = __FILE__ }
+
+sub default : Private {
+ my ($self, $c) = @_;
+
+ $c->response->redirect($c->uri_for('test'));
+}
+
+sub test : Local {
+ my ($self, $c) = @_;
+ $c->stash->{message} = $c->request->param('message') || $c->config->{default_message};
+}
+
+sub test_includepath : Local {
+ my ($self, $c) = @_;
+ $c->stash->{message} = ($c->request->param('message') || $c->config->{default_message});
+ $c->stash->{template} = $c->request->param('template');
+ if ( $c->request->param('additionalpath') ){
+ my $additionalpath = Path::Class::dir($c->config->{root}, $c->request->param('additionalpath'));
+ $c->stash->{additional_template_paths} = ["$additionalpath"];
+ }
+ if ( $c->request->param('addpath') ){
+ my $additionalpath = Path::Class::dir($c->config->{root}, $c->request->param('addpath'));
+ my $view = 'TestApp::View::' . ($c->request->param('view') || $c->config->{default_view});
+ no strict "refs";
+ push @{$view . '::include_path'}, "$additionalpath";
+ use strict;
+ }
+}
+
+sub test_render : Local {
+ my ($self, $c) = @_;
+
+ my $out = $c->stash->{message} = $c->view('Appconfig')->render(
+ $c, $c->req->param('template'), {param => $c->req->param('param') || ''}
+ );
+ if (ref $out) {
+ $c->response->body($$out);
+ $c->response->status(403);
+ } else {
+ $c->stash->{template} = 'test';
+ }
+
+}
+
+sub test_msg : Local {
+ my ($self, $c) = @_;
+ my $tmpl = $c->req->param('msg');
+ # Test commented-out in 07render.t: TD does not support template text as a
+ # scalar ref, because templates are not text, they're code.
+ $c->stash->{message} = $c->view('AppConfig')->render($c, \$tmpl);
+ $c->stash->{template} = 'test';
+}
+
+sub end : Private {
+ my ($self, $c) = @_;
+
+ return 1 if $c->response->status =~ /^3\d\d$/;
+ return 1 if $c->response->body;
+
+ my $view = 'View::' . ($c->request->param('view') || $c->config->{default_view});
+ $c->forward($view);
+}
+
+1;
Property changes on: Catalyst-View-TD/trunk/t/lib/TestApp.pm
___________________________________________________________________
Name: svn:executable
+ *
More information about the Catalyst-commits
mailing list