5 7_template_02_view.t - Test the ability to handle views in CGI::Ex::Template
9 #============================================================= -*-perl-*-
11 # The tests used here where originally written by Andy Wardley
12 # They have been modified to work with this testing framework
13 # The following is the original Copyright notice included with
14 # the t/view.t document that these tests were taken from.
16 # Tests the 'View' plugin.
18 # Written by Andy Wardley <abw@kfs.org>
20 # Copyright (C) 2000 Andy Wardley. All Rights Reserved.
22 # This is free software; you can redistribute it and/or modify it
23 # under the same terms as Perl itself.
25 # Id: view.t 131 2001-06-14 13:20:12Z abw
27 #========================================================================
29 use vars qw($module $is_tt);
31 $module = 'CGI::Ex::Template'; #real 0m0.885s #user 0m0.432s #sys 0m0.004s
32 # $module = 'Template'; #real 0m2.133s #user 0m1.108s #sys 0m0.024s
33 $is_tt = $module eq 'Template';
37 use Test::More tests => ! $is_tt ? 53 : 53;
38 use Data::Dumper qw(Dumper);
44 if (! eval { require Template::View }) {
46 skip("Template::View is not installed - skipping VIEW tests", 52);
52 sub process_ok { # process the value and say if it was ok
55 my $vars = shift || {};
56 my $conf = local $vars->{'tt_config'} = $vars->{'tt_config'} || [];
57 my $obj = shift || $module->new(@$conf); # new object each time
59 my $line = (caller)[2];
60 delete $vars->{'tt_config'};
62 $obj->process(\$str, $vars, \$out);
63 my $ok = ref($test) ? $out =~ $test : $out eq $test;
65 ok(1, "Line $line \"$str\" => \"$out\"");
68 ok(0, "Line $line \"$str\"");
69 warn "# Was:\n$out\n# Should've been:\n$test\n";
70 print $obj->error if $obj->can('error');
71 print Dumper $obj->parse_tree(\$str) if $obj->can('parse_tree');
76 ### This next section of code is verbatim from Andy's code
77 #------------------------------------------------------------------------
87 return '{ ' . join(', ', map { "$_ => $self->{ $_ }" }
88 sort keys %$self) . ' }';
93 return '{ ' . join(', ', map { "$_ => $self->{ $_ }" }
94 reverse sort keys %$self) . ' }';
97 #------------------------------------------------------------------------
98 package Blessed::List;
105 #------------------------------------------------------------------------
109 foo => Foo->new( pi => 3.14, e => 2.718 ),
110 blessed_list => bless([ "Hello", "World" ], 'Blessed::List'),
113 ###----------------------------------------------------------------###
114 ### These are Andy's tests coded as Paul's process_oks
116 ### View plugin usage
118 process_ok("[% USE v = View -%]
119 [[% v.prefix %]]" => "[]", $vars);
121 process_ok("[% USE v = View( map => { default='any' } ) -%]
122 [[% v.map.default %]]" => "[any]", $vars);
124 process_ok("[% USE view( prefix=> 'foo/', suffix => '.tt2') -%]
125 [[% view.prefix %]bar[% view.suffix %]]
126 [[% view.template_name('baz') %]]" => "[foo/bar.tt2]
127 [foo/baz.tt2]", $vars);
129 process_ok("[% USE view( prefix=> 'foo/', suffix => '.tt2') -%]
130 [[% view.prefix %]bar[% view.suffix %]]
131 [[% view.template_name('baz') %]]" => "[foo/bar.tt2]
132 [foo/baz.tt2]", $vars);
134 process_ok("[% USE view -%]
135 [% view.print('Hello World') %]
136 [% BLOCK text %]TEXT: [% item %][% END -%]" => "TEXT: Hello World\n", $vars);
138 process_ok("[% USE view -%]
139 [% view.print( { foo => 'bar' } ) %]
140 [% BLOCK hash %]HASH: {
141 [% FOREACH key = item.keys.sort -%]
142 [% key %] => [% item.\$key %]
145 [% END -%]" => "HASH: {
149 process_ok("[% USE view -%]
150 [% view = view.clone( prefix => 'my_' ) -%]
151 [% view.view('hash', { bar => 'baz' }) %]
152 [% BLOCK my_hash %]HASH: {
153 [% FOREACH key = item.keys.sort -%]
154 [% key %] => [% item.\$key %]
157 [% END -%]" => "HASH: {
161 process_ok("[% USE view(prefix='my_') -%]
162 [% view.print( foo => 'wiz', bar => 'waz' ) %]
163 [% BLOCK my_hash %]KEYS: [% item.keys.sort.join(', ') %][% END %]
165 " => "KEYS: bar, foo\n\n\n", $vars);
167 process_ok("[% USE view -%]
168 [% view.print( view ) %]
169 [% BLOCK Template_View %]Printing a Template::View object[% END -%]" => "Printing a Template::View object\n", $vars);
171 process_ok("[% USE view(prefix='my_') -%]
172 [% view.print( view ) %]
173 [% view.print( view, prefix='your_' ) %]
174 [% BLOCK my_Template_View %]Printing my Template::View object[% END -%]
175 [% BLOCK your_Template_View %]Printing your Template::View object[% END -%]" => "Printing my Template::View object
176 Printing your Template::View object\n" , $vars);
178 process_ok("[% USE view(prefix='my_', notfound='any' ) -%]
179 [% view.print( view ) %]
180 [% view.print( view, prefix='your_' ) %]
181 [% BLOCK my_any %]Printing any of my objects[% END -%]
182 [% BLOCK your_any %]Printing any of your objects[% END -%]" => "Printing any of my objects
183 Printing any of your objects
186 process_ok("[% USE view(prefix => 'my_', map => { default => 'catchall' } ) -%]
187 [% view.print( view ) %]
188 [% view.print( view, default='catchsome' ) %]
189 [% BLOCK my_catchall %]Catching all defaults[% END -%]
190 [% BLOCK my_catchsome %]Catching some defaults[% END -%]" => "Catching all defaults
191 Catching some defaults
194 process_ok("[% USE view(prefix => 'my_', map => { default => 'catchnone' } ) -%]
196 [% view.default = 'catchall' -%]
198 [% view.print( view ) %]
199 [% view.print( view, default='catchsome' ) %]
200 [% BLOCK my_catchall %]Catching all defaults[% END -%]
201 [% BLOCK my_catchsome %]Catching some defaults[% END -%]" => "catchnone
203 Catching all defaults
204 Catching some defaults
207 process_ok("[% USE view(prefix='my_', default='catchall' notfound='lost') -%]
208 [% view.print( view ) %]
209 [% BLOCK my_lost %]Something has been found[% END -%]" => "Something has been found
212 process_ok("[% USE view -%]
216 \"[\$error.type] \$error.info\" ;
218 %]" => qr{^\Q[view] file error - Template_View: not found\E}, $vars);
220 process_ok("[% USE view -%]
221 [% view.print( foo ) %]" => "{ e => 2.718, pi => 3.14 }", $vars);
223 process_ok("[% USE view -%]
224 [% view.print( foo, method => 'reverse' ) %]" => "{ pi => 3.14, e => 2.718 }", $vars);
226 process_ok("[% USE view(prefix='my_', include_naked=0, view_naked=1) -%]
227 [% BLOCK my_foo; \"Foo: \$item\"; END -%]
228 [[% view.view_foo(20) %]]
229 [[% view.foo(30) %]]" => "[Foo: 20]
232 process_ok("[% USE view(prefix='my_', include_naked=0, view_naked=0) -%]
233 [% BLOCK my_foo; \"Foo: \$item\"; END -%]
234 [[% view.view_foo(20) %]]
241 no such view member: foo", $vars);
243 process_ok("[% USE view(map => { HASH => 'my_hash', ARRAY => 'your_list' }) -%]
244 [% BLOCK text %]TEXT: [% item %][% END -%]
245 [% BLOCK my_hash %]HASH: [% item.keys.sort.join(', ') %][% END -%]
246 [% BLOCK your_list %]LIST: [% item.join(', ') %][% END -%]
247 [% view.print(\"some text\") %]
248 [% view.print({ alpha => 'a', bravo => 'b' }) %]
249 [% view.print([ 'charlie', 'delta' ]) %]" => "TEXT: some text
251 LIST: charlie, delta", $vars);
253 process_ok("[% USE view(item => 'thing',
254 map => { HASH => 'my_hash', ARRAY => 'your_list' }) -%]
255 [% BLOCK text %]TEXT: [% thing %][% END -%]
256 [% BLOCK my_hash %]HASH: [% thing.keys.sort.join(', ') %][% END -%]
257 [% BLOCK your_list %]LIST: [% thing.join(', ') %][% END -%]
258 [% view.print(\"some text\") %]
259 [% view.print({ alpha => 'a', bravo => 'b' }) %]
260 [% view.print([ 'charlie', 'delta' ]) %]" => "TEXT: some text
262 LIST: charlie, delta", $vars);
264 process_ok("[% USE view -%]
265 [% view.print('Hello World') %]
266 [% view1 = view.clone( prefix='my_') -%]
267 [% view1.print('Hello World') %]
268 [% view2 = view1.clone( prefix='dud_', notfound='no_text' ) -%]
269 [% view2.print('Hello World') %]
270 [% BLOCK text %]TEXT: [% item %][% END -%]
271 [% BLOCK my_text %]MY TEXT: [% item %][% END -%]
272 [% BLOCK dud_no_text %]NO TEXT: [% item %][% END -%]" => "TEXT: Hello World
277 process_ok("[% USE view( prefix = 'base_', default => 'any' ) -%]
278 [% view1 = view.clone( prefix => 'one_') -%]
279 [% view2 = view.clone( prefix => 'two_') -%]
280 [% view.default %] / [% view.map.default %]
281 [% view1.default = 'anyone' -%]
282 [% view1.default %] / [% view1.map.default %]
283 [% view2.map.default = 'anytwo' -%]
284 [% view2.default %] / [% view2.map.default %]
285 [% view.print(\"Hello World\") %] / [% view.print(blessed_list) %]
286 [% view1.print(\"Hello World\") %] / [% view1.print(blessed_list) %]
287 [% view2.print(\"Hello World\") %] / [% view2.print(blessed_list) %]
288 [% BLOCK base_text %]ANY TEXT: [% item %][% END -%]
289 [% BLOCK one_text %]ONE TEXT: [% item %][% END -%]
290 [% BLOCK two_text %]TWO TEXT: [% item %][% END -%]
291 [% BLOCK base_any %]BASE ANY: [% item.as_list.join(', ') %][% END -%]
292 [% BLOCK one_anyone %]ONE ANY: [% item.as_list.join(', ') %][% END -%]
293 [% BLOCK two_anytwo %]TWO ANY: [% item.as_list.join(', ') %][% END -%]" => "any / any
296 ANY TEXT: Hello World / BASE ANY: Hello, World
297 ONE TEXT: Hello World / ONE ANY: Hello, World
298 TWO TEXT: Hello World / TWO ANY: Hello, World
301 process_ok("[% USE view( prefix => 'my_', item => 'thing' ) -%]
302 [% view.view('thingy', [ 'foo', 'bar'] ) %]
303 [% BLOCK my_thingy %]thingy: [ [% thing.join(', ') %] ][%END %]" => "thingy: [ foo, bar ]
306 process_ok("[% USE view -%]
307 [% view.map.\${'Template::View'} = 'myview' -%]
308 [% view.print(view) %]
309 [% BLOCK myview %]MYVIEW[% END%]" => "MYVIEW
312 process_ok("[% USE view -%]
313 [% view.include('greeting', msg => 'Hello World!') %]
314 [% BLOCK greeting %]msg: [% msg %][% END -%]" => "msg: Hello World!
317 process_ok("[% USE view( prefix=\"my_\" )-%]
318 [% view.include('greeting', msg => 'Hello World!') %]
319 [% BLOCK my_greeting %]msg: [% msg %][% END -%]" => "msg: Hello World!
322 process_ok("[% USE view( prefix=\"my_\" )-%]
323 [% view.include_greeting( msg => 'Hello World!') %]
324 [% BLOCK my_greeting %]msg: [% msg %][% END -%]" => "msg: Hello World!
327 process_ok("[% USE view( prefix=\"my_\" )-%]
328 [% INCLUDE \$view.template('greeting')
329 msg = 'Hello World!' %]
330 [% BLOCK my_greeting %]msg: [% msg %][% END -%]" => "msg: Hello World!
333 process_ok("[% USE view( title=\"My View\" )-%]
334 [% view.title %]" => "My View", $vars);
336 process_ok("[% USE view( title=\"My View\" )-%]
337 [% newview = view.clone( col = 'Chartreuse') -%]
338 [% newerview = newview.clone( title => 'New Title' ) -%]
342 [% newerview.title %]
343 [% newerview.col %]" => "My View
349 ###----------------------------------------------------------------###
351 ### VIEW directive usage
353 process_ok("[% VIEW fred prefix='blat_' %]
356 [% BLOCK blat_foo; 'This is blat_foo'; END -%]
357 [% fred.view_foo %]" => "This is blat_foo", $vars);
359 process_ok("[% VIEW fred %]
361 [% view.prefix = 'blat_' %]
363 [% BLOCK blat_foo; 'This is blat_foo'; END -%]
364 [% fred.view_foo %]" => "This is blat_foo", $vars);
366 process_ok("[% VIEW fred %]
368 [% view.prefix = 'blat_' %]
369 [% view.thingy = 'bloop' %]
370 [% fred.name = 'Freddy' %]
374 [% fred.name %]" => "blat_
378 process_ok("[% VIEW fred prefix='blat_'; view.name='Fred'; END -%]
382 fred.prefix = 'nonblat_';
394 view error - cannot update config item in sealed view: prefix
395 view error - cannot update item in sealed view: name", $vars);
397 process_ok("[% VIEW foo prefix='blat_' default=\"default\" notfound=\"notfound\"
398 title=\"fred\" age=23 height=1.82 %]
399 [% view.other = 'another' %]
401 [% BLOCK blat_hash -%]
402 [% FOREACH key = item.keys.sort -%]
403 [% key %] => [% item.\$key %]
406 [% foo.print(foo.data) %]" => " age => 23
412 process_ok("[% VIEW foo %]
420 [% TRY; INCLUDE foo; CATCH; error; END %]
421 [% foo.include_hello %]" => qr{^\Qfile error - foo: not found
425 process_ok("[% title = \"Previous Title\" -%]
428 title = title or 'Default Title'
432 [% view.bgcol = '#ffffff' -%]
435 Header: bgcol: [% view.bgcol %]
437 view.title: [% view.title %]
441 © Copyright [% view.copy %]
445 [% title = 'New Title' -%]
447 [% foo.header(bgcol='#dead' title=\"Title Parameter\") %]
449 [% foo.footer(copy=\"you, then\") %]
450 " => "Header: bgcol: #ffffff
452 view.title: Previous Title
453 Header: bgcol: #ffffff
454 title: Title Parameter
455 view.title: Previous Title
456 © Copyright me, now
457 © Copyright me, now
460 process_ok("[% VIEW foo
462 author = 'Andy Wardley'
463 bgcol = bgcol or '#ffffff'
465 [% view.arg1 = 'argument #1' -%]
466 [% view.data.arg2 = 'argument #2' -%]
473 [% bar = foo.clone( title='New View', arg1='New Arg1' ) %]cloned!
500 process_ok("[% VIEW basic title = \"My Web Site\" %]
502 This is the basic header: [% title or view.title %]
507 title = \"<fancy>\$basic.title</fancy>\"
510 [% BLOCK header ; view.basic.header(title = title or view.title) %]
511 Fancy new part of header
516 [% basic.header( title = \"New Title\" ) %]
519 [% fancy.header( title = \"Fancy Title\" ) %]" => "===
520 This is the basic header: My Web Site
521 This is the basic header: New Title
523 This is the basic header: <fancy>My Web Site</fancy>
524 Fancy new part of header
525 This is the basic header: Fancy Title
526 Fancy new part of header", $vars);
528 process_ok("[% VIEW baz notfound='lost' %]
529 [% BLOCK lost; 'lost, not found'; END %]
531 [% baz.any %]" => "lost, not found", $vars);
533 process_ok("[% VIEW woz prefix='outer_' %]
534 [% BLOCK wiz; 'The inner wiz'; END %]
536 [% BLOCK outer_waz; 'The outer waz'; END -%]
538 [% woz.waz %]" => "The inner wiz
539 The outer waz", $vars);
541 process_ok("[% VIEW foo %]
544 File: [% item.name %]
547 [% BLOCK directory -%]
552 [% foo.view_file({ name => 'some_file' }) %]
553 [% foo.include_file(item => { name => 'some_file' }) %]
554 [% foo.view('directory', { name => 'some_dir' }) %]" => " File: some_file
556 Dir: some_dir", $vars);
558 process_ok("[% BLOCK parent -%]
559 This is the base block
563 [%- INCLUDE parent FILTER replace('base', 'super') -%]
566 base: [% INCLUDE parent %]
567 super: [% super.parent %]" => "base: This is the base block
568 super: This is the super block", $vars);
570 process_ok("[% BLOCK foo -%]
575 <plain>[% PROCESS foo %]</plain>
580 [%- plain.foo | replace('plain', 'fancy') -%]
584 [% fancy.foo %]" => "<plain>public foo block</plain>
585 <fancy>public foo block</fancy>", $vars);
587 process_ok("[% VIEW foo %]
588 [% BLOCK Blessed_List -%]
589 This is a list: [% item.as_list.join(', ') %]
592 [% foo.print(blessed_list) %]" => "This is a list: Hello, World
595 process_ok("[% VIEW my.foo value=33; END -%]
596 n: [% my.foo.value %]" => "n: 33", $vars);
598 process_ok("[% VIEW parent -%]
599 [% BLOCK one %]This is base one[% END %]
600 [% BLOCK two %]This is base two[% END %]
603 [%- VIEW child1 base=parent %]
604 [% BLOCK one %]This is child1 one[% END %]
607 [%- VIEW child2 base=parent %]
608 [% BLOCK two %]This is child2 two[% END %]
611 [%- VIEW child3 base=child2 %]
612 [% BLOCK two %]This is child3 two[% END %]
615 [%- FOREACH child = [ child1, child2, child3 ] -%]
618 [% FOREACH child = [ child1, child2, child3 ] -%]
621 " => "one: This is child1 one
622 one: This is base one
623 one: This is base one
624 two: This is base two
625 two: This is child2 two
626 two: This is child3 two
630 process_ok("[% VIEW my.view.default
631 prefix = 'view/default/'
635 value: [% my.view.default.value %]" => "value: 3.14", $vars);
637 process_ok("[% VIEW my.view.default
638 prefix = 'view/default/'
642 base = my.view.default
643 prefix = 'view/one/';
646 base = my.view.default
650 [% BLOCK view/default/foo %]Default foo[% END -%]
651 [% BLOCK view/one/foo %]One foo[% END -%]
652 0: [% my.view.default.foo %]
653 1: [% my.view.one.foo %]
654 2: [% my.view.two.foo %]
655 0: [% my.view.default.value %]
656 1: [% my.view.one.value %]
657 2: [% my.view.two.value %]" => "0: Default foo
664 process_ok("[% VIEW foo number = 10 sealed = 0; END -%]
666 b: [% foo.number = 20 %]
668 d: [% foo.number(30) %]
669 e: [% foo.number %]" => "a: 10
675 process_ok("[% VIEW foo number = 10 silent = 1; END -%]
677 b: [% foo.number = 20 %]
679 d: [% foo.number(30) %]
680 e: [% foo.number %]" => "a: 10