# -*- Mode: Perl; -*- =head1 NAME 7_template_02_view.t - Test the ability to handle views in CGI::Ex::Template =cut #============================================================= -*-perl-*- # # The tests used here where originally written by Andy Wardley # They have been modified to work with this testing framework # The following is the original Copyright notice included with # the t/view.t document that these tests were taken from. # # Tests the 'View' plugin. # # Written by Andy Wardley # # Copyright (C) 2000 Andy Wardley. All Rights Reserved. # # This is free software; you can redistribute it and/or modify it # under the same terms as Perl itself. # # Id: view.t 131 2001-06-14 13:20:12Z abw # #======================================================================== use vars qw($module $is_tt); BEGIN { $module = 'CGI::Ex::Template'; #real 0m0.885s #user 0m0.432s #sys 0m0.004s # $module = 'Template'; #real 0m2.133s #user 0m1.108s #sys 0m0.024s $is_tt = $module eq 'Template'; }; use strict; use Test::More tests => ! $is_tt ? 53 : 53; use Data::Dumper qw(Dumper); use_ok($module); my $skipped; SKIP: { if (! eval { require Template::View }) { $skipped = 1; skip("Template::View is not installed - skipping VIEW tests", 52); } }; exit if $skipped; sub process_ok { # process the value and say if it was ok my $str = shift; my $test = shift; my $vars = shift || {}; my $conf = local $vars->{'tt_config'} = $vars->{'tt_config'} || []; my $obj = shift || $module->new(@$conf); # new object each time my $out = ''; my $line = (caller)[2]; delete $vars->{'tt_config'}; $obj->process(\$str, $vars, \$out); my $ok = ref($test) ? $out =~ $test : $out eq $test; if ($ok) { ok(1, "Line $line \"$str\" => \"$out\""); return $obj; } else { ok(0, "Line $line \"$str\""); warn "# Was:\n$out\n# Should've been:\n$test\n"; print $obj->error if $obj->can('error'); print Dumper $obj->parse_tree(\$str) if $obj->can('parse_tree'); exit; } } ### This next section of code is verbatim from Andy's code #------------------------------------------------------------------------ package Foo; sub new { my $class = shift; bless { @_ }, $class; } sub present { my $self = shift; return '{ ' . join(', ', map { "$_ => $self->{ $_ }" } sort keys %$self) . ' }'; } sub reverse { my $self = shift; return '{ ' . join(', ', map { "$_ => $self->{ $_ }" } reverse sort keys %$self) . ' }'; } #------------------------------------------------------------------------ package Blessed::List; sub as_list { my $self = shift; return @$self; } #------------------------------------------------------------------------ package main; my $vars = { foo => Foo->new( pi => 3.14, e => 2.718 ), blessed_list => bless([ "Hello", "World" ], 'Blessed::List'), }; ###----------------------------------------------------------------### ### These are Andy's tests coded as Paul's process_oks ### View plugin usage process_ok("[% USE v = View -%] [[% v.prefix %]]" => "[]", $vars); process_ok("[% USE v = View( map => { default='any' } ) -%] [[% v.map.default %]]" => "[any]", $vars); process_ok("[% USE view( prefix=> 'foo/', suffix => '.tt2') -%] [[% view.prefix %]bar[% view.suffix %]] [[% view.template_name('baz') %]]" => "[foo/bar.tt2] [foo/baz.tt2]", $vars); process_ok("[% USE view( prefix=> 'foo/', suffix => '.tt2') -%] [[% view.prefix %]bar[% view.suffix %]] [[% view.template_name('baz') %]]" => "[foo/bar.tt2] [foo/baz.tt2]", $vars); process_ok("[% USE view -%] [% view.print('Hello World') %] [% BLOCK text %]TEXT: [% item %][% END -%]" => "TEXT: Hello World\n", $vars); process_ok("[% USE view -%] [% view.print( { foo => 'bar' } ) %] [% BLOCK hash %]HASH: { [% FOREACH key = item.keys.sort -%] [% key %] => [% item.\$key %] [%- END %] } [% END -%]" => "HASH: { foo => bar }\n\n", $vars); process_ok("[% USE view -%] [% view = view.clone( prefix => 'my_' ) -%] [% view.view('hash', { bar => 'baz' }) %] [% BLOCK my_hash %]HASH: { [% FOREACH key = item.keys.sort -%] [% key %] => [% item.\$key %] [%- END %] } [% END -%]" => "HASH: { bar => baz }\n\n", $vars); process_ok("[% USE view(prefix='my_') -%] [% view.print( foo => 'wiz', bar => 'waz' ) %] [% BLOCK my_hash %]KEYS: [% item.keys.sort.join(', ') %][% END %] " => "KEYS: bar, foo\n\n\n", $vars); process_ok("[% USE view -%] [% view.print( view ) %] [% BLOCK Template_View %]Printing a Template::View object[% END -%]" => "Printing a Template::View object\n", $vars); process_ok("[% USE view(prefix='my_') -%] [% view.print( view ) %] [% view.print( view, prefix='your_' ) %] [% BLOCK my_Template_View %]Printing my Template::View object[% END -%] [% BLOCK your_Template_View %]Printing your Template::View object[% END -%]" => "Printing my Template::View object Printing your Template::View object\n" , $vars); process_ok("[% USE view(prefix='my_', notfound='any' ) -%] [% view.print( view ) %] [% view.print( view, prefix='your_' ) %] [% BLOCK my_any %]Printing any of my objects[% END -%] [% BLOCK your_any %]Printing any of your objects[% END -%]" => "Printing any of my objects Printing any of your objects ", $vars); process_ok("[% USE view(prefix => 'my_', map => { default => 'catchall' } ) -%] [% view.print( view ) %] [% view.print( view, default='catchsome' ) %] [% BLOCK my_catchall %]Catching all defaults[% END -%] [% BLOCK my_catchsome %]Catching some defaults[% END -%]" => "Catching all defaults Catching some defaults ", $vars); process_ok("[% USE view(prefix => 'my_', map => { default => 'catchnone' } ) -%] [% view.default %] [% view.default = 'catchall' -%] [% view.default %] [% view.print( view ) %] [% view.print( view, default='catchsome' ) %] [% BLOCK my_catchall %]Catching all defaults[% END -%] [% BLOCK my_catchsome %]Catching some defaults[% END -%]" => "catchnone catchall Catching all defaults Catching some defaults ", $vars); process_ok("[% USE view(prefix='my_', default='catchall' notfound='lost') -%] [% view.print( view ) %] [% BLOCK my_lost %]Something has been found[% END -%]" => "Something has been found ", $vars); process_ok("[% USE view -%] [% TRY ; view.print( view ) ; CATCH view ; \"[\$error.type] \$error.info\" ; END %]" => qr{^\Q[view] file error - Template_View: not found\E}, $vars); process_ok("[% USE view -%] [% view.print( foo ) %]" => "{ e => 2.718, pi => 3.14 }", $vars); process_ok("[% USE view -%] [% view.print( foo, method => 'reverse' ) %]" => "{ pi => 3.14, e => 2.718 }", $vars); process_ok("[% USE view(prefix='my_', include_naked=0, view_naked=1) -%] [% BLOCK my_foo; \"Foo: \$item\"; END -%] [[% view.view_foo(20) %]] [[% view.foo(30) %]]" => "[Foo: 20] [Foo: 30]", $vars); process_ok("[% USE view(prefix='my_', include_naked=0, view_naked=0) -%] [% BLOCK my_foo; \"Foo: \$item\"; END -%] [[% view.view_foo(20) %]] [% TRY ; view.foo(30) ; CATCH ; error.info ; END %]" => "[Foo: 20] no such view member: foo", $vars); process_ok("[% USE view(map => { HASH => 'my_hash', ARRAY => 'your_list' }) -%] [% BLOCK text %]TEXT: [% item %][% END -%] [% BLOCK my_hash %]HASH: [% item.keys.sort.join(', ') %][% END -%] [% BLOCK your_list %]LIST: [% item.join(', ') %][% END -%] [% view.print(\"some text\") %] [% view.print({ alpha => 'a', bravo => 'b' }) %] [% view.print([ 'charlie', 'delta' ]) %]" => "TEXT: some text HASH: alpha, bravo LIST: charlie, delta", $vars); process_ok("[% USE view(item => 'thing', map => { HASH => 'my_hash', ARRAY => 'your_list' }) -%] [% BLOCK text %]TEXT: [% thing %][% END -%] [% BLOCK my_hash %]HASH: [% thing.keys.sort.join(', ') %][% END -%] [% BLOCK your_list %]LIST: [% thing.join(', ') %][% END -%] [% view.print(\"some text\") %] [% view.print({ alpha => 'a', bravo => 'b' }) %] [% view.print([ 'charlie', 'delta' ]) %]" => "TEXT: some text HASH: alpha, bravo LIST: charlie, delta", $vars); process_ok("[% USE view -%] [% view.print('Hello World') %] [% view1 = view.clone( prefix='my_') -%] [% view1.print('Hello World') %] [% view2 = view1.clone( prefix='dud_', notfound='no_text' ) -%] [% view2.print('Hello World') %] [% BLOCK text %]TEXT: [% item %][% END -%] [% BLOCK my_text %]MY TEXT: [% item %][% END -%] [% BLOCK dud_no_text %]NO TEXT: [% item %][% END -%]" => "TEXT: Hello World MY TEXT: Hello World NO TEXT: Hello World ", $vars); process_ok("[% USE view( prefix = 'base_', default => 'any' ) -%] [% view1 = view.clone( prefix => 'one_') -%] [% view2 = view.clone( prefix => 'two_') -%] [% view.default %] / [% view.map.default %] [% view1.default = 'anyone' -%] [% view1.default %] / [% view1.map.default %] [% view2.map.default = 'anytwo' -%] [% view2.default %] / [% view2.map.default %] [% view.print(\"Hello World\") %] / [% view.print(blessed_list) %] [% view1.print(\"Hello World\") %] / [% view1.print(blessed_list) %] [% view2.print(\"Hello World\") %] / [% view2.print(blessed_list) %] [% BLOCK base_text %]ANY TEXT: [% item %][% END -%] [% BLOCK one_text %]ONE TEXT: [% item %][% END -%] [% BLOCK two_text %]TWO TEXT: [% item %][% END -%] [% BLOCK base_any %]BASE ANY: [% item.as_list.join(', ') %][% END -%] [% BLOCK one_anyone %]ONE ANY: [% item.as_list.join(', ') %][% END -%] [% BLOCK two_anytwo %]TWO ANY: [% item.as_list.join(', ') %][% END -%]" => "any / any anyone / anyone anytwo / anytwo ANY TEXT: Hello World / BASE ANY: Hello, World ONE TEXT: Hello World / ONE ANY: Hello, World TWO TEXT: Hello World / TWO ANY: Hello, World ", $vars); process_ok("[% USE view( prefix => 'my_', item => 'thing' ) -%] [% view.view('thingy', [ 'foo', 'bar'] ) %] [% BLOCK my_thingy %]thingy: [ [% thing.join(', ') %] ][%END %]" => "thingy: [ foo, bar ] ", $vars); process_ok("[% USE view -%] [% view.map.\${'Template::View'} = 'myview' -%] [% view.print(view) %] [% BLOCK myview %]MYVIEW[% END%]" => "MYVIEW ", $vars); process_ok("[% USE view -%] [% view.include('greeting', msg => 'Hello World!') %] [% BLOCK greeting %]msg: [% msg %][% END -%]" => "msg: Hello World! ", $vars); process_ok("[% USE view( prefix=\"my_\" )-%] [% view.include('greeting', msg => 'Hello World!') %] [% BLOCK my_greeting %]msg: [% msg %][% END -%]" => "msg: Hello World! ", $vars); process_ok("[% USE view( prefix=\"my_\" )-%] [% view.include_greeting( msg => 'Hello World!') %] [% BLOCK my_greeting %]msg: [% msg %][% END -%]" => "msg: Hello World! ", $vars); process_ok("[% USE view( prefix=\"my_\" )-%] [% INCLUDE \$view.template('greeting') msg = 'Hello World!' %] [% BLOCK my_greeting %]msg: [% msg %][% END -%]" => "msg: Hello World! ", $vars); process_ok("[% USE view( title=\"My View\" )-%] [% view.title %]" => "My View", $vars); process_ok("[% USE view( title=\"My View\" )-%] [% newview = view.clone( col = 'Chartreuse') -%] [% newerview = newview.clone( title => 'New Title' ) -%] [% view.title %] [% newview.title %] [% newview.col %] [% newerview.title %] [% newerview.col %]" => "My View My View Chartreuse New Title Chartreuse", $vars); ###----------------------------------------------------------------### ### VIEW directive usage process_ok("[% VIEW fred prefix='blat_' %] This is the view [% END -%] [% BLOCK blat_foo; 'This is blat_foo'; END -%] [% fred.view_foo %]" => "This is blat_foo", $vars); process_ok("[% VIEW fred %] This is the view [% view.prefix = 'blat_' %] [% END -%] [% BLOCK blat_foo; 'This is blat_foo'; END -%] [% fred.view_foo %]" => "This is blat_foo", $vars); process_ok("[% VIEW fred %] This is the view [% view.prefix = 'blat_' %] [% view.thingy = 'bloop' %] [% fred.name = 'Freddy' %] [% END -%] [% fred.prefix %] [% fred.thingy %] [% fred.name %]" => "blat_ bloop Freddy", $vars); process_ok("[% VIEW fred prefix='blat_'; view.name='Fred'; END -%] [% fred.prefix %] [% fred.name %] [% TRY; fred.prefix = 'nonblat_'; CATCH; error; END %] [% TRY; fred.name = 'Derek'; CATCH; error; END %]" => "blat_ Fred view error - cannot update config item in sealed view: prefix view error - cannot update item in sealed view: name", $vars); process_ok("[% VIEW foo prefix='blat_' default=\"default\" notfound=\"notfound\" title=\"fred\" age=23 height=1.82 %] [% view.other = 'another' %] [% END -%] [% BLOCK blat_hash -%] [% FOREACH key = item.keys.sort -%] [% key %] => [% item.\$key %] [% END -%] [% END -%] [% foo.print(foo.data) %]" => " age => 23 height => 1.82 other => another title => fred ", $vars); process_ok("[% VIEW foo %] [% BLOCK hello -%] Hello World! [% END %] [% BLOCK goodbye -%] Goodbye World! [% END %] [% END -%] [% TRY; INCLUDE foo; CATCH; error; END %] [% foo.include_hello %]" => qr{^\Qfile error - foo: not found Hello World! \E}, $vars); process_ok("[% title = \"Previous Title\" -%] [% VIEW foo include_naked = 1 title = title or 'Default Title' copy = 'me, now' -%] [% view.bgcol = '#ffffff' -%] [% BLOCK header -%] Header: bgcol: [% view.bgcol %] title: [% title %] view.title: [% view.title %] [%- END %] [% BLOCK footer -%] © Copyright [% view.copy %] [%- END %] [% END -%] [% title = 'New Title' -%] [% foo.header %] [% foo.header(bgcol='#dead' title=\"Title Parameter\") %] [% foo.footer %] [% foo.footer(copy=\"you, then\") %] " => "Header: bgcol: #ffffff title: New Title view.title: Previous Title Header: bgcol: #ffffff title: Title Parameter view.title: Previous Title © Copyright me, now © Copyright me, now ", $vars); process_ok("[% VIEW foo title = 'My View' author = 'Andy Wardley' bgcol = bgcol or '#ffffff' -%] [% view.arg1 = 'argument #1' -%] [% view.data.arg2 = 'argument #2' -%] [% END -%] [% foo.title %] [% foo.author %] [% foo.bgcol %] [% foo.arg1 %] [% foo.arg2 %] [% bar = foo.clone( title='New View', arg1='New Arg1' ) %]cloned! [% bar.title %] [% bar.author %] [% bar.bgcol %] [% bar.arg1 %] [% bar.arg2 %] originals: [% foo.title %] [% foo.arg1 %] " => " My View Andy Wardley #ffffff argument #1 argument #2 cloned! New View Andy Wardley #ffffff New Arg1 argument #2 originals: My View argument #1 ", $vars); process_ok("[% VIEW basic title = \"My Web Site\" %] [% BLOCK header -%] This is the basic header: [% title or view.title %] [%- END -%] [% END -%] [%- VIEW fancy title = \"\$basic.title\" basic = basic %] [% BLOCK header ; view.basic.header(title = title or view.title) %] Fancy new part of header [%- END %] [% END -%] === [% basic.header %] [% basic.header( title = \"New Title\" ) %] === [% fancy.header %] [% fancy.header( title = \"Fancy Title\" ) %]" => "=== This is the basic header: My Web Site This is the basic header: New Title === This is the basic header: My Web Site Fancy new part of header This is the basic header: Fancy Title Fancy new part of header", $vars); process_ok("[% VIEW baz notfound='lost' %] [% BLOCK lost; 'lost, not found'; END %] [% END -%] [% baz.any %]" => "lost, not found", $vars); process_ok("[% VIEW woz prefix='outer_' %] [% BLOCK wiz; 'The inner wiz'; END %] [% END -%] [% BLOCK outer_waz; 'The outer waz'; END -%] [% woz.wiz %] [% woz.waz %]" => "The inner wiz The outer waz", $vars); process_ok("[% VIEW foo %] [% BLOCK file -%] File: [% item.name %] [%- END -%] [% BLOCK directory -%] Dir: [% item.name %] [%- END %] [% END -%] [% foo.view_file({ name => 'some_file' }) %] [% foo.include_file(item => { name => 'some_file' }) %] [% foo.view('directory', { name => 'some_dir' }) %]" => " File: some_file File: some_file Dir: some_dir", $vars); process_ok("[% BLOCK parent -%] This is the base block [%- END -%] [% VIEW super %] [%- BLOCK parent -%] [%- INCLUDE parent FILTER replace('base', 'super') -%] [%- END -%] [% END -%] base: [% INCLUDE parent %] super: [% super.parent %]" => "base: This is the base block super: This is the super block", $vars); process_ok("[% BLOCK foo -%] public foo block [%- END -%] [% VIEW plain %] [% BLOCK foo -%] [% PROCESS foo %] [%- END %] [% END -%] [% VIEW fancy %] [% BLOCK foo -%] [%- plain.foo | replace('plain', 'fancy') -%] [%- END %] [% END -%] [% plain.foo %] [% fancy.foo %]" => "public foo block public foo block", $vars); process_ok("[% VIEW foo %] [% BLOCK Blessed_List -%] This is a list: [% item.as_list.join(', ') %] [% END -%] [% END -%] [% foo.print(blessed_list) %]" => "This is a list: Hello, World ", $vars); process_ok("[% VIEW my.foo value=33; END -%] n: [% my.foo.value %]" => "n: 33", $vars); process_ok("[% VIEW parent -%] [% BLOCK one %]This is base one[% END %] [% BLOCK two %]This is base two[% END %] [% END -%] [%- VIEW child1 base=parent %] [% BLOCK one %]This is child1 one[% END %] [% END -%] [%- VIEW child2 base=parent %] [% BLOCK two %]This is child2 two[% END %] [% END -%] [%- VIEW child3 base=child2 %] [% BLOCK two %]This is child3 two[% END %] [% END -%] [%- FOREACH child = [ child1, child2, child3 ] -%] one: [% child.one %] [% END -%] [% FOREACH child = [ child1, child2, child3 ] -%] two: [% child.two %] [% END %] " => "one: This is child1 one one: This is base one one: This is base one two: This is base two two: This is child2 two two: This is child3 two ", $vars); process_ok("[% VIEW my.view.default prefix = 'view/default/' value = 3.14; END -%] value: [% my.view.default.value %]" => "value: 3.14", $vars); process_ok("[% VIEW my.view.default prefix = 'view/default/' value = 3.14; END; VIEW my.view.one base = my.view.default prefix = 'view/one/'; END; VIEW my.view.two base = my.view.default value = 2.718; END; -%] [% BLOCK view/default/foo %]Default foo[% END -%] [% BLOCK view/one/foo %]One foo[% END -%] 0: [% my.view.default.foo %] 1: [% my.view.one.foo %] 2: [% my.view.two.foo %] 0: [% my.view.default.value %] 1: [% my.view.one.value %] 2: [% my.view.two.value %]" => "0: Default foo 1: One foo 2: Default foo 0: 3.14 1: 3.14 2: 2.718", $vars); process_ok("[% VIEW foo number = 10 sealed = 0; END -%] a: [% foo.number %] b: [% foo.number = 20 %] c: [% foo.number %] d: [% foo.number(30) %] e: [% foo.number %]" => "a: 10 b: c: 20 d: 30 e: 30", $vars); process_ok("[% VIEW foo number = 10 silent = 1; END -%] a: [% foo.number %] b: [% foo.number = 20 %] c: [% foo.number %] d: [% foo.number(30) %] e: [% foo.number %]" => "a: 10 b: c: 10 d: 10 e: 10", $vars);