#!perl -w use strict; use Test::More; use Text::Xslate; my $tx = Text::Xslate->new(); my @data = ( ['Hello, : for $types -> ($type) { [<:= $type :>] : } world!' => "Hello,\n[Str]\n[Int]\n[Object]\nworld!"], ['Hello, :for$types->($type){ [<:=$type:>] :} world!' => "Hello,\n[Str]\n[Int]\n[Object]\nworld!"], ['Hello, : for $types -> ($type) { := $type : } world!' => "Hello,\nStrIntObjectworld!"], ['<< : for $types -> ($t1) { : for $types -> ($t2) { [<:=$t1:>|<:=$t2:>] : } : } >>', "<< [Str|Str] [Str|Int] [Str|Object] [Int|Str] [Int|Int] [Int|Object] [Object|Str] [Object|Int] [Object|Object] >>", "nested"], ['<< : for $types -> ($t1) { [<:=$t1:>] : } | : for $types -> ($t1) { [<:=$t1:>] : } >>', "<< [Str] [Int] [Object] | [Str] [Int] [Object] >>"], ['<< : for $types -> ($lang) { [<:=$lang:>] : } >> <:=$lang:>', "<< [Str] [Int] [Object] >> Xslate"], ['<< : for $Types -> ($t) { [<:=$t.name:>] : } >>', "<< [Void] [Bool] >>"], ['<< : for $empty -> ($t) { [<:=$t.name:>] : } >>', "<< >>"], [<<'T', <<'X'], : macro foo -> $x { : for $x -> ($item) { <: $item :> : } : } : for $data -> ($item) { : foo($item) : } T Perl X [<<'T', <<'X'], : for $types -> ($item) { <: $~item :> : } T 0 1 2 X # iterators [<<'T', <<'X'], : for $types -> $item { : if (($~item+1) % 2) == 0 { Even : } : else { Odd : } : } T Odd Even Odd X [<<'T', <<'X'], : for $types -> ($item) { <: $~item.index :> : } T 0 1 2 X [<<'T', <<'X'], : for $types -> ($item) { <: $~item.count :> : } T 1 2 3 X [<<'T', <<'X', 'is_first && is_last'], : for $types -> ($item) { : if $~item.is_first { ---- first ---- : } <: $~item.count :> : if $~item.is_last { ---- last ---- : } : } T ---- first ---- 1 2 3 ---- last ---- X [<<'T', <<'X', 'size'], : for $types -> ($item) { <: $~item.size :> : } T 3 3 3 X [<<'T', <<'X', 'max_index'], : for $types -> ($item) { <: $~item.max_index :> : } T 2 2 2 X [<<'T', <<'X', 'body'], : for $types -> ($item) { <: $~item.body[ $~item.index ] :> : } T Str Int Object X [<<'T', <<'X', 'peek_next'], : for $types -> ($item) { <: $~item.peek_next // "(none)" :> : } T Int Object (none) X [<<'T', <<'X', 'peek_prev'], : for $types -> ($item) { <: $~item.peek_prev // "(none)" :> : } T (none) Str Int X [<<'T', <<'X', 'cycle'], : for [1, 2, 3, 4] -> ($item) { <: $~item.cycle("foo", "bar") :> : } T foo bar foo bar X [<<'T', <<'X', 'cycle'], : for [1, 2, 3, 4, 5, 6, 7, 8, 9] -> ($item) { <: $~item.cycle("foo", "bar", "baz") :> : } T foo bar baz foo bar baz foo bar baz X [<<'T', <<'X', 'cycle'], : for [1, 2, 3, 4] -> ($item) { <: $~item.cycle("foo", "bar", "baz") :> : } ------- : for [1, 2, 3, 4] -> ($item) { <: $~item.cycle("FOO", "BAR", "BAZ") :> : } T foo bar baz foo ------- FOO BAR BAZ FOO X [<<'T', <<'X', 'nested $~i'], : for $types -> $i { : for $types -> $j { [<: $~i.index :>][<: $~j.count :>] : } : } T [0][1] [0][2] [0][3] [1][1] [1][2] [1][3] [2][1] [2][2] [2][3] X [<<'T', <<'X', 'nested $~i.cycle()'], : for $types -> $i { : for $types -> $j { [<: $~i.cycle("a", "b") :>][<: $~j.cycle("c", "d", "e") :>] : } : } T [a][c] [a][d] [a][e] [b][c] [b][d] [b][e] [a][c] [a][d] [a][e] X ); my %vars = ( lang => 'Xslate', types => [qw(Str Int Object)], Types => [{ name => 'Void' }, { name => 'Bool' }], empty => [], data => [[qw(Perl)]], ); foreach my $pair(@data) { my($in, $out, $msg) = @$pair; is $tx->render_string($in, \%vars), $out, $msg or do { diag($in); my $code = $tx->compile($in); diag("// assembly"); diag($tx->_compiler->as_assembly($code)); }; } done_testing;