summaryrefslogtreecommitdiff
path: root/tests/examplefiles/twig_test
diff options
context:
space:
mode:
Diffstat (limited to 'tests/examplefiles/twig_test')
-rw-r--r--tests/examplefiles/twig_test4612
1 files changed, 0 insertions, 4612 deletions
diff --git a/tests/examplefiles/twig_test b/tests/examplefiles/twig_test
deleted file mode 100644
index 0932fe90..00000000
--- a/tests/examplefiles/twig_test
+++ /dev/null
@@ -1,4612 +0,0 @@
-From the Twig test suite, https://github.com/fabpot/Twig, available under BSD license.
-
---TEST--
-Exception for an unclosed tag
---TEMPLATE--
-{% block foo %}
- {% if foo %}
-
-
-
-
- {% for i in fo %}
-
-
-
- {% endfor %}
-
-
-
-{% endblock %}
---EXCEPTION--
-Twig_Error_Syntax: Unexpected tag name "endblock" (expecting closing tag for the "if" tag defined near line 4) in "index.twig" at line 16
---TEST--
-Exception for an undefined trait
---TEMPLATE--
-{% use 'foo' with foobar as bar %}
---TEMPLATE(foo)--
-{% block bar %}
-{% endblock %}
---EXCEPTION--
-Twig_Error_Runtime: Block "foobar" is not defined in trait "foo" in "index.twig".
---TEST--
-Twig supports method calls
---TEMPLATE--
-{{ items.foo }}
-{{ items['foo'] }}
-{{ items[foo] }}
-{{ items[items[foo]] }}
---DATA--
-return array('foo' => 'bar', 'items' => array('foo' => 'bar', 'bar' => 'foo'))
---EXPECT--
-bar
-bar
-foo
-bar
---TEST--
-Twig supports array notation
---TEMPLATE--
-{# empty array #}
-{{ []|join(',') }}
-
-{{ [1, 2]|join(',') }}
-{{ ['foo', "bar"]|join(',') }}
-{{ {0: 1, 'foo': 'bar'}|join(',') }}
-{{ {0: 1, 'foo': 'bar'}|keys|join(',') }}
-
-{{ {0: 1, foo: 'bar'}|join(',') }}
-{{ {0: 1, foo: 'bar'}|keys|join(',') }}
-
-{# nested arrays #}
-{% set a = [1, 2, [1, 2], {'foo': {'foo': 'bar'}}] %}
-{{ a[2]|join(',') }}
-{{ a[3]["foo"]|join(',') }}
-
-{# works even if [] is used inside the array #}
-{{ [foo[bar]]|join(',') }}
-
-{# elements can be any expression #}
-{{ ['foo'|upper, bar|upper, bar == foo]|join(',') }}
-
-{# arrays can have a trailing , like in PHP #}
-{{
- [
- 1,
- 2,
- ]|join(',')
-}}
-
-{# keys can be any expression #}
-{% set a = 1 %}
-{% set b = "foo" %}
-{% set ary = { (a): 'a', (b): 'b', 'c': 'c', (a ~ b): 'd' } %}
-{{ ary|keys|join(',') }}
-{{ ary|join(',') }}
---DATA--
-return array('bar' => 'bar', 'foo' => array('bar' => 'bar'))
---EXPECT--
-1,2
-foo,bar
-1,bar
-0,foo
-
-1,bar
-0,foo
-
-1,2
-bar
-
-bar
-
-FOO,BAR,
-
-1,2
-
-1,foo,c,1foo
-a,b,c,d
---TEST--
-Twig supports binary operations (+, -, *, /, ~, %, and, or)
---TEMPLATE--
-{{ 1 + 1 }}
-{{ 2 - 1 }}
-{{ 2 * 2 }}
-{{ 2 / 2 }}
-{{ 3 % 2 }}
-{{ 1 and 1 }}
-{{ 1 and 0 }}
-{{ 0 and 1 }}
-{{ 0 and 0 }}
-{{ 1 or 1 }}
-{{ 1 or 0 }}
-{{ 0 or 1 }}
-{{ 0 or 0 }}
-{{ 0 or 1 and 0 }}
-{{ 1 or 0 and 1 }}
-{{ "foo" ~ "bar" }}
-{{ foo ~ "bar" }}
-{{ "foo" ~ bar }}
-{{ foo ~ bar }}
-{{ 20 // 7 }}
---DATA--
-return array('foo' => 'bar', 'bar' => 'foo')
---EXPECT--
-2
-1
-4
-1
-1
-1
-
-
-
-1
-1
-1
-
-
-1
-foobar
-barbar
-foofoo
-barfoo
-2
---TEST--
-Twig supports bitwise operations
---TEMPLATE--
-{{ 1 b-and 5 }}
-{{ 1 b-or 5 }}
-{{ 1 b-xor 5 }}
-{{ (1 and 0 b-or 0) is same as(1 and (0 b-or 0)) ? 'ok' : 'ko' }}
---DATA--
-return array()
---EXPECT--
-1
-5
-4
-ok
---TEST--
-Twig supports comparison operators (==, !=, <, >, >=, <=)
---TEMPLATE--
-{{ 1 > 2 }}/{{ 1 > 1 }}/{{ 1 >= 2 }}/{{ 1 >= 1 }}
-{{ 1 < 2 }}/{{ 1 < 1 }}/{{ 1 <= 2 }}/{{ 1 <= 1 }}
-{{ 1 == 1 }}/{{ 1 == 2 }}
-{{ 1 != 1 }}/{{ 1 != 2 }}
---DATA--
-return array()
---EXPECT--
-///1
-1//1/1
-1/
-/1
---TEST--
-Twig supports the "divisible by" operator
---TEMPLATE--
-{{ 8 is divisible by(2) ? 'OK' }}
-{{ 8 is not divisible by(3) ? 'OK' }}
-{{ 8 is divisible by (2) ? 'OK' }}
-{{ 8 is not
- divisible
- by
- (3) ? 'OK' }}
---DATA--
-return array()
---EXPECT--
-OK
-OK
-OK
-OK
---TEST--
-Twig supports the .. operator
---TEMPLATE--
-{% for i in 0..10 %}{{ i }} {% endfor %}
-
-{% for letter in 'a'..'z' %}{{ letter }} {% endfor %}
-
-{% for letter in 'a'|upper..'z'|upper %}{{ letter }} {% endfor %}
-
-{% for i in foo[0]..foo[1] %}{{ i }} {% endfor %}
-
-{% for i in 0 + 1 .. 10 - 1 %}{{ i }} {% endfor %}
---DATA--
-return array('foo' => array(1, 10))
---EXPECT--
-0 1 2 3 4 5 6 7 8 9 10
-a b c d e f g h i j k l m n o p q r s t u v w x y z
-A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
-1 2 3 4 5 6 7 8 9 10
-1 2 3 4 5 6 7 8 9
---TEST--
-Twig supports the "ends with" operator
---TEMPLATE--
-{{ 'foo' ends with 'o' ? 'OK' : 'KO' }}
-{{ not ('foo' ends with 'f') ? 'OK' : 'KO' }}
-{{ not ('foo' ends with 'foowaytoolong') ? 'OK' : 'KO' }}
-{{ 'foo' ends with '' ? 'OK' : 'KO' }}
-{{ '1' ends with true ? 'OK' : 'KO' }}
-{{ 1 ends with true ? 'OK' : 'KO' }}
-{{ 0 ends with false ? 'OK' : 'KO' }}
-{{ '' ends with false ? 'OK' : 'KO' }}
-{{ false ends with false ? 'OK' : 'KO' }}
-{{ false ends with '' ? 'OK' : 'KO' }}
---DATA--
-return array()
---EXPECT--
-OK
-OK
-OK
-OK
-KO
-KO
-KO
-KO
-KO
-KO
---TEST--
-Twig supports grouping of expressions
---TEMPLATE--
-{{ (2 + 2) / 2 }}
---DATA--
-return array()
---EXPECT--
-2
---TEST--
-Twig supports literals
---TEMPLATE--
-1 {{ true }}
-2 {{ TRUE }}
-3 {{ false }}
-4 {{ FALSE }}
-5 {{ none }}
-6 {{ NONE }}
-7 {{ null }}
-8 {{ NULL }}
---DATA--
-return array()
---EXPECT--
-1 1
-2 1
-3
-4
-5
-6
-7
-8
---TEST--
-Twig supports __call() for attributes
---TEMPLATE--
-{{ foo.foo }}
-{{ foo.bar }}
---EXPECT--
-foo_from_call
-bar_from_getbar
---TEST--
-Twig supports the "matches" operator
---TEMPLATE--
-{{ 'foo' matches '/o/' ? 'OK' : 'KO' }}
-{{ 'foo' matches '/^fo/' ? 'OK' : 'KO' }}
-{{ 'foo' matches '/O/i' ? 'OK' : 'KO' }}
---DATA--
-return array()
---EXPECT--
-OK
-OK
-OK
---TEST--
-Twig supports method calls
---TEMPLATE--
-{{ items.foo.foo }}
-{{ items.foo.getFoo() }}
-{{ items.foo.bar }}
-{{ items.foo['bar'] }}
-{{ items.foo.bar('a', 43) }}
-{{ items.foo.bar(foo) }}
-{{ items.foo.self.foo() }}
-{{ items.foo.is }}
-{{ items.foo.in }}
-{{ items.foo.not }}
---DATA--
-return array('foo' => 'bar', 'items' => array('foo' => new TwigTestFoo(), 'bar' => 'foo'))
---CONFIG--
-return array('strict_variables' => false)
---EXPECT--
-foo
-foo
-bar
-
-bar_a-43
-bar_bar
-foo
-is
-in
-not
---TEST--
-Twig allows to use named operators as variable names
---TEMPLATE--
-{% for match in matches %}
- {{- match }}
-{% endfor %}
-{{ in }}
-{{ is }}
---DATA--
-return array('matches' => array(1, 2, 3), 'in' => 'in', 'is' => 'is')
---EXPECT--
-1
-2
-3
-in
-is
---TEST--
-Twig parses postfix expressions
---TEMPLATE--
-{% import _self as macros %}
-
-{% macro foo() %}foo{% endmacro %}
-
-{{ 'a' }}
-{{ 'a'|upper }}
-{{ ('a')|upper }}
-{{ -1|upper }}
-{{ macros.foo() }}
-{{ (macros).foo() }}
---DATA--
-return array();
---EXPECT--
-a
-A
-A
--1
-foo
-foo
---TEST--
-Twig supports the "same as" operator
---TEMPLATE--
-{{ 1 is same as(1) ? 'OK' }}
-{{ 1 is not same as(true) ? 'OK' }}
-{{ 1 is same as(1) ? 'OK' }}
-{{ 1 is not same as(true) ? 'OK' }}
-{{ 1 is same as (1) ? 'OK' }}
-{{ 1 is not
- same
- as
- (true) ? 'OK' }}
---DATA--
-return array()
---EXPECT--
-OK
-OK
-OK
-OK
-OK
-OK
---TEST--
-Twig supports the "starts with" operator
---TEMPLATE--
-{{ 'foo' starts with 'f' ? 'OK' : 'KO' }}
-{{ not ('foo' starts with 'oo') ? 'OK' : 'KO' }}
-{{ not ('foo' starts with 'foowaytoolong') ? 'OK' : 'KO' }}
-{{ 'foo' starts with 'f' ? 'OK' : 'KO' }}
-{{ 'foo' starts
-with 'f' ? 'OK' : 'KO' }}
-{{ 'foo' starts with '' ? 'OK' : 'KO' }}
-{{ '1' starts with true ? 'OK' : 'KO' }}
-{{ '' starts with false ? 'OK' : 'KO' }}
-{{ 'a' starts with false ? 'OK' : 'KO' }}
-{{ false starts with '' ? 'OK' : 'KO' }}
---DATA--
-return array()
---EXPECT--
-OK
-OK
-OK
-OK
-OK
-OK
-KO
-KO
-KO
-KO
---TEST--
-Twig supports string interpolation
---TEMPLATE--
-{# "foo #{"foo #{bar} baz"} baz" #}
-{# "foo #{bar}#{bar} baz" #}
---DATA--
-return array('bar' => 'BAR');
---EXPECT--
-foo foo BAR baz baz
-foo BARBAR baz
---TEST--
-Twig supports the ternary operator
---TEMPLATE--
-{{ 1 ? 'YES' }}
-{{ 0 ? 'YES' }}
---DATA--
-return array()
---EXPECT--
-YES
-
---TEST--
-Twig supports the ternary operator
---TEMPLATE--
-{{ 'YES' ?: 'NO' }}
-{{ 0 ?: 'NO' }}
---DATA--
-return array()
---EXPECT--
-YES
-NO
---TEST--
-Twig supports the ternary operator
---TEMPLATE--
-{{ 1 ? 'YES' : 'NO' }}
-{{ 0 ? 'YES' : 'NO' }}
-{{ 0 ? 'YES' : (1 ? 'YES1' : 'NO1') }}
-{{ 0 ? 'YES' : (0 ? 'YES1' : 'NO1') }}
-{{ 1 == 1 ? 'foo<br />':'' }}
-{{ foo ~ (bar ? ('-' ~ bar) : '') }}
---DATA--
-return array('foo' => 'foo', 'bar' => 'bar')
---EXPECT--
-YES
-NO
-YES1
-NO1
-foo<br />
-foo-bar
---TEST--
-Twig does not allow to use two-word named operators as variable names
---TEMPLATE--
-{{ starts with }}
---DATA--
-return array()
---EXCEPTION--
-Twig_Error_Syntax: Unexpected token "operator" of value "starts with" in "index.twig" at line 2
---TEST--
-Twig unary operators precedence
---TEMPLATE--
-{{ -1 - 1 }}
-{{ -1 - -1 }}
-{{ -1 * -1 }}
-{{ 4 / -1 * 5 }}
---DATA--
-return array()
---EXPECT--
--2
-0
-1
--20
---TEST--
-Twig supports unary operators (not, -, +)
---TEMPLATE--
-{{ not 1 }}/{{ not 0 }}
-{{ +1 + 1 }}/{{ -1 - 1 }}
-{{ not (false or true) }}
---DATA--
-return array()
---EXPECT--
-/1
-2/-2
-
---TEST--
-"abs" filter
---TEMPLATE--
-{{ (-5.5)|abs }}
-{{ (-5)|abs }}
-{{ (-0)|abs }}
-{{ 0|abs }}
-{{ 5|abs }}
-{{ 5.5|abs }}
-{{ number1|abs }}
-{{ number2|abs }}
-{{ number3|abs }}
-{{ number4|abs }}
-{{ number5|abs }}
-{{ number6|abs }}
---DATA--
-return array('number1' => -5.5, 'number2' => -5, 'number3' => -0, 'number4' => 0, 'number5' => 5, 'number6' => 5.5)
---EXPECT--
-5.5
-5
-0
-0
-5
-5.5
-5.5
-5
-0
-0
-5
-5.5
---TEST--
-"batch" filter
---TEMPLATE--
-{% for row in items|batch(3.1) %}
- <div class=row>
- {% for column in row %}
- <div class=item>{{ column }}</div>
- {% endfor %}
- </div>
-{% endfor %}
---DATA--
-return array('items' => array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'))
---EXPECT--
-<div class=row>
- <div class=item>a</div>
- <div class=item>b</div>
- <div class=item>c</div>
- <div class=item>d</div>
- </div>
- <div class=row>
- <div class=item>e</div>
- <div class=item>f</div>
- <div class=item>g</div>
- <div class=item>h</div>
- </div>
- <div class=row>
- <div class=item>i</div>
- <div class=item>j</div>
- </div>
---TEST--
-"batch" filter
---TEMPLATE--
-{% for row in items|batch(3) %}
- <div class=row>
- {% for column in row %}
- <div class=item>{{ column }}</div>
- {% endfor %}
- </div>
-{% endfor %}
---DATA--
-return array('items' => array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'))
---EXPECT--
-<div class=row>
- <div class=item>a</div>
- <div class=item>b</div>
- <div class=item>c</div>
- </div>
- <div class=row>
- <div class=item>d</div>
- <div class=item>e</div>
- <div class=item>f</div>
- </div>
- <div class=row>
- <div class=item>g</div>
- <div class=item>h</div>
- <div class=item>i</div>
- </div>
- <div class=row>
- <div class=item>j</div>
- </div>
---TEST--
-"batch" filter
---TEMPLATE--
-<table>
-{% for row in items|batch(3, '') %}
- <tr>
- {% for column in row %}
- <td>{{ column }}</td>
- {% endfor %}
- </tr>
-{% endfor %}
-</table>
---DATA--
-return array('items' => array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'))
---EXPECT--
-<table>
- <tr>
- <td>a</td>
- <td>b</td>
- <td>c</td>
- </tr>
- <tr>
- <td>d</td>
- <td>e</td>
- <td>f</td>
- </tr>
- <tr>
- <td>g</td>
- <td>h</td>
- <td>i</td>
- </tr>
- <tr>
- <td>j</td>
- <td></td>
- <td></td>
- </tr>
-</table>
---TEST--
-"batch" filter
---TEMPLATE--
-{% for row in items|batch(3, 'fill') %}
- <div class=row>
- {% for column in row %}
- <div class=item>{{ column }}</div>
- {% endfor %}
- </div>
-{% endfor %}
---DATA--
-return array('items' => array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'))
---EXPECT--
-<div class=row>
- <div class=item>a</div>
- <div class=item>b</div>
- <div class=item>c</div>
- </div>
- <div class=row>
- <div class=item>d</div>
- <div class=item>e</div>
- <div class=item>f</div>
- </div>
- <div class=row>
- <div class=item>g</div>
- <div class=item>h</div>
- <div class=item>i</div>
- </div>
- <div class=row>
- <div class=item>j</div>
- <div class=item>k</div>
- <div class=item>l</div>
- </div>
---TEST--
-"batch" filter
---TEMPLATE--
-<table>
-{% for row in items|batch(3, 'fill') %}
- <tr>
- {% for column in row %}
- <td>{{ column }}</td>
- {% endfor %}
- </tr>
-{% endfor %}
-</table>
---DATA--
-return array('items' => array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'))
---EXPECT--
-<table>
- <tr>
- <td>a</td>
- <td>b</td>
- <td>c</td>
- </tr>
- <tr>
- <td>d</td>
- <td>e</td>
- <td>f</td>
- </tr>
- <tr>
- <td>g</td>
- <td>h</td>
- <td>i</td>
- </tr>
- <tr>
- <td>j</td>
- <td>fill</td>
- <td>fill</td>
- </tr>
-</table>
---TEST--
-"convert_encoding" filter
---CONDITION--
-function_exists('iconv') || function_exists('mb_convert_encoding')
---TEMPLATE--
-{{ "愛していますか?"|convert_encoding('ISO-2022-JP', 'UTF-8')|convert_encoding('UTF-8', 'ISO-2022-JP') }}
---DATA--
-return array()
---EXPECT--
-愛していますか?
---TEST--
-"date" filter (interval support as of PHP 5.3)
---CONDITION--
-version_compare(phpversion(), '5.3.0', '>=')
---TEMPLATE--
-{{ date2|date }}
-{{ date2|date('%d days') }}
---DATA--
-date_default_timezone_set('UTC');
-$twig->getExtension('core')->setDateFormat('Y-m-d', '%d days %h hours');
-return array(
- 'date2' => new DateInterval('P2D'),
-)
---EXPECT--
-2 days 0 hours
-2 days
---TEST--
-"date" filter
---TEMPLATE--
-{{ date1|date }}
-{{ date1|date('d/m/Y') }}
---DATA--
-date_default_timezone_set('UTC');
-$twig->getExtension('core')->setDateFormat('Y-m-d', '%d days %h hours');
-return array(
- 'date1' => mktime(13, 45, 0, 10, 4, 2010),
-)
---EXPECT--
-2010-10-04
-04/10/2010
---TEST--
-"date" filter
---CONDITION--
-version_compare(phpversion(), '5.5.0', '>=')
---TEMPLATE--
-{{ date1|date }}
-{{ date1|date('d/m/Y') }}
-{{ date1|date('d/m/Y H:i:s', 'Asia/Hong_Kong') }}
-{{ date1|date('d/m/Y H:i:s', timezone1) }}
-{{ date1|date('d/m/Y H:i:s') }}
-
-{{ date2|date('d/m/Y H:i:s P', 'Europe/Paris') }}
-{{ date2|date('d/m/Y H:i:s P', 'Asia/Hong_Kong') }}
-{{ date2|date('d/m/Y H:i:s P', false) }}
-{{ date2|date('e', 'Europe/Paris') }}
-{{ date2|date('e', false) }}
---DATA--
-date_default_timezone_set('Europe/Paris');
-return array(
- 'date1' => new DateTimeImmutable('2010-10-04 13:45'),
- 'date2' => new DateTimeImmutable('2010-10-04 13:45', new DateTimeZone('America/New_York')),
- 'timezone1' => new DateTimeZone('America/New_York'),
-)
---EXPECT--
-October 4, 2010 13:45
-04/10/2010
-04/10/2010 19:45:00
-04/10/2010 07:45:00
-04/10/2010 13:45:00
-
-04/10/2010 19:45:00 +02:00
-05/10/2010 01:45:00 +08:00
-04/10/2010 13:45:00 -04:00
-Europe/Paris
-America/New_York
---TEST--
-"date" filter (interval support as of PHP 5.3)
---CONDITION--
-version_compare(phpversion(), '5.3.0', '>=')
---TEMPLATE--
-{{ date1|date }}
-{{ date1|date('%d days %h hours') }}
-{{ date1|date('%d days %h hours', timezone1) }}
---DATA--
-date_default_timezone_set('UTC');
-return array(
- 'date1' => new DateInterval('P2D'),
- // This should have no effect on DateInterval formatting
- 'timezone1' => new DateTimeZone('America/New_York'),
-)
---EXPECT--
-2 days
-2 days 0 hours
-2 days 0 hours
---TEST--
-"date_modify" filter
---TEMPLATE--
-{{ date1|date_modify('-1day')|date('Y-m-d H:i:s') }}
-{{ date2|date_modify('-1day')|date('Y-m-d H:i:s') }}
---DATA--
-date_default_timezone_set('UTC');
-return array(
- 'date1' => '2010-10-04 13:45',
- 'date2' => new DateTime('2010-10-04 13:45'),
-)
---EXPECT--
-2010-10-03 13:45:00
-2010-10-03 13:45:00
---TEST--
-"date" filter
---TEMPLATE--
-{{ date|date(format='d/m/Y H:i:s P', timezone='America/Chicago') }}
-{{ date|date(timezone='America/Chicago', format='d/m/Y H:i:s P') }}
-{{ date|date('d/m/Y H:i:s P', timezone='America/Chicago') }}
---DATA--
-date_default_timezone_set('UTC');
-return array('date' => mktime(13, 45, 0, 10, 4, 2010))
---EXPECT--
-04/10/2010 08:45:00 -05:00
-04/10/2010 08:45:00 -05:00
-04/10/2010 08:45:00 -05:00
---TEST--
-"date" filter
---TEMPLATE--
-{{ date1|date }}
-{{ date1|date('d/m/Y') }}
-{{ date1|date('d/m/Y H:i:s', 'Asia/Hong_Kong') }}
-{{ date1|date('d/m/Y H:i:s P', 'Asia/Hong_Kong') }}
-{{ date1|date('d/m/Y H:i:s P', 'America/Chicago') }}
-{{ date1|date('e') }}
-{{ date1|date('d/m/Y H:i:s') }}
-
-{{ date2|date }}
-{{ date2|date('d/m/Y') }}
-{{ date2|date('d/m/Y H:i:s', 'Asia/Hong_Kong') }}
-{{ date2|date('d/m/Y H:i:s', timezone1) }}
-{{ date2|date('d/m/Y H:i:s') }}
-
-{{ date3|date }}
-{{ date3|date('d/m/Y') }}
-
-{{ date4|date }}
-{{ date4|date('d/m/Y') }}
-
-{{ date5|date }}
-{{ date5|date('d/m/Y') }}
-
-{{ date6|date('d/m/Y H:i:s P', 'Europe/Paris') }}
-{{ date6|date('d/m/Y H:i:s P', 'Asia/Hong_Kong') }}
-{{ date6|date('d/m/Y H:i:s P', false) }}
-{{ date6|date('e', 'Europe/Paris') }}
-{{ date6|date('e', false) }}
-
-{{ date7|date }}
---DATA--
-date_default_timezone_set('Europe/Paris');
-return array(
- 'date1' => mktime(13, 45, 0, 10, 4, 2010),
- 'date2' => new DateTime('2010-10-04 13:45'),
- 'date3' => '2010-10-04 13:45',
- 'date4' => 1286199900, // DateTime::createFromFormat('Y-m-d H:i', '2010-10-04 13:45', new DateTimeZone('UTC'))->getTimestamp() -- A unixtimestamp is always GMT
- 'date5' => -189291360, // DateTime::createFromFormat('Y-m-d H:i', '1964-01-02 03:04', new DateTimeZone('UTC'))->getTimestamp(),
- 'date6' => new DateTime('2010-10-04 13:45', new DateTimeZone('America/New_York')),
- 'date7' => '2010-01-28T15:00:00+05:00',
- 'timezone1' => new DateTimeZone('America/New_York'),
-)
---EXPECT--
-October 4, 2010 13:45
-04/10/2010
-04/10/2010 19:45:00
-04/10/2010 19:45:00 +08:00
-04/10/2010 06:45:00 -05:00
-Europe/Paris
-04/10/2010 13:45:00
-
-October 4, 2010 13:45
-04/10/2010
-04/10/2010 19:45:00
-04/10/2010 07:45:00
-04/10/2010 13:45:00
-
-October 4, 2010 13:45
-04/10/2010
-
-October 4, 2010 15:45
-04/10/2010
-
-January 2, 1964 04:04
-02/01/1964
-
-04/10/2010 19:45:00 +02:00
-05/10/2010 01:45:00 +08:00
-04/10/2010 13:45:00 -04:00
-Europe/Paris
-America/New_York
-
-January 28, 2010 11:00
---TEST--
-"default" filter
---TEMPLATE--
-Variable:
-{{ definedVar |default('default') is same as('default') ? 'ko' : 'ok' }}
-{{ zeroVar |default('default') is same as('default') ? 'ko' : 'ok' }}
-{{ emptyVar |default('default') is same as('default') ? 'ok' : 'ko' }}
-{{ nullVar |default('default') is same as('default') ? 'ok' : 'ko' }}
-{{ undefinedVar |default('default') is same as('default') ? 'ok' : 'ko' }}
-Array access:
-{{ nested.definedVar |default('default') is same as('default') ? 'ko' : 'ok' }}
-{{ nested['definedVar'] |default('default') is same as('default') ? 'ko' : 'ok' }}
-{{ nested.zeroVar |default('default') is same as('default') ? 'ko' : 'ok' }}
-{{ nested.emptyVar |default('default') is same as('default') ? 'ok' : 'ko' }}
-{{ nested.nullVar |default('default') is same as('default') ? 'ok' : 'ko' }}
-{{ nested.undefinedVar |default('default') is same as('default') ? 'ok' : 'ko' }}
-{{ nested['undefinedVar'] |default('default') is same as('default') ? 'ok' : 'ko' }}
-{{ undefinedVar.foo |default('default') is same as('default') ? 'ok' : 'ko' }}
-Plain values:
-{{ 'defined' |default('default') is same as('default') ? 'ko' : 'ok' }}
-{{ 0 |default('default') is same as('default') ? 'ko' : 'ok' }}
-{{ '' |default('default') is same as('default') ? 'ok' : 'ko' }}
-{{ null |default('default') is same as('default') ? 'ok' : 'ko' }}
-Precedence:
-{{ 'o' ~ nullVar |default('k') }}
-{{ 'o' ~ nested.nullVar |default('k') }}
-Object methods:
-{{ object.foo |default('default') is same as('default') ? 'ko' : 'ok' }}
-{{ object.undefinedMethod |default('default') is same as('default') ? 'ok' : 'ko' }}
-{{ object.getFoo() |default('default') is same as('default') ? 'ko' : 'ok' }}
-{{ object.getFoo('a') |default('default') is same as('default') ? 'ko' : 'ok' }}
-{{ object.undefinedMethod() |default('default') is same as('default') ? 'ok' : 'ko' }}
-{{ object.undefinedMethod('a') |default('default') is same as('default') ? 'ok' : 'ko' }}
-Deep nested:
-{{ nested.undefinedVar.foo.bar |default('default') is same as('default') ? 'ok' : 'ko' }}
-{{ nested.definedArray.0 |default('default') is same as('default') ? 'ko' : 'ok' }}
-{{ nested['definedArray'][0] |default('default') is same as('default') ? 'ko' : 'ok' }}
-{{ object.self.foo |default('default') is same as('default') ? 'ko' : 'ok' }}
-{{ object.self.undefinedMethod |default('default') is same as('default') ? 'ok' : 'ko' }}
-{{ object.undefinedMethod.self |default('default') is same as('default') ? 'ok' : 'ko' }}
---DATA--
-return array(
- 'definedVar' => 'defined',
- 'zeroVar' => 0,
- 'emptyVar' => '',
- 'nullVar' => null,
- 'nested' => array(
- 'definedVar' => 'defined',
- 'zeroVar' => 0,
- 'emptyVar' => '',
- 'nullVar' => null,
- 'definedArray' => array(0),
- ),
- 'object' => new TwigTestFoo(),
-)
---CONFIG--
-return array('strict_variables' => false)
---EXPECT--
-Variable:
-ok
-ok
-ok
-ok
-ok
-Array access:
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-Plain values:
-ok
-ok
-ok
-ok
-Precedence:
-ok
-ok
-Object methods:
-ok
-ok
-ok
-ok
-ok
-ok
-Deep nested:
-ok
-ok
-ok
-ok
-ok
-ok
---DATA--
-return array(
- 'definedVar' => 'defined',
- 'zeroVar' => 0,
- 'emptyVar' => '',
- 'nullVar' => null,
- 'nested' => array(
- 'definedVar' => 'defined',
- 'zeroVar' => 0,
- 'emptyVar' => '',
- 'nullVar' => null,
- 'definedArray' => array(0),
- ),
- 'object' => new TwigTestFoo(),
-)
---CONFIG--
-return array('strict_variables' => true)
---EXPECT--
-Variable:
-ok
-ok
-ok
-ok
-ok
-Array access:
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-Plain values:
-ok
-ok
-ok
-ok
-Precedence:
-ok
-ok
-Object methods:
-ok
-ok
-ok
-ok
-ok
-ok
-Deep nested:
-ok
-ok
-ok
-ok
-ok
-ok
---TEST--
-dynamic filter
---TEMPLATE--
-{{ 'bar'|foo_path }}
-{{ 'bar'|a_foo_b_bar }}
---DATA--
-return array()
---EXPECT--
-foo/bar
-a/b/bar
---TEST--
-"escape" filter does not escape with the html strategy when using the html_attr strategy
---TEMPLATE--
-{{ '<br />'|escape('html_attr') }}
---DATA--
-return array()
---EXPECT--
-&lt;br&#x20;&#x2F;&gt;
---TEST--
-"escape" filter
---TEMPLATE--
-{{ "愛していますか? <br />"|e }}
---DATA--
-return array()
---EXPECT--
-愛していますか? &lt;br /&gt;
---TEST--
-"escape" filter
---TEMPLATE--
-{{ "foo <br />"|e }}
---DATA--
-return array()
---EXPECT--
-foo &lt;br /&gt;
---TEST--
-"first" filter
---TEMPLATE--
-{{ [1, 2, 3, 4]|first }}
-{{ {a: 1, b: 2, c: 3, d: 4}|first }}
-{{ '1234'|first }}
-{{ arr|first }}
-{{ 'Ä€é'|first }}
-{{ ''|first }}
---DATA--
-return array('arr' => new ArrayObject(array(1, 2, 3, 4)))
---EXPECT--
-1
-1
-1
-1
---TEST--
-"escape" filter
---TEMPLATE--
-{% set foo %}
- foo<br />
-{% endset %}
-
-{{ foo|e('html') -}}
-{{ foo|e('js') }}
-{% autoescape true %}
- {{ foo }}
-{% endautoescape %}
---DATA--
-return array()
---EXPECT--
- foo&lt;br /&gt;
-\x20\x20\x20\x20foo\x3Cbr\x20\x2F\x3E\x0A
- foo<br />
---TEST--
-"format" filter
---TEMPLATE--
-{{ string|format(foo, 3) }}
---DATA--
-return array('string' => '%s/%d', 'foo' => 'bar')
---EXPECT--
-bar/3
---TEST--
-"join" filter
---TEMPLATE--
-{{ ["foo", "bar"]|join(', ') }}
-{{ foo|join(', ') }}
-{{ bar|join(', ') }}
---DATA--
-return array('foo' => new TwigTestFoo(), 'bar' => new ArrayObject(array(3, 4)))
---EXPECT--
-foo, bar
-1, 2
-3, 4
---TEST--
-"json_encode" filter
---TEMPLATE--
-{{ "foo"|json_encode|raw }}
-{{ foo|json_encode|raw }}
-{{ [foo, "foo"]|json_encode|raw }}
---DATA--
-return array('foo' => new Twig_Markup('foo', 'UTF-8'))
---EXPECT--
-"foo"
-"foo"
-["foo","foo"]
---TEST--
-"last" filter
---TEMPLATE--
-{{ [1, 2, 3, 4]|last }}
-{{ {a: 1, b: 2, c: 3, d: 4}|last }}
-{{ '1234'|last }}
-{{ arr|last }}
-{{ 'Ä€é'|last }}
-{{ ''|last }}
---DATA--
-return array('arr' => new ArrayObject(array(1, 2, 3, 4)))
---EXPECT--
-4
-4
-4
-4
---TEST--
-"length" filter
---TEMPLATE--
-{{ array|length }}
-{{ string|length }}
-{{ number|length }}
-{{ markup|length }}
---DATA--
-return array('array' => array(1, 4), 'string' => 'foo', 'number' => 1000, 'markup' => new Twig_Markup('foo', 'UTF-8'))
---EXPECT--
-2
-3
-4
-3
---TEST--
-"length" filter
---CONDITION--
-function_exists('mb_get_info')
---TEMPLATE--
-{{ string|length }}
-{{ markup|length }}
---DATA--
-return array('string' => 'été', 'markup' => new Twig_Markup('foo', 'UTF-8'))
---EXPECT--
-3
-3
---TEST--
-"merge" filter
---TEMPLATE--
-{{ items|merge({'bar': 'foo'})|join }}
-{{ items|merge({'bar': 'foo'})|keys|join }}
-{{ {'bar': 'foo'}|merge(items)|join }}
-{{ {'bar': 'foo'}|merge(items)|keys|join }}
-{{ numerics|merge([4, 5, 6])|join }}
---DATA--
-return array('items' => array('foo' => 'bar'), 'numerics' => array(1, 2, 3))
---EXPECT--
-barfoo
-foobar
-foobar
-barfoo
-123456
---TEST--
-"nl2br" filter
---TEMPLATE--
-{{ "I like Twig.\nYou will like it too.\n\nEverybody like it!"|nl2br }}
-{{ text|nl2br }}
---DATA--
-return array('text' => "If you have some <strong>HTML</strong>\nit will be escaped.")
---EXPECT--
-I like Twig.<br />
-You will like it too.<br />
-<br />
-Everybody like it!
-If you have some &lt;strong&gt;HTML&lt;/strong&gt;<br />
-it will be escaped.
---TEST--
-"number_format" filter with defaults.
---TEMPLATE--
-{{ 20|number_format }}
-{{ 20.25|number_format }}
-{{ 20.25|number_format(1) }}
-{{ 20.25|number_format(2, ',') }}
-{{ 1020.25|number_format }}
-{{ 1020.25|number_format(2, ',') }}
-{{ 1020.25|number_format(2, ',', '.') }}
---DATA--
-$twig->getExtension('core')->setNumberFormat(2, '!', '=');
-return array();
---EXPECT--
-20!00
-20!25
-20!3
-20,25
-1=020!25
-1=020,25
-1.020,25
---TEST--
-"number_format" filter
---TEMPLATE--
-{{ 20|number_format }}
-{{ 20.25|number_format }}
-{{ 20.25|number_format(2) }}
-{{ 20.25|number_format(2, ',') }}
-{{ 1020.25|number_format(2, ',') }}
-{{ 1020.25|number_format(2, ',', '.') }}
---DATA--
-return array();
---EXPECT--
-20
-20
-20.25
-20,25
-1,020,25
-1.020,25
---TEST--
-"replace" filter
---TEMPLATE--
-{{ "I like %this% and %that%."|replace({'%this%': "foo", '%that%': "bar"}) }}
---DATA--
-return array()
---EXPECT--
-I like foo and bar.
---TEST--
-"reverse" filter
---TEMPLATE--
-{{ [1, 2, 3, 4]|reverse|join('') }}
-{{ '1234évènement'|reverse }}
-{{ arr|reverse|join('') }}
-{{ {'a': 'c', 'b': 'a'}|reverse()|join(',') }}
-{{ {'a': 'c', 'b': 'a'}|reverse(preserveKeys=true)|join(glue=',') }}
-{{ {'a': 'c', 'b': 'a'}|reverse(preserve_keys=true)|join(glue=',') }}
---DATA--
-return array('arr' => new ArrayObject(array(1, 2, 3, 4)))
---EXPECT--
-4321
-tnemenèvé4321
-4321
-a,c
-a,c
-a,c
---TEST--
-"round" filter
---TEMPLATE--
-{{ 2.7|round }}
-{{ 2.1|round }}
-{{ 2.1234|round(3, 'floor') }}
-{{ 2.1|round(0, 'ceil') }}
-
-{{ 21.3|round(-1)}}
-{{ 21.3|round(-1, 'ceil')}}
-{{ 21.3|round(-1, 'floor')}}
---DATA--
-return array()
---EXPECT--
-3
-2
-2.123
-3
-
-20
-30
-20
---TEST--
-"slice" filter
---TEMPLATE--
-{{ [1, 2, 3, 4][1:2]|join('') }}
-{{ {a: 1, b: 2, c: 3, d: 4}[1:2]|join('') }}
-{{ [1, 2, 3, 4][start:length]|join('') }}
-{{ [1, 2, 3, 4]|slice(1, 2)|join('') }}
-{{ [1, 2, 3, 4]|slice(1, 2)|keys|join('') }}
-{{ [1, 2, 3, 4]|slice(1, 2, true)|keys|join('') }}
-{{ {a: 1, b: 2, c: 3, d: 4}|slice(1, 2)|join('') }}
-{{ {a: 1, b: 2, c: 3, d: 4}|slice(1, 2)|keys|join('') }}
-{{ '1234'|slice(1, 2) }}
-{{ '1234'[1:2] }}
-{{ arr|slice(1, 2)|join('') }}
-{{ arr[1:2]|join('') }}
-
-{{ [1, 2, 3, 4]|slice(1)|join('') }}
-{{ [1, 2, 3, 4][1:]|join('') }}
-{{ '1234'|slice(1) }}
-{{ '1234'[1:] }}
-{{ '1234'[:1] }}
---DATA--
-return array('start' => 1, 'length' => 2, 'arr' => new ArrayObject(array(1, 2, 3, 4)))
---EXPECT--
-23
-23
-23
-23
-01
-12
-23
-bc
-23
-23
-23
-23
-
-234
-234
-234
-234
-1
---TEST--
-"sort" filter
---TEMPLATE--
-{{ array1|sort|join }}
-{{ array2|sort|join }}
---DATA--
-return array('array1' => array(4, 1), 'array2' => array('foo', 'bar'))
---EXPECT--
-14
-barfoo
---TEST--
-"split" filter
---TEMPLATE--
-{{ "one,two,three,four,five"|split(',')|join('-') }}
-{{ foo|split(',')|join('-') }}
-{{ foo|split(',', 3)|join('-') }}
-{{ baz|split('')|join('-') }}
-{{ baz|split('', 2)|join('-') }}
-{{ foo|split(',', -2)|join('-') }}
---DATA--
-return array('foo' => "one,two,three,four,five", 'baz' => '12345',)
---EXPECT--
-one-two-three-four-five
-one-two-three-four-five
-one-two-three,four,five
-1-2-3-4-5
-12-34-5
-one-two-three--TEST--
-"trim" filter
---TEMPLATE--
-{{ " I like Twig. "|trim }}
-{{ text|trim }}
-{{ " foo/"|trim("/") }}
---DATA--
-return array('text' => " If you have some <strong>HTML</strong> it will be escaped. ")
---EXPECT--
-I like Twig.
-If you have some &lt;strong&gt;HTML&lt;/strong&gt; it will be escaped.
- foo
---TEST--
-"url_encode" filter for PHP < 5.4 and HHVM
---CONDITION--
-defined('PHP_QUERY_RFC3986')
---TEMPLATE--
-{{ {foo: "bar", number: 3, "spéßi%l": "e%c0d@d", "spa ce": ""}|url_encode }}
-{{ {foo: "bar", number: 3, "spéßi%l": "e%c0d@d", "spa ce": ""}|url_encode|raw }}
-{{ {}|url_encode|default("default") }}
-{{ 'spéßi%le%c0d@dspa ce'|url_encode }}
---DATA--
-return array()
---EXPECT--
-foo=bar&amp;number=3&amp;sp%C3%A9%C3%9Fi%25l=e%25c0d%40d&amp;spa%20ce=
-foo=bar&number=3&sp%C3%A9%C3%9Fi%25l=e%25c0d%40d&spa%20ce=
-default
-sp%C3%A9%C3%9Fi%25le%25c0d%40dspa%20ce
---TEST--
-"url_encode" filter
---CONDITION--
-defined('PHP_QUERY_RFC3986')
---TEMPLATE--
-{{ {foo: "bar", number: 3, "spéßi%l": "e%c0d@d", "spa ce": ""}|url_encode }}
-{{ {foo: "bar", number: 3, "spéßi%l": "e%c0d@d", "spa ce": ""}|url_encode|raw }}
-{{ {}|url_encode|default("default") }}
-{{ 'spéßi%le%c0d@dspa ce'|url_encode }}
---DATA--
-return array()
---EXPECT--
-foo=bar&amp;number=3&amp;sp%C3%A9%C3%9Fi%25l=e%25c0d%40d&amp;spa%20ce=
-foo=bar&number=3&sp%C3%A9%C3%9Fi%25l=e%25c0d%40d&spa%20ce=
-default
-sp%C3%A9%C3%9Fi%25le%25c0d%40dspa%20ce
---TEST--
-"attribute" function
---TEMPLATE--
-{{ attribute(obj, method) }}
-{{ attribute(array, item) }}
-{{ attribute(obj, "bar", ["a", "b"]) }}
-{{ attribute(obj, "bar", arguments) }}
-{{ attribute(obj, method) is defined ? 'ok' : 'ko' }}
-{{ attribute(obj, nonmethod) is defined ? 'ok' : 'ko' }}
---DATA--
-return array('obj' => new TwigTestFoo(), 'method' => 'foo', 'array' => array('foo' => 'bar'), 'item' => 'foo', 'nonmethod' => 'xxx', 'arguments' => array('a', 'b'))
---EXPECT--
-foo
-bar
-bar_a-b
-bar_a-b
-ok
-ko
---TEST--
-"block" function
---TEMPLATE--
-{% extends 'base.twig' %}
-{% block bar %}BAR{% endblock %}
---TEMPLATE(base.twig)--
-{% block foo %}{{ block('bar') }}{% endblock %}
-{% block bar %}BAR_BASE{% endblock %}
---DATA--
-return array()
---EXPECT--
-BARBAR
---TEST--
-"constant" function
---TEMPLATE--
-{{ constant('DATE_W3C') == expect ? 'true' : 'false' }}
-{{ constant('ARRAY_AS_PROPS', object) }}
---DATA--
-return array('expect' => DATE_W3C, 'object' => new ArrayObject(array('hi')));
---EXPECT--
-true
-2
---TEST--
-"cycle" function
---TEMPLATE--
-{% for i in 0..6 %}
-{{ cycle(array1, i) }}-{{ cycle(array2, i) }}
-{% endfor %}
---DATA--
-return array('array1' => array('odd', 'even'), 'array2' => array('apple', 'orange', 'citrus'))
---EXPECT--
-odd-apple
-even-orange
-odd-citrus
-even-apple
-odd-orange
-even-citrus
-odd-apple
---TEST--
-"date" function
---TEMPLATE--
-{{ date(date, "America/New_York")|date('d/m/Y H:i:s P', false) }}
-{{ date(timezone="America/New_York", date=date)|date('d/m/Y H:i:s P', false) }}
---DATA--
-date_default_timezone_set('UTC');
-return array('date' => mktime(13, 45, 0, 10, 4, 2010))
---EXPECT--
-04/10/2010 09:45:00 -04:00
-04/10/2010 09:45:00 -04:00
---TEST--
-"date" function
---TEMPLATE--
-{{ date() == date('now') ? 'OK' : 'KO' }}
-{{ date(date1) == date('2010-10-04 13:45') ? 'OK' : 'KO' }}
-{{ date(date2) == date('2010-10-04 13:45') ? 'OK' : 'KO' }}
-{{ date(date3) == date('2010-10-04 13:45') ? 'OK' : 'KO' }}
-{{ date(date4) == date('2010-10-04 13:45') ? 'OK' : 'KO' }}
-{{ date(date5) == date('1964-01-02 03:04') ? 'OK' : 'KO' }}
---DATA--
-date_default_timezone_set('UTC');
-return array(
- 'date1' => mktime(13, 45, 0, 10, 4, 2010),
- 'date2' => new DateTime('2010-10-04 13:45'),
- 'date3' => '2010-10-04 13:45',
- 'date4' => 1286199900, // DateTime::createFromFormat('Y-m-d H:i', '2010-10-04 13:45', new DateTimeZone('UTC'))->getTimestamp() -- A unixtimestamp is always GMT
- 'date5' => -189291360, // DateTime::createFromFormat('Y-m-d H:i', '1964-01-02 03:04', new DateTimeZone('UTC'))->getTimestamp(),
-)
---EXPECT--
-OK
-OK
-OK
-OK
-OK
-OK
---TEST--
-"dump" function, xdebug is not loaded or xdebug <2.2-dev is loaded
---CONDITION--
-!extension_loaded('xdebug') || (($r = new ReflectionExtension('xdebug')) && version_compare($r->getVersion(), '2.2-dev', '<'))
---TEMPLATE--
-{{ dump() }}
---DATA--
-return array('foo' => 'foo', 'bar' => 'bar')
---CONFIG--
-return array('debug' => true, 'autoescape' => false);
---TEST--
-"dump" function
---CONDITION--
-!extension_loaded('xdebug')
---TEMPLATE--
-{{ dump('foo') }}
-{{ dump('foo', 'bar') }}
---DATA--
-return array('foo' => 'foo', 'bar' => 'bar')
---CONFIG--
-return array('debug' => true, 'autoescape' => false);
---EXPECT--
-string(3) "foo"
-
-string(3) "foo"
-string(3) "bar"
---TEST--
-dynamic function
---TEMPLATE--
-{{ foo_path('bar') }}
-{{ a_foo_b_bar('bar') }}
---DATA--
-return array()
---EXPECT--
-foo/bar
-a/b/bar
---TEST--
-"include" function
---TEMPLATE--
-{% set tmp = include("foo.twig") %}
-
-FOO{{ tmp }}BAR
---TEMPLATE(foo.twig)--
-FOOBAR
---DATA--
-return array()
---EXPECT--
-FOO
-FOOBARBAR
---TEST--
-"include" function is safe for auto-escaping
---TEMPLATE--
-{{ include("foo.twig") }}
---TEMPLATE(foo.twig)--
-<p>Test</p>
---DATA--
-return array()
---EXPECT--
-<p>Test</p>
---TEST--
-"include" function
---TEMPLATE--
-FOO
-{{ include("foo.twig") }}
-
-BAR
---TEMPLATE(foo.twig)--
-FOOBAR
---DATA--
-return array()
---EXPECT--
-FOO
-
-FOOBAR
-
-BAR
---TEST--
-"include" function allows expressions for the template to include
---TEMPLATE--
-FOO
-{{ include(foo) }}
-
-BAR
---TEMPLATE(foo.twig)--
-FOOBAR
---DATA--
-return array('foo' => 'foo.twig')
---EXPECT--
-FOO
-
-FOOBAR
-
-BAR
---TEST--
-"include" function
---TEMPLATE--
-{{ include(["foo.twig", "bar.twig"], ignore_missing = true) }}
-{{ include("foo.twig", ignore_missing = true) }}
-{{ include("foo.twig", ignore_missing = true, variables = {}) }}
-{{ include("foo.twig", ignore_missing = true, variables = {}, with_context = true) }}
---DATA--
-return array()
---EXPECT--
---TEST--
-"include" function
---TEMPLATE--
-{% extends "base.twig" %}
-
-{% block content %}
- {{ parent() }}
-{% endblock %}
---TEMPLATE(base.twig)--
-{% block content %}
- {{ include("foo.twig") }}
-{% endblock %}
---DATA--
-return array();
---EXCEPTION--
-Twig_Error_Loader: Template "foo.twig" is not defined in "base.twig" at line 3.
---TEST--
-"include" function
---TEMPLATE--
-{{ include("foo.twig") }}
---DATA--
-return array();
---EXCEPTION--
-Twig_Error_Loader: Template "foo.twig" is not defined in "index.twig" at line 2.
---TEST--
-"include" tag sandboxed
---TEMPLATE--
-{{ include("foo.twig", sandboxed = true) }}
---TEMPLATE(foo.twig)--
-{{ foo|e }}
---DATA--
-return array()
---EXCEPTION--
-Twig_Sandbox_SecurityError: Filter "e" is not allowed in "index.twig" at line 2.
---TEST--
-"include" function accepts Twig_Template instance
---TEMPLATE--
-{{ include(foo) }} FOO
---TEMPLATE(foo.twig)--
-BAR
---DATA--
-return array('foo' => $twig->loadTemplate('foo.twig'))
---EXPECT--
-BAR FOO
---TEST--
-"include" function
---TEMPLATE--
-{{ include(["foo.twig", "bar.twig"]) }}
-{{- include(["bar.twig", "foo.twig"]) }}
---TEMPLATE(foo.twig)--
-foo
---DATA--
-return array()
---EXPECT--
-foo
-foo
---TEST--
-"include" function accept variables and with_context
---TEMPLATE--
-{{ include("foo.twig") }}
-{{- include("foo.twig", with_context = false) }}
-{{- include("foo.twig", {'foo1': 'bar'}) }}
-{{- include("foo.twig", {'foo1': 'bar'}, with_context = false) }}
---TEMPLATE(foo.twig)--
-{% for k, v in _context %}{{ k }},{% endfor %}
---DATA--
-return array('foo' => 'bar')
---EXPECT--
-foo,global,_parent,
-global,_parent,
-foo,global,foo1,_parent,
-foo1,global,_parent,
---TEST--
-"include" function accept variables
---TEMPLATE--
-{{ include("foo.twig", {'foo': 'bar'}) }}
-{{- include("foo.twig", vars) }}
---TEMPLATE(foo.twig)--
-{{ foo }}
---DATA--
-return array('vars' => array('foo' => 'bar'))
---EXPECT--
-bar
-bar
---TEST--
-"max" function
---TEMPLATE--
-{{ max([2, 1, 3, 5, 4]) }}
-{{ max(2, 1, 3, 5, 4) }}
-{{ max({2:"two", 1:"one", 3:"three", 5:"five", 4:"for"}) }}
---DATA--
-return array()
---EXPECT--
-5
-5
-two
---TEST--
-"min" function
---TEMPLATE--
-{{ min(2, 1, 3, 5, 4) }}
-{{ min([2, 1, 3, 5, 4]) }}
-{{ min({2:"two", 1:"one", 3:"three", 5:"five", 4:"for"}) }}
---DATA--
-return array()
---EXPECT--
-1
-1
-five
---TEST--
-"range" function
---TEMPLATE--
-{{ range(low=0+1, high=10+0, step=2)|join(',') }}
---DATA--
-return array()
---EXPECT--
-1,3,5,7,9
---TEST--
-"block" function recursively called in a parent template
---TEMPLATE--
-{% extends "ordered_menu.twig" %}
-{% block label %}"{{ parent() }}"{% endblock %}
-{% block list %}{% set class = 'b' %}{{ parent() }}{% endblock %}
---TEMPLATE(ordered_menu.twig)--
-{% extends "menu.twig" %}
-{% block list %}{% set class = class|default('a') %}<ol class="{{ class }}">{{ block('children') }}</ol>{% endblock %}
---TEMPLATE(menu.twig)--
-{% extends "base.twig" %}
-{% block list %}<ul>{{ block('children') }}</ul>{% endblock %}
-{% block children %}{% set currentItem = item %}{% for item in currentItem %}{{ block('item') }}{% endfor %}{% set item = currentItem %}{% endblock %}
-{% block item %}<li>{% if item is not iterable %}{{ block('label') }}{% else %}{{ block('list') }}{% endif %}</li>{% endblock %}
-{% block label %}{{ item }}{{ block('unknown') }}{% endblock %}
---TEMPLATE(base.twig)--
-{{ block('list') }}
---DATA--
-return array('item' => array('1', '2', array('3.1', array('3.2.1', '3.2.2'), '3.4')))
---EXPECT--
-<ol class="b"><li>"1"</li><li>"2"</li><li><ol class="b"><li>"3.1"</li><li><ol class="b"><li>"3.2.1"</li><li>"3.2.2"</li></ol></li><li>"3.4"</li></ol></li></ol>
---TEST--
-"source" function
---TEMPLATE--
-FOO
-{{ source("foo.twig") }}
-
-BAR
---TEMPLATE(foo.twig)--
-{{ foo }}<br />
---DATA--
-return array()
---EXPECT--
-FOO
-
-{{ foo }}<br />
-
-BAR
---TEST--
-"template_from_string" function
---TEMPLATE--
-{% include template_from_string(template) %}
-
-{% include template_from_string("Hello {{ name }}") %}
-{% include template_from_string('{% extends "parent.twig" %}{% block content %}Hello {{ name }}{% endblock %}') %}
---TEMPLATE(parent.twig)--
-{% block content %}{% endblock %}
---DATA--
-return array('name' => 'Fabien', 'template' => "Hello {{ name }}")
---EXPECT--
-Hello Fabien
-Hello Fabien
-Hello Fabien
---TEST--
-macro
---TEMPLATE--
-{% from _self import test %}
-
-{% macro test(a, b = 'bar') -%}
-{{ a }}{{ b }}
-{%- endmacro %}
-
-{{ test('foo') }}
-{{ test('bar', 'foo') }}
---DATA--
-return array();
---EXPECT--
-foobar
-barfoo
---TEST--
-macro
---TEMPLATE--
-{% import _self as macros %}
-
-{% macro foo(data) %}
- {{ data }}
-{% endmacro %}
-
-{% macro bar() %}
- <br />
-{% endmacro %}
-
-{{ macros.foo(macros.bar()) }}
---DATA--
-return array();
---EXPECT--
-<br />
---TEST--
-macro
---TEMPLATE--
-{% from _self import test %}
-
-{% macro test(this) -%}
- {{ this }}
-{%- endmacro %}
-
-{{ test(this) }}
---DATA--
-return array('this' => 'foo');
---EXPECT--
-foo
---TEST--
-macro
---TEMPLATE--
-{% import _self as test %}
-{% from _self import test %}
-
-{% macro test(a, b) -%}
- {{ a|default('a') }}<br />
- {{- b|default('b') }}<br />
-{%- endmacro %}
-
-{{ test.test() }}
-{{ test() }}
-{{ test.test(1, "c") }}
-{{ test(1, "c") }}
---DATA--
-return array();
---EXPECT--
-a<br />b<br />
-a<br />b<br />
-1<br />c<br />
-1<br />c<br />
---TEST--
-macro with a filter
---TEMPLATE--
-{% import _self as test %}
-
-{% macro test() %}
- {% filter escape %}foo<br />{% endfilter %}
-{% endmacro %}
-
-{{ test.test() }}
---DATA--
-return array();
---EXPECT--
-foo&lt;br /&gt;
---TEST--
-Twig outputs 0 nodes correctly
---TEMPLATE--
-{{ foo }}0{{ foo }}
---DATA--
-return array('foo' => 'foo')
---EXPECT--
-foo0foo
---TEST--
-error in twig extension
---TEMPLATE--
-{{ object.region is not null ? object.regionChoices[object.region] }}
---EXPECT--
-house.region.s
---TEST--
-Twig is able to deal with SimpleXMLElement instances as variables
---CONDITION--
-version_compare(phpversion(), '5.3.0', '>=')
---TEMPLATE--
-Hello '{{ images.image.0.group }}'!
-{{ images.image.0.group.attributes.myattr }}
-{{ images.children().image.count() }}
-{% for image in images %}
- - {{ image.group }}
-{% endfor %}
---DATA--
-return array('images' => new SimpleXMLElement('<images><image><group myattr="example">foo</group></image><image><group>bar</group></image></images>'))
---EXPECT--
-Hello 'foo'!
-example
-2
- - foo
- - bar
---TEST--
-Twig does not confuse strings with integers in getAttribute()
---TEMPLATE--
-{{ hash['2e2'] }}
---DATA--
-return array('hash' => array('2e2' => 'works'))
---EXPECT--
-works
---TEST--
-"autoescape" tag applies escaping on its children
---TEMPLATE--
-{% autoescape %}
-{{ var }}<br />
-{% endautoescape %}
-{% autoescape 'html' %}
-{{ var }}<br />
-{% endautoescape %}
-{% autoescape false %}
-{{ var }}<br />
-{% endautoescape %}
-{% autoescape true %}
-{{ var }}<br />
-{% endautoescape %}
-{% autoescape false %}
-{{ var }}<br />
-{% endautoescape %}
---DATA--
-return array('var' => '<br />')
---EXPECT--
-&lt;br /&gt;<br />
-&lt;br /&gt;<br />
-<br /><br />
-&lt;br /&gt;<br />
-<br /><br />
---TEST--
-"autoescape" tag applies escaping on embedded blocks
---TEMPLATE--
-{% autoescape 'html' %}
- {% block foo %}
- {{ var }}
- {% endblock %}
-{% endautoescape %}
---DATA--
-return array('var' => '<br />')
---EXPECT--
-&lt;br /&gt;
---TEST--
-"autoescape" tag does not double-escape
---TEMPLATE--
-{% autoescape 'html' %}
-{{ var|escape }}
-{% endautoescape %}
---DATA--
-return array('var' => '<br />')
---EXPECT--
-&lt;br /&gt;
---TEST--
-"autoescape" tag applies escaping after calling functions
---TEMPLATE--
-
-autoescape false
-{% autoescape false %}
-
-safe_br
-{{ safe_br() }}
-
-unsafe_br
-{{ unsafe_br() }}
-
-{% endautoescape %}
-
-autoescape 'html'
-{% autoescape 'html' %}
-
-safe_br
-{{ safe_br() }}
-
-unsafe_br
-{{ unsafe_br() }}
-
-unsafe_br()|raw
-{{ (unsafe_br())|raw }}
-
-safe_br()|escape
-{{ (safe_br())|escape }}
-
-safe_br()|raw
-{{ (safe_br())|raw }}
-
-unsafe_br()|escape
-{{ (unsafe_br())|escape }}
-
-{% endautoescape %}
-
-autoescape js
-{% autoescape 'js' %}
-
-safe_br
-{{ safe_br() }}
-
-{% endautoescape %}
---DATA--
-return array()
---EXPECT--
-
-autoescape false
-
-safe_br
-<br />
-
-unsafe_br
-<br />
-
-
-autoescape 'html'
-
-safe_br
-<br />
-
-unsafe_br
-&lt;br /&gt;
-
-unsafe_br()|raw
-<br />
-
-safe_br()|escape
-&lt;br /&gt;
-
-safe_br()|raw
-<br />
-
-unsafe_br()|escape
-&lt;br /&gt;
-
-
-autoescape js
-
-safe_br
-\x3Cbr\x20\x2F\x3E
---TEST--
-"autoescape" tag does not apply escaping on literals
---TEMPLATE--
-{% autoescape 'html' %}
-
-1. Simple literal
-{{ "<br />" }}
-
-2. Conditional expression with only literals
-{{ true ? "<br />" : "<br>" }}
-
-3. Conditional expression with a variable
-{{ true ? "<br />" : someVar }}
-
-4. Nested conditionals with only literals
-{{ true ? (true ? "<br />" : "<br>") : "\n" }}
-
-5. Nested conditionals with a variable
-{{ true ? (true ? "<br />" : someVar) : "\n" }}
-
-6. Nested conditionals with a variable marked safe
-{{ true ? (true ? "<br />" : someVar|raw) : "\n" }}
-
-{% endautoescape %}
---DATA--
-return array()
---EXPECT--
-
-1. Simple literal
-<br />
-
-2. Conditional expression with only literals
-<br />
-
-3. Conditional expression with a variable
-&lt;br /&gt;
-
-4. Nested conditionals with only literals
-<br />
-
-5. Nested conditionals with a variable
-&lt;br /&gt;
-
-6. Nested conditionals with a variable marked safe
-<br />
---TEST--
-"autoescape" tags can be nested at will
---TEMPLATE--
-{{ var }}
-{% autoescape 'html' %}
- {{ var }}
- {% autoescape false %}
- {{ var }}
- {% autoescape 'html' %}
- {{ var }}
- {% endautoescape %}
- {{ var }}
- {% endautoescape %}
- {{ var }}
-{% endautoescape %}
-{{ var }}
---DATA--
-return array('var' => '<br />')
---EXPECT--
-&lt;br /&gt;
- &lt;br /&gt;
- <br />
- &lt;br /&gt;
- <br />
- &lt;br /&gt;
-&lt;br /&gt;
---TEST--
-"autoescape" tag applies escaping to object method calls
---TEMPLATE--
-{% autoescape 'html' %}
-{{ user.name }}
-{{ user.name|lower }}
-{{ user }}
-{% endautoescape %}
---EXPECT--
-Fabien&lt;br /&gt;
-fabien&lt;br /&gt;
-Fabien&lt;br /&gt;
---TEST--
-"autoescape" tag does not escape when raw is used as a filter
---TEMPLATE--
-{% autoescape 'html' %}
-{{ var|raw }}
-{% endautoescape %}
---DATA--
-return array('var' => '<br />')
---EXPECT--
-<br />
---TEST--
-"autoescape" tag accepts an escaping strategy
---TEMPLATE--
-{% autoescape true js %}{{ var }}{% endautoescape %}
-
-{% autoescape true html %}{{ var }}{% endautoescape %}
-
-{% autoescape 'js' %}{{ var }}{% endautoescape %}
-
-{% autoescape 'html' %}{{ var }}{% endautoescape %}
---DATA--
-return array('var' => '<br />"')
---EXPECT--
-\x3Cbr\x20\x2F\x3E\x22
-&lt;br /&gt;&quot;
-\x3Cbr\x20\x2F\x3E\x22
-&lt;br /&gt;&quot;
---TEST--
-escape types
---TEMPLATE--
-
-1. autoescape 'html' |escape('js')
-
-{% autoescape 'html' %}
-<a onclick="alert(&quot;{{ msg|escape('js') }}&quot;)"></a>
-{% endautoescape %}
-
-2. autoescape 'html' |escape('js')
-
-{% autoescape 'html' %}
-<a onclick="alert(&quot;{{ msg|escape('js') }}&quot;)"></a>
-{% endautoescape %}
-
-3. autoescape 'js' |escape('js')
-
-{% autoescape 'js' %}
-<a onclick="alert(&quot;{{ msg|escape('js') }}&quot;)"></a>
-{% endautoescape %}
-
-4. no escape
-
-{% autoescape false %}
-<a onclick="alert(&quot;{{ msg }}&quot;)"></a>
-{% endautoescape %}
-
-5. |escape('js')|escape('html')
-
-{% autoescape false %}
-<a onclick="alert(&quot;{{ msg|escape('js')|escape('html') }}&quot;)"></a>
-{% endautoescape %}
-
-6. autoescape 'html' |escape('js')|escape('html')
-
-{% autoescape 'html' %}
-<a onclick="alert(&quot;{{ msg|escape('js')|escape('html') }}&quot;)"></a>
-{% endautoescape %}
-
---DATA--
-return array('msg' => "<>\n'\"")
---EXPECT--
-
-1. autoescape 'html' |escape('js')
-
-<a onclick="alert(&quot;\x3C\x3E\x0A\x27\x22&quot;)"></a>
-
-2. autoescape 'html' |escape('js')
-
-<a onclick="alert(&quot;\x3C\x3E\x0A\x27\x22&quot;)"></a>
-
-3. autoescape 'js' |escape('js')
-
-<a onclick="alert(&quot;\x3C\x3E\x0A\x27\x22&quot;)"></a>
-
-4. no escape
-
-<a onclick="alert(&quot;<>
-'"&quot;)"></a>
-
-5. |escape('js')|escape('html')
-
-<a onclick="alert(&quot;\x3C\x3E\x0A\x27\x22&quot;)"></a>
-
-6. autoescape 'html' |escape('js')|escape('html')
-
-<a onclick="alert(&quot;\x3C\x3E\x0A\x27\x22&quot;)"></a>
-
---TEST--
-"autoescape" tag do not applies escaping on filter arguments
---TEMPLATE--
-{% autoescape 'html' %}
-{{ var|nl2br("<br />") }}
-{{ var|nl2br("<br />"|escape) }}
-{{ var|nl2br(sep) }}
-{{ var|nl2br(sep|raw) }}
-{{ var|nl2br(sep|escape) }}
-{% endautoescape %}
---DATA--
-return array('var' => "<Fabien>\nTwig", 'sep' => '<br />')
---EXPECT--
-&lt;Fabien&gt;<br />
-Twig
-&lt;Fabien&gt;&lt;br /&gt;
-Twig
-&lt;Fabien&gt;<br />
-Twig
-&lt;Fabien&gt;<br />
-Twig
-&lt;Fabien&gt;&lt;br /&gt;
-Twig
---TEST--
-"autoescape" tag applies escaping after calling filters
---TEMPLATE--
-{% autoescape 'html' %}
-
-(escape_and_nl2br is an escaper filter)
-
-1. Don't escape escaper filter output
-( var is escaped by |escape_and_nl2br, line-breaks are added,
- the output is not escaped )
-{{ var|escape_and_nl2br }}
-
-2. Don't escape escaper filter output
-( var is escaped by |escape_and_nl2br, line-breaks are added,
- the output is not escaped, |raw is redundant )
-{{ var|escape_and_nl2br|raw }}
-
-3. Explicit escape
-( var is escaped by |escape_and_nl2br, line-breaks are added,
- the output is explicitly escaped by |escape )
-{{ var|escape_and_nl2br|escape }}
-
-4. Escape non-escaper filter output
-( var is upper-cased by |upper,
- the output is auto-escaped )
-{{ var|upper }}
-
-5. Escape if last filter is not an escaper
-( var is escaped by |escape_and_nl2br, line-breaks are added,
- the output is upper-cased by |upper,
- the output is auto-escaped as |upper is not an escaper )
-{{ var|escape_and_nl2br|upper }}
-
-6. Don't escape escaper filter output
-( var is upper cased by upper,
- the output is escaped by |escape_and_nl2br, line-breaks are added,
- the output is not escaped as |escape_and_nl2br is an escaper )
-{{ var|upper|escape_and_nl2br }}
-
-7. Escape if last filter is not an escaper
-( the output of |format is "<b>" ~ var ~ "</b>",
- the output is auto-escaped )
-{{ "<b>%s</b>"|format(var) }}
-
-8. Escape if last filter is not an escaper
-( the output of |format is "<b>" ~ var ~ "</b>",
- |raw is redundant,
- the output is auto-escaped )
-{{ "<b>%s</b>"|raw|format(var) }}
-
-9. Don't escape escaper filter output
-( the output of |format is "<b>" ~ var ~ "</b>",
- the output is not escaped due to |raw filter at the end )
-{{ "<b>%s</b>"|format(var)|raw }}
-
-10. Don't escape escaper filter output
-( the output of |format is "<b>" ~ var ~ "</b>",
- the output is not escaped due to |raw filter at the end,
- the |raw filter on var is redundant )
-{{ "<b>%s</b>"|format(var|raw)|raw }}
-
-{% endautoescape %}
---DATA--
-return array('var' => "<Fabien>\nTwig")
---EXPECT--
-
-(escape_and_nl2br is an escaper filter)
-
-1. Don't escape escaper filter output
-( var is escaped by |escape_and_nl2br, line-breaks are added,
- the output is not escaped )
-&lt;Fabien&gt;<br />
-Twig
-
-2. Don't escape escaper filter output
-( var is escaped by |escape_and_nl2br, line-breaks are added,
- the output is not escaped, |raw is redundant )
-&lt;Fabien&gt;<br />
-Twig
-
-3. Explicit escape
-( var is escaped by |escape_and_nl2br, line-breaks are added,
- the output is explicitly escaped by |escape )
-&amp;lt;Fabien&amp;gt;&lt;br /&gt;
-Twig
-
-4. Escape non-escaper filter output
-( var is upper-cased by |upper,
- the output is auto-escaped )
-&lt;FABIEN&gt;
-TWIG
-
-5. Escape if last filter is not an escaper
-( var is escaped by |escape_and_nl2br, line-breaks are added,
- the output is upper-cased by |upper,
- the output is auto-escaped as |upper is not an escaper )
-&amp;LT;FABIEN&amp;GT;&lt;BR /&gt;
-TWIG
-
-6. Don't escape escaper filter output
-( var is upper cased by upper,
- the output is escaped by |escape_and_nl2br, line-breaks are added,
- the output is not escaped as |escape_and_nl2br is an escaper )
-&lt;FABIEN&gt;<br />
-TWIG
-
-7. Escape if last filter is not an escaper
-( the output of |format is "<b>" ~ var ~ "</b>",
- the output is auto-escaped )
-&lt;b&gt;&lt;Fabien&gt;
-Twig&lt;/b&gt;
-
-8. Escape if last filter is not an escaper
-( the output of |format is "<b>" ~ var ~ "</b>",
- |raw is redundant,
- the output is auto-escaped )
-&lt;b&gt;&lt;Fabien&gt;
-Twig&lt;/b&gt;
-
-9. Don't escape escaper filter output
-( the output of |format is "<b>" ~ var ~ "</b>",
- the output is not escaped due to |raw filter at the end )
-<b><Fabien>
-Twig</b>
-
-10. Don't escape escaper filter output
-( the output of |format is "<b>" ~ var ~ "</b>",
- the output is not escaped due to |raw filter at the end,
- the |raw filter on var is redundant )
-<b><Fabien>
-Twig</b>
---TEST--
-"autoescape" tag applies escaping after calling filters, and before calling pre_escape filters
---TEMPLATE--
-{% autoescape 'html' %}
-
-(nl2br is pre_escaped for "html" and declared safe for "html")
-
-1. Pre-escape and don't post-escape
-( var|escape|nl2br )
-{{ var|nl2br }}
-
-2. Don't double-pre-escape
-( var|escape|nl2br )
-{{ var|escape|nl2br }}
-
-3. Don't escape safe values
-( var|raw|nl2br )
-{{ var|raw|nl2br }}
-
-4. Don't escape safe values
-( var|escape|nl2br|nl2br )
-{{ var|nl2br|nl2br }}
-
-5. Re-escape values that are escaped for an other contexts
-( var|escape_something|escape|nl2br )
-{{ var|escape_something|nl2br }}
-
-6. Still escape when using filters not declared safe
-( var|escape|nl2br|upper|escape )
-{{ var|nl2br|upper }}
-
-{% endautoescape %}
---DATA--
-return array('var' => "<Fabien>\nTwig")
---EXPECT--
-
-(nl2br is pre_escaped for "html" and declared safe for "html")
-
-1. Pre-escape and don't post-escape
-( var|escape|nl2br )
-&lt;Fabien&gt;<br />
-Twig
-
-2. Don't double-pre-escape
-( var|escape|nl2br )
-&lt;Fabien&gt;<br />
-Twig
-
-3. Don't escape safe values
-( var|raw|nl2br )
-<Fabien><br />
-Twig
-
-4. Don't escape safe values
-( var|escape|nl2br|nl2br )
-&lt;Fabien&gt;<br /><br />
-Twig
-
-5. Re-escape values that are escaped for an other contexts
-( var|escape_something|escape|nl2br )
-&lt;FABIEN&gt;<br />
-TWIG
-
-6. Still escape when using filters not declared safe
-( var|escape|nl2br|upper|escape )
-&amp;LT;FABIEN&amp;GT;&lt;BR /&gt;
-TWIG
-
---TEST--
-"autoescape" tag handles filters preserving the safety
---TEMPLATE--
-{% autoescape 'html' %}
-
-(preserves_safety is preserving safety for "html")
-
-1. Unsafe values are still unsafe
-( var|preserves_safety|escape )
-{{ var|preserves_safety }}
-
-2. Safe values are still safe
-( var|escape|preserves_safety )
-{{ var|escape|preserves_safety }}
-
-3. Re-escape values that are escaped for an other contexts
-( var|escape_something|preserves_safety|escape )
-{{ var|escape_something|preserves_safety }}
-
-4. Still escape when using filters not declared safe
-( var|escape|preserves_safety|replace({'FABIEN': 'FABPOT'})|escape )
-{{ var|escape|preserves_safety|replace({'FABIEN': 'FABPOT'}) }}
-
-{% endautoescape %}
---DATA--
-return array('var' => "<Fabien>\nTwig")
---EXPECT--
-
-(preserves_safety is preserving safety for "html")
-
-1. Unsafe values are still unsafe
-( var|preserves_safety|escape )
-&lt;FABIEN&gt;
-TWIG
-
-2. Safe values are still safe
-( var|escape|preserves_safety )
-&LT;FABIEN&GT;
-TWIG
-
-3. Re-escape values that are escaped for an other contexts
-( var|escape_something|preserves_safety|escape )
-&lt;FABIEN&gt;
-TWIG
-
-4. Still escape when using filters not declared safe
-( var|escape|preserves_safety|replace({'FABIEN': 'FABPOT'})|escape )
-&amp;LT;FABPOT&amp;GT;
-TWIG
-
---TEST--
-"block" tag
---TEMPLATE--
-{% block title1 %}FOO{% endblock %}
-{% block title2 foo|lower %}
---TEMPLATE(foo.twig)--
-{% block content %}{% endblock %}
---DATA--
-return array('foo' => 'bar')
---EXPECT--
-FOObar
---TEST--
-"block" tag
---TEMPLATE--
-{% block content %}
- {% block content %}
- {% endblock %}
-{% endblock %}
---DATA--
-return array()
---EXCEPTION--
-Twig_Error_Syntax: The block 'content' has already been defined line 2 in "index.twig" at line 3
---TEST--
-"§" special chars in a block name
---TEMPLATE--
-{% block § %}
-{% endblock § %}
---DATA--
-return array()
---EXPECT--
---TEST--
-"embed" tag
---TEMPLATE--
-FOO
-{% embed "foo.twig" %}
- {% block c1 %}
- {{ parent() }}
- block1extended
- {% endblock %}
-{% endembed %}
-
-BAR
---TEMPLATE(foo.twig)--
-A
-{% block c1 %}
- block1
-{% endblock %}
-B
-{% block c2 %}
- block2
-{% endblock %}
-C
---DATA--
-return array()
---EXPECT--
-FOO
-
-A
- block1
-
- block1extended
- B
- block2
-C
-BAR
---TEST--
-"embed" tag
---TEMPLATE(index.twig)--
-FOO
-{% embed "foo.twig" %}
- {% block c1 %}
- {{ nothing }}
- {% endblock %}
-{% endembed %}
-BAR
---TEMPLATE(foo.twig)--
-{% block c1 %}{% endblock %}
---DATA--
-return array()
---EXCEPTION--
-Twig_Error_Runtime: Variable "nothing" does not exist in "index.twig" at line 5
---TEST--
-"embed" tag
---TEMPLATE--
-FOO
-{% embed "foo.twig" %}
- {% block c1 %}
- {{ parent() }}
- block1extended
- {% endblock %}
-{% endembed %}
-
-{% embed "foo.twig" %}
- {% block c1 %}
- {{ parent() }}
- block1extended
- {% endblock %}
-{% endembed %}
-
-BAR
---TEMPLATE(foo.twig)--
-A
-{% block c1 %}
- block1
-{% endblock %}
-B
-{% block c2 %}
- block2
-{% endblock %}
-C
---DATA--
-return array()
---EXPECT--
-FOO
-
-A
- block1
-
- block1extended
- B
- block2
-C
-
-A
- block1
-
- block1extended
- B
- block2
-C
-BAR
---TEST--
-"embed" tag
---TEMPLATE--
-{% embed "foo.twig" %}
- {% block c1 %}
- {{ parent() }}
- {% embed "foo.twig" %}
- {% block c1 %}
- {{ parent() }}
- block1extended
- {% endblock %}
- {% endembed %}
-
- {% endblock %}
-{% endembed %}
---TEMPLATE(foo.twig)--
-A
-{% block c1 %}
- block1
-{% endblock %}
-B
-{% block c2 %}
- block2
-{% endblock %}
-C
---DATA--
-return array()
---EXPECT--
-A
- block1
-
-
-A
- block1
-
- block1extended
- B
- block2
-C
- B
- block2
-C
---TEST--
-"embed" tag
---TEMPLATE--
-{% extends "base.twig" %}
-
-{% block c1 %}
- {{ parent() }}
- blockc1baseextended
-{% endblock %}
-
-{% block c2 %}
- {{ parent() }}
-
- {% embed "foo.twig" %}
- {% block c1 %}
- {{ parent() }}
- block1extended
- {% endblock %}
- {% endembed %}
-{% endblock %}
---TEMPLATE(base.twig)--
-A
-{% block c1 %}
- blockc1base
-{% endblock %}
-{% block c2 %}
- blockc2base
-{% endblock %}
-B
---TEMPLATE(foo.twig)--
-A
-{% block c1 %}
- block1
-{% endblock %}
-B
-{% block c2 %}
- block2
-{% endblock %}
-C
---DATA--
-return array()
---EXPECT--
-A
- blockc1base
-
- blockc1baseextended
- blockc2base
-
-
-
-A
- block1
-
- block1extended
- B
- block2
-CB--TEST--
-"filter" tag applies a filter on its children
---TEMPLATE--
-{% filter upper %}
-Some text with a {{ var }}
-{% endfilter %}
---DATA--
-return array('var' => 'var')
---EXPECT--
-SOME TEXT WITH A VAR
---TEST--
-"filter" tag applies a filter on its children
---TEMPLATE--
-{% filter json_encode|raw %}test{% endfilter %}
---DATA--
-return array()
---EXPECT--
-"test"
---TEST--
-"filter" tags accept multiple chained filters
---TEMPLATE--
-{% filter lower|title %}
- {{ var }}
-{% endfilter %}
---DATA--
-return array('var' => 'VAR')
---EXPECT--
- Var
---TEST--
-"filter" tags can be nested at will
---TEMPLATE--
-{% filter lower|title %}
- {{ var }}
- {% filter upper %}
- {{ var }}
- {% endfilter %}
- {{ var }}
-{% endfilter %}
---DATA--
-return array('var' => 'var')
---EXPECT--
- Var
- Var
- Var
---TEST--
-"filter" tag applies the filter on "for" tags
---TEMPLATE--
-{% filter upper %}
-{% for item in items %}
-{{ item }}
-{% endfor %}
-{% endfilter %}
---DATA--
-return array('items' => array('a', 'b'))
---EXPECT--
-A
-B
---TEST--
-"filter" tag applies the filter on "if" tags
---TEMPLATE--
-{% filter upper %}
-{% if items %}
-{{ items|join(', ') }}
-{% endif %}
-
-{% if items.3 is defined %}
-FOO
-{% else %}
-{{ items.1 }}
-{% endif %}
-
-{% if items.3 is defined %}
-FOO
-{% elseif items.1 %}
-{{ items.0 }}
-{% endif %}
-
-{% endfilter %}
---DATA--
-return array('items' => array('a', 'b'))
---EXPECT--
-A, B
-
-B
-
-A
---TEST--
-"for" tag takes a condition
---TEMPLATE--
-{% for i in 1..5 if i is odd -%}
- {{ loop.index }}.{{ i }}{{ foo.bar }}
-{% endfor %}
---DATA--
-return array('foo' => array('bar' => 'X'))
---CONFIG--
-return array('strict_variables' => false)
---EXPECT--
-1.1X
-2.3X
-3.5X
---TEST--
-"for" tag keeps the context safe
---TEMPLATE--
-{% for item in items %}
- {% for item in items %}
- * {{ item }}
- {% endfor %}
- * {{ item }}
-{% endfor %}
---DATA--
-return array('items' => array('a', 'b'))
---EXPECT--
- * a
- * b
- * a
- * a
- * b
- * b
---TEST--
-"for" tag can use an "else" clause
---TEMPLATE--
-{% for item in items %}
- * {{ item }}
-{% else %}
- no item
-{% endfor %}
---DATA--
-return array('items' => array('a', 'b'))
---EXPECT--
- * a
- * b
---DATA--
-return array('items' => array())
---EXPECT--
- no item
---DATA--
-return array()
---CONFIG--
-return array('strict_variables' => false)
---EXPECT--
- no item
---TEST--
-"for" tag does not reset inner variables
---TEMPLATE--
-{% for i in 1..2 %}
- {% for j in 0..2 %}
- {{k}}{% set k = k+1 %} {{ loop.parent.loop.index }}
- {% endfor %}
-{% endfor %}
---DATA--
-return array('k' => 0)
---EXPECT--
- 0 1
- 1 1
- 2 1
- 3 2
- 4 2
- 5 2
---TEST--
-"for" tag can iterate over keys and values
---TEMPLATE--
-{% for key, item in items %}
- * {{ key }}/{{ item }}
-{% endfor %}
---DATA--
-return array('items' => array('a', 'b'))
---EXPECT--
- * 0/a
- * 1/b
---TEST--
-"for" tag can iterate over keys
---TEMPLATE--
-{% for key in items|keys %}
- * {{ key }}
-{% endfor %}
---DATA--
-return array('items' => array('a', 'b'))
---EXPECT--
- * 0
- * 1
---TEST--
-"for" tag adds a loop variable to the context locally
---TEMPLATE--
-{% for item in items %}
-{% endfor %}
-{% if loop is not defined %}WORKS{% endif %}
---DATA--
-return array('items' => array())
---EXPECT--
-WORKS
---TEST--
-"for" tag adds a loop variable to the context
---TEMPLATE--
-{% for item in items %}
- * {{ loop.index }}/{{ loop.index0 }}
- * {{ loop.revindex }}/{{ loop.revindex0 }}
- * {{ loop.first }}/{{ loop.last }}/{{ loop.length }}
-
-{% endfor %}
---DATA--
-return array('items' => array('a', 'b'))
---EXPECT--
- * 1/0
- * 2/1
- * 1//2
-
- * 2/1
- * 1/0
- * /1/2
---TEST--
-"for" tag
---TEMPLATE--
-{% for i, item in items if loop.last > 0 %}
-{% endfor %}
---DATA--
-return array('items' => array('a', 'b'))
---EXCEPTION--
-Twig_Error_Syntax: The "loop" variable cannot be used in a looping condition in "index.twig" at line 2
---TEST--
-"for" tag
---TEMPLATE--
-{% for i, item in items if i > 0 %}
- {{ loop.last }}
-{% endfor %}
---DATA--
-return array('items' => array('a', 'b'))
---EXCEPTION--
-Twig_Error_Syntax: The "loop.last" variable is not defined when looping with a condition in "index.twig" at line 3
---TEST--
-"for" tag can use an "else" clause
---TEMPLATE--
-{% for item in items %}
- {% for item in items1 %}
- * {{ item }}
- {% else %}
- no {{ item }}
- {% endfor %}
-{% else %}
- no item1
-{% endfor %}
---DATA--
-return array('items' => array('a', 'b'), 'items1' => array())
---EXPECT--
-no a
- no b
---TEST--
-"for" tag iterates over iterable and countable objects
---TEMPLATE--
-{% for item in items %}
- * {{ item }}
- * {{ loop.index }}/{{ loop.index0 }}
- * {{ loop.revindex }}/{{ loop.revindex0 }}
- * {{ loop.first }}/{{ loop.last }}/{{ loop.length }}
-
-{% endfor %}
-
-{% for key, value in items %}
- * {{ key }}/{{ value }}
-{% endfor %}
-
-{% for key in items|keys %}
- * {{ key }}
-{% endfor %}
---DATA--
-class ItemsIteratorCountable implements Iterator, Countable
-{
- protected $values = array('foo' => 'bar', 'bar' => 'foo');
- public function current() { return current($this->values); }
- public function key() { return key($this->values); }
- public function next() { return next($this->values); }
- public function rewind() { return reset($this->values); }
- public function valid() { return false !== current($this->values); }
- public function count() { return count($this->values); }
-}
-return array('items' => new ItemsIteratorCountable())
---EXPECT--
- * bar
- * 1/0
- * 2/1
- * 1//2
-
- * foo
- * 2/1
- * 1/0
- * /1/2
-
-
- * foo/bar
- * bar/foo
-
- * foo
- * bar
---TEST--
-"for" tag iterates over iterable objects
---TEMPLATE--
-{% for item in items %}
- * {{ item }}
- * {{ loop.index }}/{{ loop.index0 }}
- * {{ loop.first }}
-
-{% endfor %}
-
-{% for key, value in items %}
- * {{ key }}/{{ value }}
-{% endfor %}
-
-{% for key in items|keys %}
- * {{ key }}
-{% endfor %}
---DATA--
-class ItemsIterator implements Iterator
-{
- protected $values = array('foo' => 'bar', 'bar' => 'foo');
- public function current() { return current($this->values); }
- public function key() { return key($this->values); }
- public function next() { return next($this->values); }
- public function rewind() { return reset($this->values); }
- public function valid() { return false !== current($this->values); }
-}
-return array('items' => new ItemsIterator())
---EXPECT--
- * bar
- * 1/0
- * 1
-
- * foo
- * 2/1
- *
-
-
- * foo/bar
- * bar/foo
-
- * foo
- * bar
---TEST--
-"for" tags can be nested
---TEMPLATE--
-{% for key, item in items %}
-* {{ key }} ({{ loop.length }}):
-{% for value in item %}
- * {{ value }} ({{ loop.length }})
-{% endfor %}
-{% endfor %}
---DATA--
-return array('items' => array('a' => array('a1', 'a2', 'a3'), 'b' => array('b1')))
---EXPECT--
-* a (2):
- * a1 (3)
- * a2 (3)
- * a3 (3)
-* b (2):
- * b1 (1)
---TEST--
-"for" tag iterates over item values
---TEMPLATE--
-{% for item in items %}
- * {{ item }}
-{% endfor %}
---DATA--
-return array('items' => array('a', 'b'))
---EXPECT--
- * a
- * b
---TEST--
-global variables
---TEMPLATE--
-{% include "included.twig" %}
-{% from "included.twig" import foobar %}
-{{ foobar() }}
---TEMPLATE(included.twig)--
-{% macro foobar() %}
-called foobar
-{% endmacro %}
---DATA--
-return array();
---EXPECT--
-called foobar
---TEST--
-"if" creates a condition
---TEMPLATE--
-{% if a is defined %}
- {{ a }}
-{% elseif b is defined %}
- {{ b }}
-{% else %}
- NOTHING
-{% endif %}
---DATA--
-return array('a' => 'a')
---EXPECT--
- a
---DATA--
-return array('b' => 'b')
---EXPECT--
- b
---DATA--
-return array()
---EXPECT--
- NOTHING
---TEST--
-"if" takes an expression as a test
---TEMPLATE--
-{% if a < 2 %}
- A1
-{% elseif a > 10 %}
- A2
-{% else %}
- A3
-{% endif %}
---DATA--
-return array('a' => 1)
---EXPECT--
- A1
---DATA--
-return array('a' => 12)
---EXPECT--
- A2
---DATA--
-return array('a' => 7)
---EXPECT--
- A3
---TEST--
-"include" tag
---TEMPLATE--
-FOO
-{% include "foo.twig" %}
-
-BAR
---TEMPLATE(foo.twig)--
-FOOBAR
---DATA--
-return array()
---EXPECT--
-FOO
-
-FOOBAR
-BAR
---TEST--
-"include" tag allows expressions for the template to include
---TEMPLATE--
-FOO
-{% include foo %}
-
-BAR
---TEMPLATE(foo.twig)--
-FOOBAR
---DATA--
-return array('foo' => 'foo.twig')
---EXPECT--
-FOO
-
-FOOBAR
-BAR
---TEST--
-"include" tag
---TEMPLATE--
-{% include ["foo.twig", "bar.twig"] ignore missing %}
-{% include "foo.twig" ignore missing %}
-{% include "foo.twig" ignore missing with {} %}
-{% include "foo.twig" ignore missing with {} only %}
---DATA--
-return array()
---EXPECT--
---TEST--
-"include" tag
---TEMPLATE--
-{% extends "base.twig" %}
-
-{% block content %}
- {{ parent() }}
-{% endblock %}
---TEMPLATE(base.twig)--
-{% block content %}
- {% include "foo.twig" %}
-{% endblock %}
---DATA--
-return array();
---EXCEPTION--
-Twig_Error_Loader: Template "foo.twig" is not defined in "base.twig" at line 3.
---TEST--
-"include" tag
---TEMPLATE--
-{% include "foo.twig" %}
---DATA--
-return array();
---EXCEPTION--
-Twig_Error_Loader: Template "foo.twig" is not defined in "index.twig" at line 2.
---TEST--
-"include" tag accept variables and only
---TEMPLATE--
-{% include "foo.twig" %}
-{% include "foo.twig" only %}
-{% include "foo.twig" with {'foo1': 'bar'} %}
-{% include "foo.twig" with {'foo1': 'bar'} only %}
---TEMPLATE(foo.twig)--
-{% for k, v in _context %}{{ k }},{% endfor %}
---DATA--
-return array('foo' => 'bar')
---EXPECT--
-foo,global,_parent,
-global,_parent,
-foo,global,foo1,_parent,
-foo1,global,_parent,
---TEST--
-"include" tag accepts Twig_Template instance
---TEMPLATE--
-{% include foo %} FOO
---TEMPLATE(foo.twig)--
-BAR
---DATA--
-return array('foo' => $twig->loadTemplate('foo.twig'))
---EXPECT--
-BAR FOO
---TEST--
-"include" tag
---TEMPLATE--
-{% include ["foo.twig", "bar.twig"] %}
-{% include ["bar.twig", "foo.twig"] %}
---TEMPLATE(foo.twig)--
-foo
---DATA--
-return array()
---EXPECT--
-foo
-foo
---TEST--
-"include" tag accept variables
---TEMPLATE--
-{% include "foo.twig" with {'foo': 'bar'} %}
-{% include "foo.twig" with vars %}
---TEMPLATE(foo.twig)--
-{{ foo }}
---DATA--
-return array('vars' => array('foo' => 'bar'))
---EXPECT--
-bar
-bar
---TEST--
-"extends" tag
---TEMPLATE--
-{% extends "foo.twig" %}
-
-{% block content %}
-FOO
-{% endblock %}
---TEMPLATE(foo.twig)--
-{% block content %}{% endblock %}
---DATA--
-return array()
---EXPECT--
-FOO
---TEST--
-block_expr2
---TEMPLATE--
-{% extends "base2.twig" %}
-
-{% block element -%}
- Element:
- {{- parent() -}}
-{% endblock %}
---TEMPLATE(base2.twig)--
-{% extends "base.twig" %}
---TEMPLATE(base.twig)--
-{% spaceless %}
-{% block element -%}
- <div>
- {%- if item.children is defined %}
- {%- for item in item.children %}
- {{- block('element') -}}
- {% endfor %}
- {%- endif -%}
- </div>
-{%- endblock %}
-{% endspaceless %}
---DATA--
-return array(
- 'item' => array(
- 'children' => array(
- null,
- null,
- )
- )
-)
---EXPECT--
-Element:<div>Element:<div></div>Element:<div></div></div>
---TEST--
-block_expr
---TEMPLATE--
-{% extends "base.twig" %}
-
-{% block element -%}
- Element:
- {{- parent() -}}
-{% endblock %}
---TEMPLATE(base.twig)--
-{% spaceless %}
-{% block element -%}
- <div>
- {%- if item.children is defined %}
- {%- for item in item.children %}
- {{- block('element') -}}
- {% endfor %}
- {%- endif -%}
- </div>
-{%- endblock %}
-{% endspaceless %}
---DATA--
-return array(
- 'item' => array(
- 'children' => array(
- null,
- null,
- )
- )
-)
---EXPECT--
-Element:<div>Element:<div></div>Element:<div></div></div>
---TEST--
-"extends" tag
---TEMPLATE--
-{% extends standalone ? foo : 'bar.twig' %}
-
-{% block content %}{{ parent() }}FOO{% endblock %}
---TEMPLATE(foo.twig)--
-{% block content %}FOO{% endblock %}
---TEMPLATE(bar.twig)--
-{% block content %}BAR{% endblock %}
---DATA--
-return array('foo' => 'foo.twig', 'standalone' => true)
---EXPECT--
-FOOFOO
---TEST--
-"extends" tag
---TEMPLATE--
-{% extends foo %}
-
-{% block content %}
-FOO
-{% endblock %}
---TEMPLATE(foo.twig)--
-{% block content %}{% endblock %}
---DATA--
-return array('foo' => 'foo.twig')
---EXPECT--
-FOO
---TEST--
-"extends" tag
---TEMPLATE--
-{% extends "foo.twig" %}
---TEMPLATE(foo.twig)--
-{% block content %}FOO{% endblock %}
---DATA--
-return array()
---EXPECT--
-FOO
---TEST--
-"extends" tag
---TEMPLATE--
-{% extends ["foo.twig", "bar.twig"] %}
---TEMPLATE(bar.twig)--
-{% block content %}
-foo
-{% endblock %}
---DATA--
-return array()
---EXPECT--
-foo
---TEST--
-"extends" tag
---TEMPLATE--
-{% extends "layout.twig" %}{% block content %}{{ parent() }}index {% endblock %}
---TEMPLATE(layout.twig)--
-{% extends "base.twig" %}{% block content %}{{ parent() }}layout {% endblock %}
---TEMPLATE(base.twig)--
-{% block content %}base {% endblock %}
---DATA--
-return array()
---EXPECT--
-base layout index
---TEST--
-"block" tag
---TEMPLATE--
-{% block content %}
- CONTENT
- {%- block subcontent -%}
- SUBCONTENT
- {%- endblock -%}
- ENDCONTENT
-{% endblock %}
---TEMPLATE(foo.twig)--
---DATA--
-return array()
---EXPECT--
-CONTENTSUBCONTENTENDCONTENT
---TEST--
-"block" tag
---TEMPLATE--
-{% extends "foo.twig" %}
-
-{% block content %}
- {% block subcontent %}
- {% block subsubcontent %}
- SUBSUBCONTENT
- {% endblock %}
- {% endblock %}
-{% endblock %}
---TEMPLATE(foo.twig)--
-{% block content %}
- {% block subcontent %}
- SUBCONTENT
- {% endblock %}
-{% endblock %}
---DATA--
-return array()
---EXPECT--
-SUBSUBCONTENT
---TEST--
-"extends" tag
---TEMPLATE--
-{% extends "layout.twig" %}
-{% block inside %}INSIDE{% endblock inside %}
---TEMPLATE(layout.twig)--
-{% extends "base.twig" %}
-{% block body %}
- {% block inside '' %}
-{% endblock body %}
---TEMPLATE(base.twig)--
-{% block body '' %}
---DATA--
-return array()
---EXPECT--
-INSIDE
---TEST--
-"extends" tag
---TEMPLATE--
-{% extends foo ? 'foo.twig' : 'bar.twig' %}
---TEMPLATE(foo.twig)--
-FOO
---TEMPLATE(bar.twig)--
-BAR
---DATA--
-return array('foo' => true)
---EXPECT--
-FOO
---DATA--
-return array('foo' => false)
---EXPECT--
-BAR
---TEST--
-"extends" tag
---TEMPLATE--
-{% block content %}
- {% extends "foo.twig" %}
-{% endblock %}
---EXCEPTION--
-Twig_Error_Syntax: Cannot extend from a block in "index.twig" at line 3
---TEST--
-"extends" tag
---TEMPLATE--
-{% extends "base.twig" %}
-{% block content %}{% include "included.twig" %}{% endblock %}
-
-{% block footer %}Footer{% endblock %}
---TEMPLATE(included.twig)--
-{% extends "base.twig" %}
-{% block content %}Included Content{% endblock %}
---TEMPLATE(base.twig)--
-{% block content %}Default Content{% endblock %}
-
-{% block footer %}Default Footer{% endblock %}
---DATA--
-return array()
---EXPECT--
-Included Content
-Default Footer
-Footer
---TEST--
-"extends" tag
---TEMPLATE--
-{% extends "foo.twig" %}
-
-{% block content %}
- {% block inside %}
- INSIDE OVERRIDDEN
- {% endblock %}
-
- BEFORE
- {{ parent() }}
- AFTER
-{% endblock %}
---TEMPLATE(foo.twig)--
-{% block content %}
- BAR
-{% endblock %}
---DATA--
-return array()
---EXPECT--
-
-INSIDE OVERRIDDEN
-
- BEFORE
- BAR
-
- AFTER
---TEST--
-"extends" tag
---TEMPLATE--
-{% extends "foo.twig" %}
-
-{% block content %}{{ parent() }}FOO{{ parent() }}{% endblock %}
---TEMPLATE(foo.twig)--
-{% block content %}BAR{% endblock %}
---DATA--
-return array()
---EXPECT--
-BARFOOBAR
---TEST--
-"parent" tag
---TEMPLATE--
-{% use 'foo.twig' %}
-
-{% block content %}
- {{ parent() }}
-{% endblock %}
---TEMPLATE(foo.twig)--
-{% block content %}BAR{% endblock %}
---DATA--
-return array()
---EXPECT--
-BAR
---TEST--
-"parent" tag
---TEMPLATE--
-{% block content %}
- {{ parent() }}
-{% endblock %}
---EXCEPTION--
-Twig_Error_Syntax: Calling "parent" on a template that does not extend nor "use" another template is forbidden in "index.twig" at line 3
---TEST--
-"extends" tag accepts Twig_Template instance
---TEMPLATE--
-{% extends foo %}
-
-{% block content %}
-{{ parent() }}FOO
-{% endblock %}
---TEMPLATE(foo.twig)--
-{% block content %}BAR{% endblock %}
---DATA--
-return array('foo' => $twig->loadTemplate('foo.twig'))
---EXPECT--
-BARFOO
---TEST--
-"parent" function
---TEMPLATE--
-{% extends "parent.twig" %}
-
-{% use "use1.twig" %}
-{% use "use2.twig" %}
-
-{% block content_parent %}
- {{ parent() }}
-{% endblock %}
-
-{% block content_use1 %}
- {{ parent() }}
-{% endblock %}
-
-{% block content_use2 %}
- {{ parent() }}
-{% endblock %}
-
-{% block content %}
- {{ block('content_use1_only') }}
- {{ block('content_use2_only') }}
-{% endblock %}
---TEMPLATE(parent.twig)--
-{% block content_parent 'content_parent' %}
-{% block content_use1 'content_parent' %}
-{% block content_use2 'content_parent' %}
-{% block content '' %}
---TEMPLATE(use1.twig)--
-{% block content_use1 'content_use1' %}
-{% block content_use2 'content_use1' %}
-{% block content_use1_only 'content_use1_only' %}
---TEMPLATE(use2.twig)--
-{% block content_use2 'content_use2' %}
-{% block content_use2_only 'content_use2_only' %}
---DATA--
-return array()
---EXPECT--
- content_parent
- content_use1
- content_use2
- content_use1_only
- content_use2_only
---TEST--
-"macro" tag
---TEMPLATE--
-{% import _self as macros %}
-
-{{ macros.input('username') }}
-{{ macros.input('password', null, 'password', 1) }}
-
-{% macro input(name, value, type, size) %}
- <input type="{{ type|default("text") }}" name="{{ name }}" value="{{ value|e|default('') }}" size="{{ size|default(20) }}">
-{% endmacro %}
---DATA--
-return array()
---EXPECT--
- <input type="text" name="username" value="" size="20">
-
- <input type="password" name="password" value="" size="1">
---TEST--
-"macro" tag supports name for endmacro
---TEMPLATE--
-{% import _self as macros %}
-
-{{ macros.foo() }}
-{{ macros.bar() }}
-
-{% macro foo() %}foo{% endmacro %}
-{% macro bar() %}bar{% endmacro bar %}
---DATA--
-return array()
---EXPECT--
-foo
-bar
-
---TEST--
-"macro" tag
---TEMPLATE--
-{% import 'forms.twig' as forms %}
-
-{{ forms.input('username') }}
-{{ forms.input('password', null, 'password', 1) }}
---TEMPLATE(forms.twig)--
-{% macro input(name, value, type, size) %}
- <input type="{{ type|default("text") }}" name="{{ name }}" value="{{ value|e|default('') }}" size="{{ size|default(20) }}">
-{% endmacro %}
---DATA--
-return array()
---EXPECT--
- <input type="text" name="username" value="" size="20">
-
- <input type="password" name="password" value="" size="1">
---TEST--
-"macro" tag
---TEMPLATE--
-{% from 'forms.twig' import foo %}
-{% from 'forms.twig' import foo as foobar, bar %}
-
-{{ foo('foo') }}
-{{ foobar('foo') }}
-{{ bar('foo') }}
---TEMPLATE(forms.twig)--
-{% macro foo(name) %}foo{{ name }}{% endmacro %}
-{% macro bar(name) %}bar{{ name }}{% endmacro %}
---DATA--
-return array()
---EXPECT--
-foofoo
-foofoo
-barfoo
---TEST--
-"macro" tag
---TEMPLATE--
-{% from 'forms.twig' import foo %}
-
-{{ foo('foo') }}
-{{ foo() }}
---TEMPLATE(forms.twig)--
-{% macro foo(name) %}{{ name|default('foo') }}{{ global }}{% endmacro %}
---DATA--
-return array()
---EXPECT--
-fooglobal
-fooglobal
---TEST--
-"macro" tag
---TEMPLATE--
-{% import _self as forms %}
-
-{{ forms.input('username') }}
-{{ forms.input('password', null, 'password', 1) }}
-
-{% macro input(name, value, type, size) %}
- <input type="{{ type|default("text") }}" name="{{ name }}" value="{{ value|e|default('') }}" size="{{ size|default(20) }}">
-{% endmacro %}
---DATA--
-return array()
---EXPECT--
- <input type="text" name="username" value="" size="20">
-
- <input type="password" name="password" value="" size="1">
---TEST--
-"raw" tag
---TEMPLATE--
-{% raw %}
-{{ foo }}
-{% endraw %}
---DATA--
-return array()
---EXPECT--
-{{ foo }}
---TEST--
-"raw" tag
---TEMPLATE--
-{% raw %}
-{{ foo }}
-{% endverbatim %}
---DATA--
-return array()
---EXCEPTION--
-Twig_Error_Syntax: Unexpected end of file: Unclosed "raw" block in "index.twig" at line 2
---TEST--
-"raw" tag
---TEMPLATE--
-1***
-
-{%- raw %}
- {{ 'bla' }}
-{% endraw %}
-
-1***
-2***
-
-{%- raw -%}
- {{ 'bla' }}
-{% endraw %}
-
-2***
-3***
-
-{%- raw -%}
- {{ 'bla' }}
-{% endraw -%}
-
-3***
-4***
-
-{%- raw -%}
- {{ 'bla' }}
-{%- endraw %}
-
-4***
-5***
-
-{%- raw -%}
- {{ 'bla' }}
-{%- endraw -%}
-
-5***
---DATA--
-return array()
---EXPECT--
-1***
- {{ 'bla' }}
-
-
-1***
-2***{{ 'bla' }}
-
-
-2***
-3***{{ 'bla' }}
-3***
-4***{{ 'bla' }}
-
-4***
-5***{{ 'bla' }}5***
---TEST--
-sandbox tag
---TEMPLATE--
-{%- sandbox %}
- {%- include "foo.twig" %}
- a
-{%- endsandbox %}
---TEMPLATE(foo.twig)--
-foo
---EXCEPTION--
-Twig_Error_Syntax: Only "include" tags are allowed within a "sandbox" section in "index.twig" at line 4
---TEST--
-sandbox tag
---TEMPLATE--
-{%- sandbox %}
- {%- include "foo.twig" %}
-
- {% if 1 %}
- {%- include "foo.twig" %}
- {% endif %}
-{%- endsandbox %}
---TEMPLATE(foo.twig)--
-foo
---EXCEPTION--
-Twig_Error_Syntax: Only "include" tags are allowed within a "sandbox" section in "index.twig" at line 5
---TEST--
-sandbox tag
---TEMPLATE--
-{%- sandbox %}
- {%- include "foo.twig" %}
-{%- endsandbox %}
-
-{%- sandbox %}
- {%- include "foo.twig" %}
- {%- include "foo.twig" %}
-{%- endsandbox %}
-
-{%- sandbox %}{% include "foo.twig" %}{% endsandbox %}
---TEMPLATE(foo.twig)--
-foo
---DATA--
-return array()
---EXPECT--
-foo
-foo
-foo
-foo
---TEST--
-"set" tag
---TEMPLATE--
-{% set foo = 'foo' %}
-{% set bar = 'foo<br />' %}
-
-{{ foo }}
-{{ bar }}
-
-{% set foo, bar = 'foo', 'bar' %}
-
-{{ foo }}{{ bar }}
---DATA--
-return array()
---EXPECT--
-foo
-foo&lt;br /&gt;
-
-
-foobar
---TEST--
-"set" tag block empty capture
---TEMPLATE--
-{% set foo %}{% endset %}
-
-{% if foo %}FAIL{% endif %}
---DATA--
-return array()
---EXPECT--
---TEST--
-"set" tag block capture
---TEMPLATE--
-{% set foo %}f<br />o<br />o{% endset %}
-
-{{ foo }}
---DATA--
-return array()
---EXPECT--
-f<br />o<br />o
---TEST--
-"set" tag
---TEMPLATE--
-{% set foo, bar = 'foo' ~ 'bar', 'bar' ~ 'foo' %}
-
-{{ foo }}
-{{ bar }}
---DATA--
-return array()
---EXPECT--
-foobar
-barfoo
---TEST--
-"spaceless" tag removes whites between HTML tags
---TEMPLATE--
-{% spaceless %}
-
- <div> <div> foo </div> </div>
-
-{% endspaceless %}
---DATA--
-return array()
---EXPECT--
-<div><div> foo </div></div>
---TEST--
-"§" custom tag
---TEMPLATE--
-{% § %}
---DATA--
-return array()
---EXPECT--
---TEST--
-Whitespace trimming on tags.
---TEMPLATE--
-{{ 5 * '{#-'|length }}
-{{ '{{-'|length * 5 + '{%-'|length }}
-
-Trim on control tag:
-{% for i in range(1, 9) -%}
- {{ i }}
-{%- endfor %}
-
-
-Trim on output tag:
-{% for i in range(1, 9) %}
- {{- i -}}
-{% endfor %}
-
-
-Trim comments:
-
-{#- Invisible -#}
-
-After the comment.
-
-Trim leading space:
-{% if leading %}
-
- {{- leading }}
-{% endif %}
-
-{%- if leading %}
- {{- leading }}
-
-{%- endif %}
-
-
-Trim trailing space:
-{% if trailing -%}
- {{ trailing -}}
-
-{% endif -%}
-
-Combined:
-
-{%- if both -%}
-<ul>
- <li> {{- both -}} </li>
-</ul>
-
-{%- endif -%}
-
-end
---DATA--
-return array('leading' => 'leading space', 'trailing' => 'trailing space', 'both' => 'both')
---EXPECT--
-15
-18
-
-Trim on control tag:
-123456789
-
-Trim on output tag:
-123456789
-
-Trim comments:After the comment.
-
-Trim leading space:
-leading space
-leading space
-
-Trim trailing space:
-trailing spaceCombined:<ul>
- <li>both</li>
-</ul>end
---TEST--
-"use" tag
---TEMPLATE--
-{% use "blocks.twig" with content as foo %}
-
-{{ block('foo') }}
---TEMPLATE(blocks.twig)--
-{% block content 'foo' %}
---DATA--
-return array()
---EXPECT--
-foo
---TEST--
-"use" tag
---TEMPLATE--
-{% use "blocks.twig" %}
-
-{{ block('content') }}
---TEMPLATE(blocks.twig)--
-{% block content 'foo' %}
---DATA--
-return array()
---EXPECT--
-foo
---TEST--
-"use" tag
---TEMPLATE--
-{% use "foo.twig" %}
---TEMPLATE(foo.twig)--
-{% use "bar.twig" %}
---TEMPLATE(bar.twig)--
---DATA--
-return array()
---EXPECT--
---TEST--
-"use" tag
---TEMPLATE--
-{% use "foo.twig" %}
-
-{{ block('content') }}
-{{ block('foo') }}
-{{ block('bar') }}
---TEMPLATE(foo.twig)--
-{% use "bar.twig" %}
-
-{% block content 'foo' %}
-{% block foo 'foo' %}
---TEMPLATE(bar.twig)--
-{% block content 'bar' %}
-{% block bar 'bar' %}
---DATA--
-return array()
---EXPECT--
-foo
-foo
-bar
---TEST--
-"use" tag
---TEMPLATE--
-{% use "ancestor.twig" %}
-{% use "parent.twig" %}
-
-{{ block('container') }}
---TEMPLATE(parent.twig)--
-{% block sub_container %}
- <div class="overriden_sub_container">overriden sub_container</div>
-{% endblock %}
---TEMPLATE(ancestor.twig)--
-{% block container %}
- <div class="container">{{ block('sub_container') }}</div>
-{% endblock %}
-
-{% block sub_container %}
- <div class="sub_container">sub_container</div>
-{% endblock %}
---DATA--
-return array()
---EXPECT--
-<div class="container"> <div class="overriden_sub_container">overriden sub_container</div>
-</div>
---TEST--
-"use" tag
---TEMPLATE--
-{% use "parent.twig" %}
-
-{{ block('container') }}
---TEMPLATE(parent.twig)--
-{% use "ancestor.twig" %}
-
-{% block sub_container %}
- <div class="overriden_sub_container">overriden sub_container</div>
-{% endblock %}
---TEMPLATE(ancestor.twig)--
-{% block container %}
- <div class="container">{{ block('sub_container') }}</div>
-{% endblock %}
-
-{% block sub_container %}
- <div class="sub_container">sub_container</div>
-{% endblock %}
---DATA--
-return array()
---EXPECT--
-<div class="container"> <div class="overriden_sub_container">overriden sub_container</div>
-</div>
---TEST--
-"use" tag
---TEMPLATE--
-{% use "foo.twig" with content as foo_content %}
-{% use "bar.twig" %}
-
-{{ block('content') }}
-{{ block('foo') }}
-{{ block('bar') }}
-{{ block('foo_content') }}
---TEMPLATE(foo.twig)--
-{% block content 'foo' %}
-{% block foo 'foo' %}
---TEMPLATE(bar.twig)--
-{% block content 'bar' %}
-{% block bar 'bar' %}
---DATA--
-return array()
---EXPECT--
-bar
-foo
-bar
-foo
---TEST--
-"use" tag
---TEMPLATE--
-{% use "foo.twig" %}
-{% use "bar.twig" %}
-
-{{ block('content') }}
-{{ block('foo') }}
-{{ block('bar') }}
---TEMPLATE(foo.twig)--
-{% block content 'foo' %}
-{% block foo 'foo' %}
---TEMPLATE(bar.twig)--
-{% block content 'bar' %}
-{% block bar 'bar' %}
---DATA--
-return array()
---EXPECT--
-bar
-foo
-bar
---TEST--
-"use" tag
---TEMPLATE--
-{% use 'file2.html.twig'%}
-{% block foobar %}
- {{- parent() -}}
- Content of block (second override)
-{% endblock foobar %}
---TEMPLATE(file2.html.twig)--
-{% use 'file1.html.twig' %}
-{% block foobar %}
- {{- parent() -}}
- Content of block (first override)
-{% endblock foobar %}
---TEMPLATE(file1.html.twig)--
-{% block foobar -%}
- Content of block
-{% endblock foobar %}
---DATA--
-return array()
---EXPECT--
-Content of block
-Content of block (first override)
-Content of block (second override)
---TEST--
-"use" tag
---TEMPLATE--
-{% use 'file2.html.twig' %}
-{% use 'file1.html.twig' with foo %}
-{% block foo %}
- {{- parent() -}}
- Content of foo (second override)
-{% endblock foo %}
-{% block bar %}
- {{- parent() -}}
- Content of bar (second override)
-{% endblock bar %}
---TEMPLATE(file2.html.twig)--
-{% use 'file1.html.twig' %}
-{% block foo %}
- {{- parent() -}}
- Content of foo (first override)
-{% endblock foo %}
-{% block bar %}
- {{- parent() -}}
- Content of bar (first override)
-{% endblock bar %}
---TEMPLATE(file1.html.twig)--
-{% block foo -%}
- Content of foo
-{% endblock foo %}
-{% block bar -%}
- Content of bar
-{% endblock bar %}
---DATA--
-return array()
---EXPECT--
-Content of foo
-Content of foo (first override)
-Content of foo (second override)
-Content of bar
-Content of bar (second override)
---TEST--
-"use" tag
---TEMPLATE--
-{% use 'file2.html.twig' with foobar as base_base_foobar %}
-{% block foobar %}
- {{- block('base_base_foobar') -}}
- Content of block (second override)
-{% endblock foobar %}
---TEMPLATE(file2.html.twig)--
-{% use 'file1.html.twig' with foobar as base_foobar %}
-{% block foobar %}
- {{- block('base_foobar') -}}
- Content of block (first override)
-{% endblock foobar %}
---TEMPLATE(file1.html.twig)--
-{% block foobar -%}
- Content of block
-{% endblock foobar %}
---DATA--
-return array()
---EXPECT--
-Content of block
-Content of block (first override)
-Content of block (second override)
---TEST--
-"verbatim" tag
---TEMPLATE--
-{% verbatim %}
-{{ foo }}
-{% endverbatim %}
---DATA--
-return array()
---EXPECT--
-{{ foo }}
---TEST--
-"verbatim" tag
---TEMPLATE--
-{% verbatim %}
-{{ foo }}
-{% endraw %}
---DATA--
-return array()
---EXCEPTION--
-Twig_Error_Syntax: Unexpected end of file: Unclosed "verbatim" block in "index.twig" at line 2
---TEST--
-"verbatim" tag
---TEMPLATE--
-1***
-
-{%- verbatim %}
- {{ 'bla' }}
-{% endverbatim %}
-
-1***
-2***
-
-{%- verbatim -%}
- {{ 'bla' }}
-{% endverbatim %}
-
-2***
-3***
-
-{%- verbatim -%}
- {{ 'bla' }}
-{% endverbatim -%}
-
-3***
-4***
-
-{%- verbatim -%}
- {{ 'bla' }}
-{%- endverbatim %}
-
-4***
-5***
-
-{%- verbatim -%}
- {{ 'bla' }}
-{%- endverbatim -%}
-
-5***
---DATA--
-return array()
---EXPECT--
-1***
- {{ 'bla' }}
-
-
-1***
-2***{{ 'bla' }}
-
-
-2***
-3***{{ 'bla' }}
-3***
-4***{{ 'bla' }}
-
-4***
-5***{{ 'bla' }}5***
---TEST--
-array index test
---TEMPLATE--
-{% for key, value in days %}
-{{ key }}
-{% endfor %}
---DATA--
-return array('days' => array(
- 1 => array('money' => 9),
- 2 => array('money' => 21),
- 3 => array('money' => 38),
- 4 => array('money' => 6),
- 18 => array('money' => 6),
- 19 => array('money' => 3),
- 31 => array('money' => 11),
-));
---EXPECT--
-1
-2
-3
-4
-18
-19
-31
---TEST--
-"const" test
---TEMPLATE--
-{{ 8 is constant('E_NOTICE') ? 'ok' : 'no' }}
-{{ 'bar' is constant('TwigTestFoo::BAR_NAME') ? 'ok' : 'no' }}
-{{ value is constant('TwigTestFoo::BAR_NAME') ? 'ok' : 'no' }}
-{{ 2 is constant('ARRAY_AS_PROPS', object) ? 'ok' : 'no' }}
---DATA--
-return array('value' => 'bar', 'object' => new ArrayObject(array('hi')));
---EXPECT--
-ok
-ok
-ok
-ok--TEST--
-"defined" test
---TEMPLATE--
-{{ definedVar is defined ? 'ok' : 'ko' }}
-{{ definedVar is not defined ? 'ko' : 'ok' }}
-{{ undefinedVar is defined ? 'ko' : 'ok' }}
-{{ undefinedVar is not defined ? 'ok' : 'ko' }}
-{{ zeroVar is defined ? 'ok' : 'ko' }}
-{{ nullVar is defined ? 'ok' : 'ko' }}
-{{ nested.definedVar is defined ? 'ok' : 'ko' }}
-{{ nested['definedVar'] is defined ? 'ok' : 'ko' }}
-{{ nested.definedVar is not defined ? 'ko' : 'ok' }}
-{{ nested.undefinedVar is defined ? 'ko' : 'ok' }}
-{{ nested['undefinedVar'] is defined ? 'ko' : 'ok' }}
-{{ nested.undefinedVar is not defined ? 'ok' : 'ko' }}
-{{ nested.zeroVar is defined ? 'ok' : 'ko' }}
-{{ nested.nullVar is defined ? 'ok' : 'ko' }}
-{{ nested.definedArray.0 is defined ? 'ok' : 'ko' }}
-{{ nested['definedArray'][0] is defined ? 'ok' : 'ko' }}
-{{ object.foo is defined ? 'ok' : 'ko' }}
-{{ object.undefinedMethod is defined ? 'ko' : 'ok' }}
-{{ object.getFoo() is defined ? 'ok' : 'ko' }}
-{{ object.getFoo('a') is defined ? 'ok' : 'ko' }}
-{{ object.undefinedMethod() is defined ? 'ko' : 'ok' }}
-{{ object.undefinedMethod('a') is defined ? 'ko' : 'ok' }}
-{{ object.self.foo is defined ? 'ok' : 'ko' }}
-{{ object.self.undefinedMethod is defined ? 'ko' : 'ok' }}
-{{ object.undefinedMethod.self is defined ? 'ko' : 'ok' }}
---DATA--
-return array(
- 'definedVar' => 'defined',
- 'zeroVar' => 0,
- 'nullVar' => null,
- 'nested' => array(
- 'definedVar' => 'defined',
- 'zeroVar' => 0,
- 'nullVar' => null,
- 'definedArray' => array(0),
- ),
- 'object' => new TwigTestFoo(),
-);
---EXPECT--
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
---DATA--
-return array(
- 'definedVar' => 'defined',
- 'zeroVar' => 0,
- 'nullVar' => null,
- 'nested' => array(
- 'definedVar' => 'defined',
- 'zeroVar' => 0,
- 'nullVar' => null,
- 'definedArray' => array(0),
- ),
- 'object' => new TwigTestFoo(),
-);
---CONFIG--
-return array('strict_variables' => false)
---EXPECT--
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
-ok
---TEST--
-"empty" test
---TEMPLATE--
-{{ foo is empty ? 'ok' : 'ko' }}
-{{ bar is empty ? 'ok' : 'ko' }}
-{{ foobar is empty ? 'ok' : 'ko' }}
-{{ array is empty ? 'ok' : 'ko' }}
-{{ zero is empty ? 'ok' : 'ko' }}
-{{ string is empty ? 'ok' : 'ko' }}
-{{ countable_empty is empty ? 'ok' : 'ko' }}
-{{ countable_not_empty is empty ? 'ok' : 'ko' }}
-{{ markup_empty is empty ? 'ok' : 'ko' }}
-{{ markup_not_empty is empty ? 'ok' : 'ko' }}
---DATA--
-
-class CountableStub implements Countable
-{
- private $items;
-
- public function __construct(array $items)
- {
- $this->items = $items;
- }
-
- public function count()
- {
- return count($this->items);
- }
-}
-return array(
- 'foo' => '', 'bar' => null, 'foobar' => false, 'array' => array(), 'zero' => 0, 'string' => '0',
- 'countable_empty' => new CountableStub(array()), 'countable_not_empty' => new CountableStub(array(1, 2)),
- 'markup_empty' => new Twig_Markup('', 'UTF-8'), 'markup_not_empty' => new Twig_Markup('test', 'UTF-8'),
-);
---EXPECT--
-ok
-ok
-ok
-ok
-ko
-ko
-ok
-ko
-ok
-ko
---TEST--
-"even" test
---TEMPLATE--
-{{ 1 is even ? 'ko' : 'ok' }}
-{{ 2 is even ? 'ok' : 'ko' }}
-{{ 1 is not even ? 'ok' : 'ko' }}
-{{ 2 is not even ? 'ko' : 'ok' }}
---DATA--
-return array()
---EXPECT--
-ok
-ok
-ok
-ok
---TEST--
-Twig supports the in operator
---TEMPLATE--
-{% if bar in foo %}
-TRUE
-{% endif %}
-{% if not (bar in foo) %}
-{% else %}
-TRUE
-{% endif %}
-{% if bar not in foo %}
-{% else %}
-TRUE
-{% endif %}
-{% if 'a' in bar %}
-TRUE
-{% endif %}
-{% if 'c' not in bar %}
-TRUE
-{% endif %}
-{% if '' not in bar %}
-TRUE
-{% endif %}
-{% if '' in '' %}
-TRUE
-{% endif %}
-{% if '0' not in '' %}
-TRUE
-{% endif %}
-{% if 'a' not in '0' %}
-TRUE
-{% endif %}
-{% if '0' in '0' %}
-TRUE
-{% endif %}
-{{ false in [0, 1] ? 'TRUE' : 'FALSE' }}
-{{ true in [0, 1] ? 'TRUE' : 'FALSE' }}
-{{ '0' in [0, 1] ? 'TRUE' : 'FALSE' }}
-{{ '' in [0, 1] ? 'TRUE' : 'FALSE' }}
-{{ 0 in ['', 1] ? 'TRUE' : 'FALSE' }}
-{{ '' in 'foo' ? 'TRUE' : 'FALSE' }}
-{{ 0 in 'foo' ? 'TRUE' : 'FALSE' }}
-{{ false in 'foo' ? 'TRUE' : 'FALSE' }}
-{{ true in '100' ? 'TRUE' : 'FALSE' }}
-{{ [] in 'Array' ? 'TRUE' : 'FALSE' }}
-{{ [] in [true, false] ? 'TRUE' : 'FALSE' }}
-{{ [] in [true, ''] ? 'TRUE' : 'FALSE' }}
-{{ [] in [true, []] ? 'TRUE' : 'FALSE' }}
-{{ dir_object in 'foo'~dir_name ? 'TRUE' : 'FALSE' }}
-{{ 5 in 125 ? 'TRUE' : 'FALSE' }}
---DATA--
-return array('bar' => 'bar', 'foo' => array('bar' => 'bar'), 'dir_name' => dirname(__FILE__), 'dir_object' => new SplFileInfo(dirname(__FILE__)))
---EXPECT--
-TRUE
-TRUE
-TRUE
-TRUE
-TRUE
-TRUE
-TRUE
-TRUE
-TRUE
-FALSE
-FALSE
-FALSE
-FALSE
-FALSE
-TRUE
-FALSE
-FALSE
-FALSE
-FALSE
-FALSE
-FALSE
-TRUE
-FALSE
-FALSE
---TEST--
-Twig supports the in operator when using objects
---TEMPLATE--
-{% if object in object_list %}
-TRUE
-{% endif %}
---DATA--
-$foo = new TwigTestFoo();
-$foo1 = new TwigTestFoo();
-
-$foo->position = $foo1;
-$foo1->position = $foo;
-
-return array(
- 'object' => $foo,
- 'object_list' => array($foo1, $foo),
-);
---EXPECT--
-TRUE
---TEST--
-"iterable" test
---TEMPLATE--
-{{ foo is iterable ? 'ok' : 'ko' }}
-{{ traversable is iterable ? 'ok' : 'ko' }}
-{{ obj is iterable ? 'ok' : 'ko' }}
-{{ val is iterable ? 'ok' : 'ko' }}
---DATA--
-return array(
- 'foo' => array(),
- 'traversable' => new ArrayIterator(array()),
- 'obj' => new stdClass(),
- 'val' => 'test',
-);
---EXPECT--
-ok
-ok
-ko
-ko--TEST--
-"odd" test
---TEMPLATE--
-{{ 1 is odd ? 'ok' : 'ko' }}
-{{ 2 is odd ? 'ko' : 'ok' }}
---DATA--
-return array()
---EXPECT--
-ok
-ok