[Templates-svn] r1106 - in trunk: lib/Template lib/Template/Plugin t

svn at template-toolkit.org svn at template-toolkit.org
Mon Jan 21 19:05:46 GMT 2008


Author: abw
Date: 2008-01-21 19:05:30 +0000 (Mon, 21 Jan 2008)
New Revision: 1106

Added:
   trunk/lib/Template/Plugin/Assert.pm
   trunk/t/assert.t
Modified:
   trunk/lib/Template/Plugins.pm
Log:
Added Template::Plugin::Assert and some tests

Added: trunk/lib/Template/Plugin/Assert.pm
===================================================================
--- trunk/lib/Template/Plugin/Assert.pm	                        (rev 0)
+++ trunk/lib/Template/Plugin/Assert.pm	2008-01-21 19:05:30 UTC (rev 1106)
@@ -0,0 +1,155 @@
+#============================================================= -*-Perl-*-
+#
+# Template::Plugin::Assert
+#
+# DESCRIPTION
+#   Template Toolkit plugin module which allows you to assert that
+#   items fetchs from the stash are defined.
+#
+# AUTHOR
+#   Andy Wardley   <abw at wardley.org>
+#
+# COPYRIGHT
+#   Copyright (C) 2008 Andy Wardley.  All Rights Reserved.
+#
+#   This module is free software; you can redistribute it and/or
+#   modify it under the same terms as Perl itself.
+#
+#============================================================================
+
+package Template::Plugin::Assert;
+use base 'Template::Plugin';
+use strict;
+use warnings;
+use Template::Exception;
+
+our $VERSION   = 1.00;
+our $MONAD     = 'Template::Monad::Assert';
+our $EXCEPTION = 'Template::Exception';
+our $AUTOLOAD;
+
+sub load {
+    my $class   = shift;
+    my $context = shift;
+    my $stash   = $context->stash;
+    my $vmethod = sub {
+        $MONAD->new($stash, shift);
+    };
+
+    # define .assert vmethods for hash and list objects
+    $context->define_vmethod( hash => assert => $vmethod );
+    $context->define_vmethod( list => assert => $vmethod );
+
+    return $class;
+}
+
+sub new {
+    my ($class, $context, @args) = @_;
+    # create an assert plugin object which will handle simple variable
+    # lookups.
+    return bless { _CONTEXT => $context }, $class;
+}
+
+sub AUTOLOAD {
+    my ($self, @args) = @_;
+    my $item = $AUTOLOAD;
+    $item =~ s/.*:://;
+    return if $item eq 'DESTROY';
+    
+    # lookup the named values
+    my $stash = $self->{ _CONTEXT }->stash;
+    my $value = $stash->dotop($stash, $item, \@args);
+
+    if (! defined $value) {
+        die $EXCEPTION->new( assert => "undefined value for $item" );
+    }
+    return $value;
+}
+
+
+package Template::Monad::Assert;
+
+our $EXCEPTION = 'Template::Exception';
+our $AUTOLOAD;
+
+sub new {
+    my ($class, $stash, $this) = @_;
+    bless [$stash, $this], $class;
+}
+
+sub AUTOLOAD {
+    my ($self, @args) = @_;
+    my ($stash, $this) = @$self;
+    my $item = $AUTOLOAD;
+    $item =~ s/.*:://;
+    return if $item eq 'DESTROY';
+
+    my $value = $stash->dotop($stash, $item, \@args);
+
+    if (! defined $value) {
+        die $EXCEPTION->new( assert => "undefined value for $item" );
+    }
+    return $value;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Template::Plugin::Assert - trap undefined values
+
+=head1 SYNOPSIS
+
+    [% USE assert %]
+    
+    # throws error if any undefined values are returned
+    [% object.assert.method %]
+    [% hash.assert.key %]
+    [% list.assert.item %]
+
+=head1 DESCRIPTION
+
+This plugin defines the C<assert> virtual method that can be used
+to automatically throw errors when undefined values are used.
+
+For example, consider this dotop:
+
+    [% user.name %]
+
+If C<user.name> is an undefined value then TT will silently ignore the 
+fact and print nothing.  If yoou C<USE> the C<assert> plugin then you
+can add the C<assert> vmethod between the C<user> and C<name> elements,
+like so:
+
+    [% user.assert.name %]
+
+Now, if C<user.name> is an undefined value, an exception will be thrown:
+
+    assert error - undefined value for name
+
+=head1 AUTHOR
+
+Andy Wardley E<lt>abw at wardley.orgE<gt> L<http://wardley.org/>
+
+=head1 COPYRIGHT
+
+Copyright (C) 2008 Andy Wardley.  All Rights Reserved.
+
+This module is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<Template::Plugin>
+
+=cut
+
+# Local Variables:
+# mode: perl
+# perl-indent-level: 4
+# indent-tabs-mode: nil
+# End:
+#
+# vim: expandtab shiftwidth=4:

Modified: trunk/lib/Template/Plugins.pm
===================================================================
--- trunk/lib/Template/Plugins.pm	2008-01-21 18:59:28 UTC (rev 1105)
+++ trunk/lib/Template/Plugins.pm	2008-01-21 19:05:30 UTC (rev 1106)
@@ -32,6 +32,7 @@
 our $DEBUG   = 0 unless defined $DEBUG;
 our $PLUGIN_BASE = 'Template::Plugin';
 our $STD_PLUGINS = {
+    'assert'     => 'Template::Plugin::Assert',
     'autoformat' => 'Template::Plugin::Autoformat',
     'cgi'        => 'Template::Plugin::CGI',
     'datafile'   => 'Template::Plugin::Datafile',

Added: trunk/t/assert.t
===================================================================
--- trunk/t/assert.t	                        (rev 0)
+++ trunk/t/assert.t	2008-01-21 19:05:30 UTC (rev 1106)
@@ -0,0 +1,115 @@
+#============================================================= -*-perl-*-
+#
+# t/assert.t
+#
+# Test the assert plugin which throws error if undefined values are
+# returned.
+#
+# Written by Andy Wardley <abw at wardley.org>
+#
+# Copyright (C) 1996-2008 Andy Wardley.  All Rights Reserved.
+#
+# This is free software; you can redistribute it and/or modify it
+# under the same terms as Perl itself.
+#
+#========================================================================
+
+use strict;
+use warnings;
+use lib qw( ./lib ../lib ../blib/lib ../blib/arch );
+use Template::Test;
+
+#------------------------------------------------------------------------
+# definition of test object class
+#------------------------------------------------------------------------
+
+package Template::Test::Object;
+
+sub new {
+    bless {}, shift;
+}
+
+sub nil {
+    return undef;
+}
+
+
+#-----------------------------------------------------------------------
+# main
+#-----------------------------------------------------------------------
+
+package main;
+
+my $vars = { 
+    object => Template::Test::Object->new,
+    hash   => { foo => 10, bar => undef },
+    list   => [ undef ],
+    subref => sub { return undef },
+    nothing => undef,
+};
+
+test_expect(\*DATA, undef, $vars);
+
+
+
+#------------------------------------------------------------------------
+# test input
+#------------------------------------------------------------------------
+
+__DATA__
+-- test -- 
+([% object.nil %])
+-- expect --
+()
+
+-- test -- 
+[% USE assert;
+   TRY; object.assert.nil; CATCH; error; END; "\n";
+   TRY; object.assert.zip; CATCH; error; END;
+%]
+-- expect --
+assert error - undefined value for nil
+assert error - undefined value for zip
+
+-- test -- 
+[% USE assert;
+   TRY; hash.assert.bar; CATCH; error; END; "\n";
+   TRY; hash.assert.bam; CATCH; error; END;
+%]
+-- expect --
+assert error - undefined value for bar
+assert error - undefined value for bam
+
+-- test -- 
+[% USE assert;
+   TRY; list.assert.0;     CATCH; error; END; "\n";
+   TRY; list.assert.first; CATCH; error; END;
+%]
+-- expect --
+assert error - undefined value for 0
+assert error - undefined value for first
+
+-- test -- 
+[% USE assert;
+   TRY; list.assert.0;     CATCH; error; END; "\n";
+   TRY; list.assert.first; CATCH; error; END;
+%]
+-- expect --
+assert error - undefined value for 0
+assert error - undefined value for first
+
+-- test -- 
+[% USE assert;
+   TRY; assert.nothing; CATCH; error; END;
+%]
+-- expect --
+assert error - undefined value for nothing
+
+-- test -- 
+[% USE assert;
+   TRY; assert.subref; CATCH; error; END;
+%]
+-- expect --
+assert error - undefined value for subref
+
+




More information about the templates-svn mailing list