-process_ok("[% SET name = 'two' %][% SET \$name = 3 %][% two %]" => 3);
-process_ok("[% SET name = 'two' %][% SET \${name} = 3 %][% two %]" => 3);
-process_ok("[% SET name = 2 %][% SET foo.\$name = 3 %][% foo.2 %]" => 3);
-process_ok("[% SET name = 2 %][% SET foo.\$name = 3 %][% foo.\$name %]" => 3);
-process_ok("[% SET name = 2 %][% SET foo.\${name} = 3 %][% foo.2 %]" => 3);
-process_ok("[% SET name = 2 %][% SET foo.\${name} = 3 %][% foo.2 %]" => 3);
-process_ok("[% SET name = 'two' %][% SET \$name.foo = 3 %][% two.foo %]" => 3);
-process_ok("[% SET name = 'two' %][% SET \${name}.foo = 3 %][% two.foo %]" => 3);
-process_ok("[% SET name = 'two' %][% SET foo.\$name.foo = 3 %][% foo.two.foo %]" => 3);
-process_ok("[% SET name = 'two' %][% SET foo.\${name}.foo = 3 %][% foo.two.foo %]" => 3);
-
-process_ok("[% SET foo = [1..10] %][% foo.6 %]" => 7);
-process_ok("[% SET foo = [10..1] %][% foo.6 %]" => '');
-process_ok("[% SET foo = [-10..-1] %][% foo.6 %]" => -4);
-process_ok("[% SET foo = [1..10, 21..30] %][% foo.12 %]" => 23) if ! $is_tt;
-process_ok("[% SET foo = [..100] bar = 7 %][% bar %][% foo.0 %]" => '');
-process_ok("[% SET foo = [100..] bar = 7 %][% bar %][% foo.0 %]" => '');
-process_ok("[% SET foo = ['a'..'z'] %][% foo.6 %]" => 'g');
-process_ok("[% SET foo = ['z'..'a'] %][% foo.6 %]" => '');
-process_ok("[% SET foo = ['a'..'z'].reverse %][% foo.6 %]" => 't') if ! $is_tt;
-
-process_ok("[% foo = 1 %][% foo %]" => '1');
-process_ok("[% foo = 1 ; bar = 2 %][% foo %][% bar %]" => '12');
-process_ok("[% foo.bar = 2 %][% foo.bar %]" => '2');
-
-process_ok('[% a = "a" %]|[% (b = a) %]|[% a %]|[% b %]' => '|a|a|a');
-process_ok('[% a = "a" %][% (c = (b = a)) %][% a %][% b %][% c %]' => 'aaaa');
-
-process_ok("[% a = qw{Foo Bar Baz} ; a.2 %]" => 'Baz') if ! $is_tt;
-
-process_ok("[% _foo = 1 %][% _foo %]2" => '2');
-process_ok("[% foo._bar %]2" => '2', {foo => {_bar =>1}});
-
-###----------------------------------------------------------------###
-print "### multiple statements in same tag ##################################\n";
-
-process_ok("[% foo; %]" => '1', {foo => 1});
-process_ok("[% GET foo; %]" => '1', {foo => 1});
-process_ok("[% GET foo; GET foo %]" => '11', {foo => 1});
-process_ok("[% GET foo GET foo %]" => '11', {foo => 1}) if ! $is_tt;
-process_ok("[% GET foo GET foo %]" => '', {foo => 1, tt_config => [SEMICOLONS => 1]});
-
-process_ok("[% foo = 1 bar = 2 %][% foo %][% bar %]" => '12');
-process_ok("[% foo = 1 bar = 2 %][% foo = 3 bar %][% foo %][% bar %]" => '232') if ! $is_tt;
-process_ok("[% a = 1 a = a + 2 a %]" => '3') if ! $is_tt;
-
-process_ok("[% foo = 1 bar = 2 %][% foo %][% bar %]" => '', {tt_config => [SEMICOLONS => 1]}) if ! $is_tt;
-process_ok("[% foo = 1 bar = 2 %][% foo = 3 bar %][% foo %][% bar %]" => '', {tt_config => [SEMICOLONS => 1]});
-process_ok("[% a = 1 a = a + 2 a %]" => '', {tt_config => [SEMICOLONS => 1]});
-
-
-###----------------------------------------------------------------###
-print "### CALL / DEFAULT ###################################################\n";
-
-process_ok("[% DEFAULT foo = 7 %][% foo %]" => 7);
-process_ok("[% SET foo = 5 %][% DEFAULT foo = 7 %][% foo %]" => 5);
-process_ok("[% DEFAULT foo.bar.baz.bing = 6 %][% foo.bar.baz.bing %]" => 6);
-
-my $t = 0;
-process_ok("[% foo %]" => 'hi', {foo => sub {$t++; 'hi'}});
-process_ok("[% GET foo %]" => 'hi', {foo => sub {$t++; 'hi'}});
-process_ok("[% CALL foo %]" => '', {foo => sub {$t++; 'hi'}});
-ok($t == 3, "CALL method actually called var");
-
-###----------------------------------------------------------------###
-print "### scalar vmethods ##################################################\n";
-
-process_ok("[% n.0 %]" => '7', {n => 7}) if ! $is_tt;
-process_ok("[% n.abs %]" => '7', {n => 7}) if ! $is_tt;
-process_ok("[% n.abs %]" => '7', {n => -7}) if ! $is_tt;
-process_ok("[% n.atan2.substr(0, 6) %]" => '1.5707', {n => 7}) if ! $is_tt;
-process_ok("[% (4 * n.atan2(1)).substr(0, 7) %]" => '3.14159', {n => 1}) if ! $is_tt;
-process_ok("[% n.chunk(3).join %]" => 'abc def g', {n => 'abcdefg'});
-process_ok("[% n.chunk(-3).join %]" => 'a bcd efg', {n => 'abcdefg'});
-process_ok("[% n|collapse %]" => "a b", {n => ' a b '}); # TT2 filter
-process_ok("[% n.cos.substr(0,5) %]" => "1", {n => 0}) if ! $is_tt;
-process_ok("[% n.cos.substr(0,5) %]" => "0.707", {n => atan2(1,1)}) if ! $is_tt;
-process_ok("[% n.defined %]" => "1", {n => ''});
-process_ok("[% n.defined %]" => "", {n => undef});
-process_ok("[% n.defined %]" => "1", {n => '1'});
-process_ok("[% n.exp.substr(0,5) %]" => "2.718", {n => 1}) if ! $is_tt;
-process_ok("[% n.exp.log.substr(0,5) %]" => "8", {n => 8}) if ! $is_tt;
-process_ok("[% n.fmt %]" => '7', {n => 7}) if ! $is_tt;
-process_ok("[% n.fmt('%02d') %]" => '07', {n => 7}) if ! $is_tt;
-process_ok("[% n.fmt('%0*d', 3) %]" => '007', {n => 7}) if ! $is_tt;
-process_ok("[% n.fmt('(%s)') %]" => "(a\nb)", {n => "a\nb"}) if ! $is_tt;
-process_ok("[% n|format('%02d') %]" => '07', {n => 7}); # TT2 filter
-process_ok("[% n|format('%0*d', 3) %]" => '007', {n => 7}) if ! $is_tt;
-process_ok("[% n|format('(%s)') %]" => "(a)\n(b)", {n => "a\nb"}); # TT2 filter
-process_ok("[% n.hash.items.1 %]" => "b", {n => {a => "b"}});
-process_ok("[% n.hex %]" => "255", {n => "FF"}) if ! $is_tt;
-process_ok("[% n|html %]" => "&", {n => '&'}); # TT2 filter
-process_ok("[% n|indent %]" => " a\n b", {n => "a\nb"}); # TT2 filter
-process_ok("[% n|indent(2) %]" => " a\n b", {n => "a\nb"}); # TT2 filter
-process_ok("[% n|indent('wow ') %]" => "wow a\nwow b", {n => "a\nb"}); # TT2 filter
-process_ok("[% n.int %]" => "123", {n => "123.234"}) if ! $is_tt;
-process_ok("[% n.int %]" => "123", {n => "123gggg"}) if ! $is_tt;
-process_ok("[% n.int %]" => "0", {n => "ff123.234"}) if ! $is_tt;
-process_ok("[% n.item %]" => '7', {n => 7});
-process_ok("[% n.lc %]" => 'abc', {n => "ABC"}) if ! $is_tt;
-process_ok("[% n|lcfirst %]" => 'fOO', {n => "FOO"}); # TT2 filter
-process_ok("[% n.length %]" => 3, {n => "abc"});
-process_ok("[% n.list.0 %]" => 'abc', {n => "abc"});
-process_ok("[% n.log.substr(0,5) %]" => "4.605", {n => 100}) if ! $is_tt;
-process_ok("[% n|lower %]" => 'abc', {n => "ABC"}); # TT2 filter
-process_ok("[% n.match('foo').join %]" => '', {n => "bar"});
-process_ok("[% n.match('foo').join %]" => '1', {n => "foo"});
-process_ok("[% n.match('foo',1).join %]" => 'foo', {n => "foo"});
-process_ok("[% n.match('(foo)').join %]" => 'foo', {n => "foo"});
-process_ok("[% n.match('(foo)').join %]" => 'foo', {n => "foofoo"});
-process_ok("[% n.match('(foo)',1).join %]" => 'foo foo', {n => "foofoo"});
-process_ok("[% n.null %]" => '', {n => "abc"});
-process_ok("[% n.oct %]" => "255", {n => "377"}) if ! $is_tt;
-process_ok("[% n.rand %]" => qr{^\d+\.\d+}, {n => "2"}) if ! $is_tt;
-process_ok("[% n.rand %]" => qr{^\d+\.\d+}, {n => "ab"}) if ! $is_tt;
-process_ok("[% n.remove('bc') %]" => "a", {n => "abc"});
-process_ok("[% n.remove('bc') %]" => "aa", {n => "abcabc"});
-process_ok("[% n.repeat %]" => '1', {n => 1}) if ! $is_tt; # tt2 virtual method defaults to 0
-process_ok("[% n.repeat(0) %]" => '', {n => 1});
-process_ok("[% n.repeat(1) %]" => '1', {n => 1});
-process_ok("[% n.repeat(2) %]" => '11', {n => 1});
-process_ok("[% n.repeat(2,'|') %]" => '1|1', {n => 1}) if ! $is_tt;
-process_ok("[% n.replace('foo', 'bar') %]" => 'barbar', {n => 'foofoo'});
-process_ok("[% n.replace('(foo)', 'bar\$1') %]" => 'barfoobarfoo', {n => 'foofoo'}) if ! $is_tt;
-process_ok("[% n.replace('foo', 'bar', 0) %]" => 'barfoo', {n => 'foofoo'}) if ! $is_tt;
-process_ok("[% n.search('foo') %]" => '', {n => "bar"});
-process_ok("[% n.search('foo') %]" => '1', {n => "foo"});
-process_ok("[% n.sin.substr(0,5) %]" => "0", {n => 0}) if ! $is_tt;
-process_ok("[% n.sin.substr(0,5) %]" => "1", {n => 2*atan2(1,1)}) if ! $is_tt;
-process_ok("[% n.size %]" => '1', {n => "foo"});
-process_ok("[% n.split.join('|') %]" => "abc", {n => "abc"});
-process_ok("[% n.split.join('|') %]" => "a|b|c", {n => "a b c"});
-process_ok("[% n.split.join('|') %]" => "a|b|c", {n => "a b c"});
-process_ok("[% n.split(u,2).join('|') %]" => "a|b c", {n => "a b c", u => undef}) if ! $is_tt;
-process_ok("[% n.split(u,2).join('|') %]" => "a| b c", {n => "a b c", u => undef}) if $is_tt;
-process_ok("[% n.split('/').join('|') %]" => "a|b|c", {n => "a/b/c"});
-process_ok("[% n.split('/', 2).join('|') %]" => "a|b/c", {n => "a/b/c"});
-process_ok("[% n.sprintf(7) %]" => '7', {n => '%d'}) if ! $is_tt;
-process_ok("[% n.sprintf(3, 7, 12) %]" => '007 12', {n => '%0*d %d'}) if ! $is_tt;
-process_ok("[% n.sqrt %]" => "3", {n => 9}) if ! $is_tt;
-process_ok("[% n.srand; 12 %]" => "12", {n => 9}) if ! $is_tt;
-process_ok("[% n.stderr %]" => "", {n => "# testing stderr ... ok\r"});
-process_ok("[% n|trim %]" => "a b", {n => ' a b '}); # TT2 filter
-process_ok("[% n.uc %]" => 'FOO', {n => "foo"}) if ! $is_tt; # TT2 filter
-process_ok("[% n|ucfirst %]" => 'Foo', {n => "foo"}); # TT2 filter
-process_ok("[% n|upper %]" => 'FOO', {n => "foo"}); # TT2 filter
-process_ok("[% n|uri %]" => 'a%20b', {n => "a b"}); # TT2 filter
-
-###----------------------------------------------------------------###
-print "### list vmethods ####################################################\n";
-
-process_ok("[% a.defined %]" => '1', {a => [2,3]});
-process_ok("[% a.defined(1) %]" => '1', {a => [2,3]});
-process_ok("[% a.defined(3) %]" => '', {a => [2,3]});
-process_ok("[% a.first %]" => '2', {a => [2..10]});
-process_ok("[% a.first(3).join %]" => '2 3 4', {a => [2..10]});
-process_ok("[% a.fmt %]" => '2 3', {a => [2,3]}) if ! $is_tt;
-process_ok("[% a.fmt('%02d') %]" => '02 03', {a => [2,3]}) if ! $is_tt;
-process_ok("[% a.fmt('%02d',' ') %]" => '02 03', {a => [2,3]}) if ! $is_tt;
-process_ok("[% a.fmt('%02d','|') %]" => '02|03', {a => [2,3]}) if ! $is_tt;
-process_ok("[% a.fmt('%0*d','|', 3) %]" => '002|003', {a => [2,3]}) if ! $is_tt;
-process_ok("[% a.grep.join %]" => '2 3', {a => [2,3]});
-process_ok("[% a.grep(2).join %]" => '2', {a => [2,3]});
-process_ok("[% a.hash.items.join %]" => '2 3', {a => [2,3]});
-process_ok("[% a.hash(5).items.sort.join %]" => '2 3 5 6', {a => [2,3]});
-process_ok("[% a.import(5) %]|[% a.join %]" => '|2 3', {a => [2,3]}) if ! $is_tt;
-process_ok("[% a.import(5) %]|[% a.join %]" => qr{^ARRAY.+|2 3$ }x, {a => [2,3]}) if $is_tt;
-process_ok("[% a.import([5]) %]|[% a.join %]" => '|2 3 5', {a => [2,3]}) if ! $is_tt;
-process_ok("[% a.import([5]) %]|[% a.join %]" => qr{ARRAY.+|2 3 5$ }x, {a => [2,3]}) if $is_tt;
-process_ok("[% a.item %]" => '2', {a => [2,3]});
-process_ok("[% a.item(1) %]" => '3', {a => [2,3]});
-process_ok("[% a.join %]" => '2 3', {a => [2,3]});
-process_ok("[% a.join('|') %]" => '2|3', {a => [2,3]});
-process_ok("[% a.last %]" => '10', {a => [2..10]});
-process_ok("[% a.last(3).join %]" => '8 9 10', {a => [2..10]});
-process_ok("[% a.list.join %]" => '2 3', {a => [2, 3]});
-process_ok("[% a.max %]" => '1', {a => [2, 3]});
-process_ok("[% a.merge(5).join %]" => '2 3', {a => [2,3]});
-process_ok("[% a.merge([5]).join %]" => '2 3 5', {a => [2,3]});
-process_ok("[% a.merge([5]).null %][% a.join %]" => '2 3', {a => [2,3]});
-process_ok("[% a.nsort.join %]" => '1 2 3', {a => [2, 3, 1]});
-process_ok("[% a.nsort('b').0.b %]" => '7', {a => [{b => 23}, {b => 7}]});
-process_ok("[% a.pop %][% a.join %]" => '32', {a => [2, 3]});
-process_ok("[% a.push(3) %][% a.join %]" => '2 3 3', {a => [2, 3]});
-process_ok("[% a.pick %]" => qr{ ^[23]$ }x, {a => [2, 3]}) if ! $is_tt;
-process_ok("[% a.pick(5).join('') %]" => qr{ ^[23]{5}$ }x, {a => [2, 3]}) if ! $is_tt;
-process_ok("[% a.reverse.join %]" => '3 2', {a => [2, 3]});
-process_ok("[% a.shift %][% a.join %]" => '23', {a => [2, 3]});
-process_ok("[% a.size %]" => '2', {a => [2, 3]});
-process_ok("[% a.slice.join %]" => '2 3 4 5', {a => [2..5]});
-process_ok("[% a.slice(2).join %]" => '4 5', {a => [2..5]});
-process_ok("[% a.slice(0,2).join %]" => '2 3 4', {a => [2..5]});
-process_ok("[% a.sort.join %]" => '1 2 3', {a => [2, 3, 1]});
-process_ok("[% a.sort('b').0.b %]" => 'wee', {a => [{b => "wow"}, {b => "wee"}]});
-process_ok("[% a.splice.join %]|[% a.join %]" => '2 3 4 5|', {a => [2..5]});
-process_ok("[% a.splice(2).join %]|[% a.join %]" => '4 5|2 3', {a => [2..5]});
-process_ok("[% a.splice(0,2).join %]|[% a.join %]" => '2 3|4 5', {a => [2..5]});
-process_ok("[% a.splice(0,2,'hrm').join %]|[% a.join %]" => '2 3|hrm 4 5', {a => [2..5]});
-process_ok("[% a.unique.join %]" => '2 3', {a => [2,3,3,3,2]});
-process_ok("[% a.unshift(3) %][% a.join %]" => '3 2 3', {a => [2, 3]});
-
-###----------------------------------------------------------------###
-print "### hash vmethods ####################################################\n";
-
-process_ok("[% h.defined %]" => "1", {h => {}});
-process_ok("[% h.defined('a') %]" => "1", {h => {a => 1}});
-process_ok("[% h.defined('b') %]" => "", {h => {a => 1}});
-process_ok("[% h.defined('a') %]" => "", {h => {a => undef}});
-process_ok("[% h.delete('a') %]|[% h.keys.0 %]" => "|b", {h => {a => 1, b=> 2}});
-process_ok("[% h.delete('a', 'b').join %]|[% h.keys.0 %]" => "|", {h => {a => 1, b=> 2}});
-process_ok("[% h.delete('a', 'c').join %]|[% h.keys.0 %]" => "|b", {h => {a => 1, b=> 2}});
-process_ok("[% h.each.sort.join %]" => "1 2 a b", {h => {a => 1, b=> 2}});
-process_ok("[% h.exists('a') %]" => "1", {h => {a => 1}});
-process_ok("[% h.exists('b') %]" => "", {h => {a => 1}});
-process_ok("[% h.exists('a') %]" => "1", {h => {a => undef}});
-process_ok("[% h.fmt %]" => "b\tB\nc\tC", {h => {b => "B", c => "C"}}) if ! $is_tt;
-process_ok("[% h.fmt('%s => %s') %]" => "b => B\nc => C", {h => {b => "B", c => "C"}}) if ! $is_tt;
-process_ok("[% h.fmt('%s => %s', '|') %]" => "b => B|c => C", {h => {b => "B", c => "C"}}) if ! $is_tt;
-process_ok("[% h.fmt('%*s=>%s', '|', 3) %]" => " b=>B| c=>C", {h => {b => "B", c => "C"}}) if ! $is_tt;
-process_ok("[% h.fmt('%*s=>%*s', '|', 3, 4) %]" => " b=> B| c=> C", {h => {b => "B", c => "C"}}) if ! $is_tt;
-process_ok("[% h.hash.fmt %]" => "b\tB\nc\tC", {h => {b => "B", c => "C"}}) if ! $is_tt;
-process_ok("[% h.import('a') %]|[% h.items.sort.join %]" => "|b B c C", {h => {b => "B", c => "C"}});
-process_ok("[% h.import({'b' => 'boo'}) %]|[% h.items.sort.join %]" => "|b boo c C", {h => {b => "B", c => "C"}});
-process_ok("[% h.item('a') %]" => 'A', {h => {a => 'A'}});
-process_ok("[% h.item('_a') %]" => '', {h => {_a => 'A'}}) if ! $is_tt;
-process_ok("[% h.items.sort.join %]" => "1 2 a b", {h => {a => 1, b=> 2}});
-process_ok("[% h.keys.sort.join %]" => "a b", {h => {a => 1, b=> 2}});
-process_ok("[% h.list('each').sort.join %]" => "1 2 a b", {h => {a => 1, b=> 2}});
-process_ok("[% h.list('keys').sort.join %]" => "a b", {h => {a => 1, b=> 2}});
-process_ok("[% h.list('pairs').0.items.sort.join %]" => "1 a key value", {h => {a => 1, b=> 2}});
-process_ok("[% h.list('values').sort.join %]" => "1 2", {h => {a => 1, b=> 2}});
-process_ok("[% h.null %]" => "", {h => {}});
-process_ok("[% h.nsort.join %]" => "b a", {h => {a => 7, b => 2}});
-process_ok("[% h.pairs.0.items.sort.join %]" => "1 a key value", {h => {a => 1, b=> 2}});
-process_ok("[% h.size %]" => "2", {h => {a => 1, b=> 2}});
-process_ok("[% h.sort.join %]" => "b a", {h => {a => "BBB", b => "A"}});
-process_ok("[% h.values.sort.join %]" => "1 2", {h => {a => 1, b=> 2}});
-
-###----------------------------------------------------------------###
-print "### vmethods as functions ############################################\n";
-
-process_ok("[% sprintf('%d %d', 7, 8) %] d" => '7 8 d') if ! $is_tt;
-process_ok("[% sprintf('%d %d', 7, 8) %] d" => '7 8 d', {tt_config => [VMETHOD_FUNCTIONS => 1]}) if ! $is_tt;
-process_ok("[% sprintf('%d %d', 7, 8) %] d" => ' d', {tt_config => [VMETHOD_FUNCTIONS => 0]}) if ! $is_tt;
-process_ok("[% int(2.234) %]" => '2') if ! $is_tt;
-
-process_ok("[% int(2.234) ; int = 44; int(2.234) ; SET int; int(2.234) %]" => '2442') if ! $is_tt; # hide and unhide
-
-###----------------------------------------------------------------###
-print "### more virtual methods / filters ###################################\n";
-
-process_ok("[% [0 .. 10].reverse.1 %]" => 9) if ! $is_tt;
-process_ok("[% {a => 'A'}.a %]" => 'A') if ! $is_tt;
-process_ok("[% 'This is a string'.length %]" => 16) if ! $is_tt;
-process_ok("[% 123.length %]" => 3) if ! $is_tt;
-process_ok("[% 123.2.length %]" => 5) if ! $is_tt;
-process_ok("[% -123.2.length %]" => -5) if ! $is_tt; # the - doesn't bind as tight as the dot methods
-process_ok("[% (-123.2).length %]" => 6) if ! $is_tt;
-process_ok("[% a = 23; a.0 %]" => 23) if ! $is_tt; # '0' is a scalar_op
-process_ok('[% 1.rand %]' => qr/^0\.\d+(?:e-?\d+)?$/) if ! $is_tt;
-
-process_ok("[% n.size %]", => 'SIZE', {n => {size => 'SIZE', a => 'A'}});
-process_ok("[% n|size %]", => '2', {n => {size => 'SIZE', a => 'A'}}) if ! $is_tt; # tt2 | is alias for FILTER
-
-process_ok('[% foo | eval %]' => 'baz', {foo => '[% bar %]', bar => 'baz'});
-process_ok('[% "1" | indent(2) %]' => ' 1');
-
-
-process_ok("[% n FILTER size %]", => '1', {n => {size => 'SIZE', a => 'A'}}) if ! $is_tt; # tt2 doesn't have size
-
-process_ok("[% n FILTER repeat %]" => '1', {n => 1});
-process_ok("[% n FILTER repeat(0) %]" => '', {n => 1});
-process_ok("[% n FILTER repeat(1) %]" => '1', {n => 1});
-process_ok("[% n FILTER repeat(2) %]" => '11', {n => 1});
-process_ok("[% n FILTER repeat(2,'|') %]" => '1|1', {n => 1}) if ! $is_tt;
-
-process_ok("[% n FILTER echo = repeat(2) %][% n FILTER echo %]" => '1111', {n => 1});
-process_ok("[% n FILTER echo = repeat(2) %][% n | echo %]" => '1111', {n => 1});
-process_ok("[% n FILTER echo = repeat(2) %][% n|echo.length %]" => '112', {n => 1}) if ! $is_tt;
-process_ok("[% n FILTER echo = repeat(2) %][% n FILTER \$foo %]" => '1111', {n => 1, foo => 'echo'});
-process_ok("[% n FILTER echo = repeat(2) %][% n | \$foo %]" => '1111', {n => 1, foo => 'echo'});
-process_ok("[% n FILTER echo = repeat(2) %][% n|\$foo.length %]" => '112', {n => 1, foo => 'echo'}) if ! $is_tt;
-
-process_ok('[% "hi" FILTER $foo %]' => 'hihi', {foo => sub {sub {$_[0]x2}}}); # filter via a passed var
-process_ok('[% FILTER $foo %]hi[% END %]' => 'hihi', {foo => sub {sub {$_[0]x2}}}); # filter via a passed var
-process_ok('[% "hi" FILTER foo %]' => 'hihi', {tt_config => [FILTERS => {foo => sub {$_[0]x2}}]});
-process_ok('[% "hi" FILTER foo %]' => 'hihi', {tt_config => [FILTERS => {foo => [sub {$_[0]x2},0]}]});
-process_ok('[% "hi" FILTER foo(2) %]' => 'hihi', {tt_config => [FILTERS => {foo => [sub {my$a=$_[1];sub{$_[0]x$a}},1]}]});
-
-process_ok('[% ["a".."z"].pick %]' => qr/^[a-z]/) if ! $is_tt;
-
-process_ok("[% ' ' | uri %]" => '%20');
-
-process_ok('[% "one".fmt %]' => "one") if ! $is_tt;
-process_ok('[% 2.fmt("%02d") %]' => "02") if ! $is_tt;
-
-process_ok('[% [1..3].fmt %]' => "1 2 3") if ! $is_tt;
-process_ok('[% [1..3].fmt("%02d") %]' => '01 02 03') if ! $is_tt;
-process_ok('[% [1..3].fmt("%s", ", ") %]' => '1, 2, 3') if ! $is_tt;
-
-process_ok('[% {a => "B", c => "D"}.fmt %]' => "a\tB\nc\tD") if ! $is_tt;
-process_ok('[% {a => "B", c => "D"}.fmt("%s:%s") %]' => "a:B\nc:D") if ! $is_tt;
-process_ok('[% {a => "B", c => "D"}.fmt("%s:%s", "; ") %]' => "a:B; c:D") if ! $is_tt;
-
-process_ok('[% 1|format("%s") %]' => '1') if ! $is_tt;
-process_ok('[% 1|format("%*s", 6) %]' => ' 1') if ! $is_tt;
-process_ok('[% 1|format("%-*s", 6) %]' => '1 ') if ! $is_tt;
-
-process_ok('[% 1.fmt("%-*s", 6) %]' => '1 ') if ! $is_tt;
-process_ok('[% [1,2].fmt("%-*s", "|", 6) %]' => '1 |2 ') if ! $is_tt;
-process_ok('[% {1=>2,3=>4}.fmt("%*s:%*s", "|", 3, 3) %]' => ' 1: 2| 3: 4') if ! $is_tt;
-
-###----------------------------------------------------------------###
-print "### virtual objects ##################################################\n";
-
-process_ok('[% a = "foobar" %][% Text.length(a) %]' => 6) if ! $is_tt;
-process_ok('[% a = [1 .. 10] %][% List.size(a) %]' => 10) if ! $is_tt;
-process_ok('[% a = {a=>"A", b=>"B"} ; Hash.size(a) %]' => 2) if ! $is_tt;
-
-process_ok('[% a = Text.new("This is a string") %][% a.length %]' => 16) if ! $is_tt;
-process_ok('[% a = List.new("one", "two", "three") %][% a.size %]' => 3) if ! $is_tt;
-process_ok('[% a = Hash.new("one", "ONE") %][% a.one %]' => 'ONE') if ! $is_tt;
-process_ok('[% a = Hash.new(one = "ONE") %][% a.one %]' => 'ONE') if ! $is_tt;
-process_ok('[% a = Hash.new(one => "ONE") %][% a.one %]' => 'ONE') if ! $is_tt;
-
-process_ok('[% {a => 1, b => 2} | Hash.keys | List.join(", ") %]' => 'a, b') if ! $is_tt;
-
-###----------------------------------------------------------------###
-print "### chomping #########################################################\n";
-
-process_ok(" [% foo %]" => ' ');
-process_ok(" [%- foo %]" => '');
-process_ok("\n[%- foo %]" => '');
-process_ok("\n [%- foo %]" => '');
-process_ok("\n\n[%- foo %]" => "\n");
-process_ok(" \n\n[%- foo %]" => " \n");
-process_ok(" \n[%- foo %]" => " ") if ! $is_tt;
-process_ok(" \n \n[%- foo %]" => " \n ") if ! $is_tt;
-
-process_ok("[% 7 %] " => '7 ');
-process_ok("[% 7 -%] " => '7 ');
-process_ok("[% 7 -%]\n" => '7');
-process_ok("[% 7 -%] \n" => '7');
-process_ok("[% 7 -%]\n " => '7 ');
-process_ok("[% 7 -%]\n\n\n" => "7\n\n");
-process_ok("[% 7 -%] \n " => '7 ');
-
-###----------------------------------------------------------------###
-print "### string operators #################################################\n";
-
-process_ok('[% a = "foo"; a _ "bar" %]' => 'foobar');
-process_ok('[% a = "foo"; a ~ "bar" %]' => 'foobar') if ! $is_tt;
-process_ok('[% a = "foo"; a ~= "bar"; a %]' => 'foobar') if ! $is_tt;
-process_ok('[% "b" gt "c" %]<<<' => '<<<') if ! $is_tt;
-process_ok('[% "b" gt "a" %]<<<' => '1<<<') if ! $is_tt;
-process_ok('[% "b" ge "c" %]<<<' => '<<<') if ! $is_tt;
-process_ok('[% "b" ge "b" %]<<<' => '1<<<') if ! $is_tt;
-process_ok('[% "b" lt "c" %]<<<' => '1<<<') if ! $is_tt;
-process_ok('[% "b" lt "a" %]<<<' => '<<<') if ! $is_tt;
-process_ok('[% "b" le "a" %]<<<' => '<<<') if ! $is_tt;
-process_ok('[% "b" le "b" %]<<<' => '1<<<') if ! $is_tt;
-process_ok('[% "a" cmp "b" %]<<<' => '-1<<<') if ! $is_tt;
-process_ok('[% "b" cmp "b" %]<<<' => '0<<<') if ! $is_tt;
-process_ok('[% "c" cmp "b" %]<<<' => '1<<<') if ! $is_tt;
-
-###----------------------------------------------------------------###
-print "### math operators ###################################################\n";
-
-process_ok("[% 1 + 2 %]" => 3);
-process_ok("[% 1 + 2 + 3 %]" => 6);
-process_ok("[% (1 + 2) %]" => 3);
-process_ok("[% 2 - 1 %]" => 1);
-process_ok("[% -1 + 2 %]" => 1);
-process_ok("[% -1+2 %]" => 1);
-process_ok("[% 2 - 1 %]" => 1);
-process_ok("[% 2-1 %]" => 1) if ! $is_tt;
-process_ok("[% 2 - -1 %]" => 3);
-process_ok("[% 4 * 2 %]" => 8);
-process_ok("[% 4 / 2 %]" => 2);
-process_ok("[% 10 / 3 %]" => qr/^3.333/);
-process_ok("[% 10 div 3 %]" => '3');
-process_ok("[% 2 ** 3 %]" => 8) if ! $is_tt;
-process_ok("[% 1 + 2 * 3 %]" => 7);
-process_ok("[% 3 * 2 + 1 %]" => 7);
-process_ok("[% (1 + 2) * 3 %]" => 9);
-process_ok("[% 3 * (1 + 2) %]" => 9);
-process_ok("[% 1 + 2 ** 3 %]" => 9) if ! $is_tt;
-process_ok("[% 2 * 2 ** 3 %]" => 16) if ! $is_tt;
-process_ok("[% SET foo = 1 %][% foo + 2 %]" => 3);
-process_ok("[% SET foo = 1 %][% (foo + 2) %]" => 3);
-
-process_ok("[% a = 1; (a += 2) %]" => 3) if ! $is_tt;
-process_ok("[% a = 1; (a -= 2) %]" => -1) if ! $is_tt;
-process_ok("[% a = 4; (a /= 2) %]" => 2) if ! $is_tt;
-process_ok("[% a = 1; (a *= 2) %]" => 2) if ! $is_tt;
-process_ok("[% a = 3; (a **= 2) %]" => 9) if ! $is_tt;
-process_ok("[% a = 1; (a %= 2) %]" => 1) if ! $is_tt;
-
-process_ok('[% a += 1 %]-[% a %]-[% a += 1 %]-[% a %]' => '-1--2') if ! $is_tt;
-process_ok('[% (a += 1) %]-[% (a += 1) %]' => '1-2') if ! $is_tt;
-
-process_ok('[% a = 2; a -= 3; a %]' => '-1') if ! $is_tt;
-process_ok('[% a = 2; a *= 3; a %]' => '6') if ! $is_tt;
-process_ok('[% a = 2; a /= .5; a %]' => '4') if ! $is_tt;
-process_ok('[% a = 8; a %= 3; a %]' => '2') if ! $is_tt;
-process_ok('[% a = 2; a **= 3; a %]' => '8') if ! $is_tt;
-
-process_ok('[% a = 1 %][% ++a %][% a %]' => '22') if ! $is_tt;
-process_ok('[% a = 1 %][% a++ %][% a %]' => '12') if ! $is_tt;
-process_ok('[% a = 1 %][% --a %][% a %]' => '00') if ! $is_tt;
-process_ok('[% a = 1 %][% a-- %][% a %]' => '10') if ! $is_tt;
-process_ok('[% a++ FOR [1..3] %]' => '012') if ! $is_tt;
-process_ok('[% --a FOR [1..3] %]' => '-1-2-3') if ! $is_tt;
-
-process_ok('[% 2 > 3 %]<<<' => '<<<');
-process_ok('[% 2 > 1 %]<<<' => '1<<<');
-process_ok('[% 2 >= 3 %]<<<' => '<<<');
-process_ok('[% 2 >= 2 %]<<<' => '1<<<');
-process_ok('[% 2 < 3 %]<<<' => '1<<<');
-process_ok('[% 2 < 1 %]<<<' => '<<<');
-process_ok('[% 2 <= 1 %]<<<' => '<<<');
-process_ok('[% 2 <= 2 %]<<<' => '1<<<');
-process_ok('[% 1 <=> 2 %]<<<' => '-1<<<') if ! $is_tt;
-process_ok('[% 2 <=> 2 %]<<<' => '0<<<') if ! $is_tt;
-process_ok('[% 3 <=> 2 %]<<<' => '1<<<') if ! $is_tt;
-
-###----------------------------------------------------------------###
-print "### boolean operators ################################################\n";
-
-process_ok("[% 5 && 6 %]" => 6);
-process_ok("[% 5 || 6 %]" => 5);
-process_ok("[% 0 || 6 %]" => 6);
-process_ok("[% 0 && 6 %]" => 0);
-process_ok("[% 0 && 0 %]" => 0);
-process_ok("[% 5 && 6 && 7%]" => 7);
-process_ok("[% 0 || 1 || 2 %]" => 1);
-
-process_ok("[% 5 + (0 || 5) %]" => 10);
-
-
-process_ok("[% 1 ? 2 : 3 %]" => '2');
-process_ok("[% 0 ? 2 : 3 %]" => '3');
-process_ok("[% 0 ? (1 ? 2 : 3) : 4 %]" => '4');
-process_ok("[% 0 ? 1 ? 2 : 3 : 4 %]" => '4');
-
-process_ok("[% t = 1 || 0 ? 3 : 4 %][% t %]" => 3);
-process_ok("[% t = 0 or 1 ? 3 : 4 %][% t %]" => 3);
-process_ok("[% t = 1 or 0 ? 3 : 4 %][% t %]" => 1) if ! $is_tt;
-
-process_ok("[% 0 ? 2 : 3 %]" => '3');
-process_ok("[% 1 ? 2 : 3 %]" => '2');
-process_ok("[% 0 ? 1 ? 2 : 3 : 4 %]" => '4');
-process_ok("[% t = 0 ? 1 ? [1..4] : [2..4] : [3..4] %][% t.0 %]" => '3');
-process_ok("[% t = 1 || 0 ? 0 : 1 || 2 ? 2 : 3 %][% t %]" => '0');
-process_ok("[% t = 0 or 0 ? 0 : 1 or 2 ? 2 : 3 %][% t %]" => '1') if ! $is_tt;
-process_ok("[% t = 0 or 0 ? 0 : 0 or 2 ? 2 : 3 %][% t %]" => '2');
-
-process_ok("[% 0 ? 1 ? 1 + 2 * 3 : 1 + 2 * 4 : 1 + 2 * 5 %]" => '11');
-
-###----------------------------------------------------------------###
-print "### regex ############################################################\n";
-
-process_ok("[% /foo/ %]" => '(?-xism:foo)') if ! $is_tt;
-process_ok("[% /foo %]" => '') if ! $is_tt;
-process_ok("[% /foo/x %]" => '(?-xism:(?x:foo))') if ! $is_tt;
-process_ok("[% /foo/xi %]" => '(?-xism:(?xi:foo))') if ! $is_tt;
-process_ok("[% /foo/xis %]" => '(?-xism:(?xis:foo))') if ! $is_tt;
-process_ok("[% /foo/xism %]" => '(?-xism:(?xism:foo))') if ! $is_tt;
-process_ok("[% /foo/e %]" => '') if ! $is_tt;
-process_ok("[% /foo/g %]" => '') if ! $is_tt;
-process_ok("[% /foo %]" => '') if ! $is_tt;
-process_ok("[% /foo**/ %]" => '') if ! $is_tt;
-process_ok("[% /fo\\/o/ %]" => '(?-xism:fo/o)') if ! $is_tt;
-process_ok("[% 'foobar'.match(/(f\\w\\w)/).0 %]" => 'foo') if ! $is_tt;
-
-###----------------------------------------------------------------###
-print "### BLOCK / PROCESS / INCLUDE#########################################\n";
-
-process_ok("[% PROCESS foo %]one" => '');
-process_ok("[% BLOCK foo %]one" => '');
-process_ok("[% BLOCK foo %][% END %]one" => 'one');
-process_ok("[% BLOCK %][% END %]one" => 'one');
-process_ok("[% BLOCK foo %]hi there[% END %]one" => 'one');
-process_ok("[% BLOCK foo %][% BLOCK foo %][% END %][% END %]" => '');
-process_ok("[% BLOCK foo %]hi there[% END %][% PROCESS foo %]" => 'hi there');
-process_ok("[% PROCESS foo %][% BLOCK foo %]hi there[% END %]" => 'hi there');
-process_ok("[% BLOCK foo %]hi there[% END %][% PROCESS foo foo %]" => 'hi therehi there') if ! $is_tt;
-process_ok("[% BLOCK foo %]hi there[% END %][% PROCESS foo, foo %]" => 'hi therehi there') if ! $is_tt;
-process_ok("[% BLOCK foo %]hi there[% END %][% PROCESS foo + foo %]" => 'hi therehi there');
-process_ok("[% BLOCK foo %]hi [% one %] there[% END %][% PROCESS foo %]" => 'hi ONE there', {one => 'ONE'});
-process_ok("[% BLOCK foo %]hi [% IF 1 %]Yes[% END %] there[% END %]<<[% PROCESS foo %]>>" => '<<hi Yes there>>');
-process_ok("[% BLOCK foo %]hi [% one %] there[% END %][% PROCESS foo one = 'two' %]" => 'hi two there');
-process_ok("[% BLOCK foo %]hi [% one.two %] there[% END %][% PROCESS foo one.two = 'two' %]" => 'hi two there');
-process_ok("[% BLOCK foo %]hi [% one.two %] there[% END %][% PROCESS foo + foo one.two = 'two' %]" => 'hi two there'x2);
-process_ok("[% BLOCK foo %][% BLOCK bar %]hi [% one %] there[% END %][% END %][% PROCESS foo/bar one => 'two' %]" => 'hi two there');
-
-process_ok("[% BLOCK foo %]hi [% one %] there[% END %][% PROCESS foo one = 'two' %][% one %]" => 'hi two theretwo');
-process_ok("[% BLOCK foo %]hi [% one %] there[% END %][% INCLUDE foo one = 'two' %][% one %]" => 'hi two there');
-
-###----------------------------------------------------------------###
-print "### IF / UNLESS / ELSIF / ELSE #######################################\n";
-
-process_ok("[% IF 1 %]Yes[% END %]" => 'Yes');
-process_ok("[% IF 0 %]Yes[% END %]" => '');
-process_ok("[% IF 0 %]Yes[% ELSE %]No[% END %]" => 'No');
-process_ok("[% IF 0 %]Yes[% ELSIF 1 %]No[% END %]" => 'No');
-process_ok("[% IF 0 %]Yes[% ELSIF 0 %]No[% END %]" => '');
-process_ok("[% IF 0 %]Yes[% ELSIF 0 %]No[% ELSE %]hmm[% END %]" => 'hmm');
-
-process_ok("[% UNLESS 1 %]Yes[% END %]" => '');
-process_ok("[% UNLESS 0 %]Yes[% END %]" => 'Yes');
-process_ok("[% UNLESS 0 %]Yes[% ELSE %]No[% END %]" => 'Yes');
-process_ok("[% UNLESS 1 %]Yes[% ELSIF 1 %]No[% END %]" => 'No');
-process_ok("[% UNLESS 1 %]Yes[% ELSIF 0 %]No[% END %]" => '');
-process_ok("[% UNLESS 1 %]Yes[% ELSIF 0 %]No[% ELSE %]hmm[% END %]" => 'hmm');
-
-###----------------------------------------------------------------###
-print "### comments #########################################################\n";
-
-process_ok("[%# one %]" => '', {one => 'ONE'});
-process_ok("[%#\n one %]" => '', {one => 'ONE'});
-process_ok("[%-#\n one %]" => '', {one => 'ONE'}) if ! $is_tt;
-process_ok("[% #\n one %]" => 'ONE', {one => 'ONE'});
-process_ok("[%# BLOCK one %]" => '');
-process_ok("[%# BLOCK one %]two" => 'two');
-process_ok("[%# BLOCK one %]two[% END %]" => '');
-process_ok("[%# BLOCK one %]two[% END %]three" => '');
-process_ok("[%
-#
--%]
-foo" => "foo");
-
-###----------------------------------------------------------------###
-print "### FOREACH / NEXT / LAST ############################################\n";
-
-process_ok("[% FOREACH foo %]" => '');
-process_ok("[% FOREACH foo %][% END %]" => '');
-process_ok("[% FOREACH foo %]bar[% END %]" => '');
-process_ok("[% FOREACH foo %]bar[% END %]" => 'bar', {foo => 1});
-process_ok("[% FOREACH f IN foo %]bar[% f %][% END %]" => 'bar1bar2', {foo => [1,2]});
-process_ok("[% FOREACH f = foo %]bar[% f %][% END %]" => 'bar1bar2', {foo => [1,2]});
-process_ok("[% FOREACH f = [1,2] %]bar[% f %][% END %]" => 'bar1bar2');
-process_ok("[% FOREACH f = [1..3] %]bar[% f %][% END %]" => 'bar1bar2bar3');
-process_ok("[% FOREACH f = [{a=>'A'},{a=>'B'}] %]bar[% f.a %][% END %]" => 'barAbarB');
-process_ok("[% FOREACH [{a=>'A'},{a=>'B'}] %]bar[% a %][% END %]" => 'barAbarB');
-process_ok("[% FOREACH [{a=>'A'},{a=>'B'}] %]bar[% a %][% END %][% a %]" => 'barAbarB');
-process_ok("[% FOREACH f = [1..3] %][% loop.count %]/[% loop.size %] [% END %]" => '1/3 2/3 3/3 ');
-process_ok("[% FOREACH f = [1..3] %][% IF loop.first %][% f %][% END %][% END %]" => '1');
-process_ok("[% FOREACH f = [1..3] %][% IF loop.last %][% f %][% END %][% END %]" => '3');
-process_ok("[% FOREACH f = [1..3] %][% IF loop.first %][% NEXT %][% END %][% f %][% END %]" => '23');
-process_ok("[% FOREACH f = [1..3] %][% IF loop.first %][% LAST %][% END %][% f %][% END %]" => '');
-process_ok("[% FOREACH f = [1..3] %][% f %][% IF loop.first %][% NEXT %][% END %][% END %]" => '123');
-process_ok("[% FOREACH f = [1..3] %][% f %][% IF loop.first %][% LAST %][% END %][% END %]" => '1');
-
-process_ok('[% a = ["Red", "Blue"] ; FOR [0..3] ; a.${ loop.index % a.size } ; END %]' => 'RedBlueRedBlue') if ! $is_tt;
-
-### TT is not consistent in what is localized - well it is documented
-### if you set a variable in the FOREACH tag, then nothing in the loop gets localized
-### if you don't set a variable - everything gets localized
-process_ok("[% foo = 1 %][% FOREACH [1..10] %][% foo %][% foo = 2 %][% END %]" => '1222222222');
-process_ok("[% f = 1 %][% FOREACH i = [1..10] %][% i %][% f = 2 %][% END %][% f %]" => '123456789102');
-process_ok("[% f = 1 %][% FOREACH [1..10] %][% f = 2 %][% END %][% f %]" => '1');
-process_ok("[% f = 1 %][% FOREACH f = [1..10] %][% f %][% END %][% f %]" => '1234567891010');
-process_ok("[% FOREACH [1] %][% SET a = 1 %][% END %][% a %]" => '');
-process_ok("[% a %][% FOREACH [1] %][% SET a = 1 %][% END %][% a %]" => '');
-process_ok("[% a = 2 %][% FOREACH [1] %][% SET a = 1 %][% END %][% a %]" => '2');
-process_ok("[% a = 2 %][% FOREACH [1] %][% a = 1 %][% END %][% a %]" => '2');
-process_ok("[% a = 2 %][% FOREACH i = [1] %][% a = 1 %][% END %][% a %]" => '1');
-process_ok("[% FOREACH i = [1] %][% SET a = 1 %][% END %][% a %]" => '1');
-process_ok("[% f.b = 1 %][% FOREACH f.b = [1..10] %][% f.b %][% END %][% f.b %]" => '1234567891010') if ! $is_tt;
-process_ok("[% a = 1 %][% FOREACH [{a=>'A'},{a=>'B'}] %]bar[% a %][% END %][% a %]" => 'barAbarB1');
-process_ok("[% FOREACH [1..3] %][% loop.size %][% END %][% loop.size %]" => '333');
-process_ok("[% FOREACH i = [1..3] %][% loop.size %][% END %][% loop.size %]" => '333') if ! $is_tt;
-process_ok("[% FOREACH i = [1..3] %][% loop.size %][% END %][% loop.size %]" => '3331') if $is_tt;
-
-process_ok('[% FOREACH f = [1..3]; 1; END %]' => '111');
-process_ok('[% FOREACH f = [1..3]; f; END %]' => '123');
-process_ok('[% FOREACH f = [1..3]; "$f"; END %]' => '123');
-process_ok('[% FOREACH f = [1..3]; f + 1; END %]' => '234');