// ...
}
+Functional Tests
+~~~~~~~~~~~~~~~~
+
+You can create functional tests for extensions simply by creating the following file structure
+in your test directory::
+
+ Fixtures/
+ filters/
+ foo.test
+ bar.test
+ functions/
+ foo.test
+ bar.test
+ tags/
+ foo.test
+ bar.test
+ IntegrationTest.php
+
+The ``IntegrationTest.php`` file should look like this::
+
+ class Project_Tests_IntegrationTest extends Twig_Test_IntegrationTestCase
+ {
+ public function getExtensions()
+ {
+ return array(
+ new Project_Twig_Extension1(),
+ new Project_Twig_Extension2(),
+ );
+ }
+
+ public function getFixturesDir()
+ {
+ return dirname(__FILE__).'/Fixtures/';
+ }
+ }
+
+Fixtures examples can be found within the Twig repository ``tests/Twig/Fixtures`` directory.
+
+Node Tests
+~~~~~~~~~~
+
+Testing the node visitors can be complex, so extend your test cases from
+``Twig_Test_NodeTestCase``. Examples can be found in the Twig repository ``tests/Twig/Node`` directory.
+
.. _`spl_autoload_register()`: http://www.php.net/spl_autoload_register
.. _`rot13`: http://www.php.net/manual/en/function.str-rot13.php
+.. _`tests/Twig/Fixtures`: https://github.com/fabpot/Twig/tree/master/test/Twig/Tests/Fixtures
+.. _`tests/Twig/Node`: https://github.com/fabpot/Twig/tree/master/test/Twig/Tests/Node
--- /dev/null
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2010 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Integration test helper
+ *
+ * @package twig
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Karma Dordrak <drak@zikula.org>
+ */
+abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
+{
+ abstract protected function getExtensions();
+ abstract protected function getFixturesDir();
+
+ /**
+ * @dataProvider getTests
+ */
+ public function testIntegration($file, $message, $condition, $templates, $exception, $outputs)
+ {
+ $this->doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs);
+ }
+
+ public function getTests()
+ {
+ $fixturesDir = realpath($this->getFixturesDir());
+ $tests = array();
+
+ foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fixturesDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
+ if (!preg_match('/\.test$/', $file)) {
+ continue;
+ }
+
+ $test = file_get_contents($file->getRealpath());
+
+ if (preg_match('/
+ --TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)\s*(?:--DATA--\s*(.*))?\s*--EXCEPTION--\s*(.*)/sx', $test, $match)) {
+ $message = $match[1];
+ $condition = $match[2];
+ $templates = $this->parseTemplates($match[3]);
+ $exception = $match[5];
+ $outputs = array(array(null, $match[4], null, ''));
+ } elseif (preg_match('/--TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)--DATA--.*?--EXPECT--.*/s', $test, $match)) {
+ $message = $match[1];
+ $condition = $match[2];
+ $templates = $this->parseTemplates($match[3]);
+ $exception = false;
+ preg_match_all('/--DATA--(.*?)(?:--CONFIG--(.*?))?--EXPECT--(.*?)(?=\-\-DATA\-\-|$)/s', $test, $outputs, PREG_SET_ORDER);
+ } else {
+ throw new InvalidArgumentException(sprintf('Test "%s" is not valid.', str_replace($fixturesDir.'/', '', $file)));
+ }
+
+ $tests[] = array(str_replace($fixturesDir.'/', '', $file), $message, $condition, $templates, $exception, $outputs);
+ }
+
+ return $tests;
+ }
+
+ protected function doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs)
+ {
+ if ($condition) {
+ eval('$ret = '.$condition.';');
+ if (!$ret) {
+ $this->markTestSkipped($condition);
+ }
+ }
+
+ $loader = new Twig_Loader_Array($templates);
+
+ foreach ($outputs as $match) {
+ $config = array_merge(array(
+ 'cache' => false,
+ 'strict_variables' => true,
+ ), $match[2] ? eval($match[2].';') : array());
+ $twig = new Twig_Environment($loader, $config);
+ $twig->addGlobal('global', 'global');
+ foreach ($this->getExtensions() as $extension) {
+ $twig->addExtension($extension);
+ }
+
+ try {
+ $template = $twig->loadTemplate('index.twig');
+ } catch (Exception $e) {
+ if (false !== $exception) {
+ $this->assertEquals(trim($exception), trim(sprintf('%s: %s', get_class($e), $e->getMessage())));
+
+ return;
+ }
+
+ if ($e instanceof Twig_Error_Syntax) {
+ $e->setTemplateFile($file);
+
+ throw $e;
+ }
+
+ throw new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e);
+ }
+
+ try {
+ $output = trim($template->render(eval($match[1].';')), "\n ");
+ } catch (Exception $e) {
+ if (false !== $exception) {
+ $this->assertEquals(trim($exception), trim(sprintf('%s: %s', get_class($e), $e->getMessage())));
+
+ return;
+ }
+
+ if ($e instanceof Twig_Error_Syntax) {
+ $e->setTemplateFile($file);
+ } else {
+ $e = new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e);
+ }
+
+ $output = trim(sprintf('%s: %s', get_class($e), $e->getMessage()));
+ }
+
+ if (false !== $exception) {
+ list($class, ) = explode(':', $exception);
+ $this->assertThat(NULL, new PHPUnit_Framework_Constraint_Exception($class));
+ }
+
+ $expected = trim($match[3], "\n ");
+
+ if ($expected != $output) {
+ echo 'Compiled template that failed:';
+
+ foreach (array_keys($templates) as $name) {
+ echo "Template: $name\n";
+ $source = $loader->getSource($name);
+ echo $twig->compile($twig->parse($twig->tokenize($source, $name)));
+ }
+ }
+ $this->assertEquals($expected, $output, $message.' (in '.$file.')');
+ }
+ }
+
+ protected static function parseTemplates($test)
+ {
+ $templates = array();
+ preg_match_all('/--TEMPLATE(?:\((.*?)\))?--(.*?)(?=\-\-TEMPLATE|$)/s', $test, $matches, PREG_SET_ORDER);
+ foreach ($matches as $match) {
+ $templates[($match[1] ? $match[1] : 'index.twig')] = $match[2];
+ }
+
+ return $templates;
+ }
+}
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-abstract class Twig_Tests_Node_TestCase extends PHPUnit_Framework_TestCase
+abstract class Twig_Test_NodeTestCase extends PHPUnit_Framework_TestCase
{
abstract public function getTests();
{{ items.foo.in }}
{{ items.foo.not }}
--DATA--
-return array('foo' => 'bar', 'items' => array('foo' => new Foo(), 'bar' => 'foo'))
+return array('foo' => 'bar', 'items' => array('foo' => new TwigTestFoo(), 'bar' => 'foo'))
--CONFIG--
return array('strict_variables' => false)
--EXPECT--
'nullVar' => null,
'definedArray' => array(0),
),
- 'object' => new Foo(),
+ 'object' => new TwigTestFoo(),
)
--CONFIG--
return array('strict_variables' => false)
'nullVar' => null,
'definedArray' => array(0),
),
- 'object' => new Foo(),
+ 'object' => new TwigTestFoo(),
)
--CONFIG--
return array('strict_variables' => true)
{{ foo|join(', ') }}
{{ bar|join(', ') }}
--DATA--
-return array('foo' => new Foo(), 'bar' => new ArrayObject(array(3, 4)))
+return array('foo' => new TwigTestFoo(), 'bar' => new ArrayObject(array(3, 4)))
--EXPECT--
foo, bar
1, 2
{{ attribute(array, item) }}
{{ attribute(obj, "bar", ["a", "b"]) }}
--DATA--
-return array('obj' => new Foo(), 'method' => 'foo', 'array' => array('foo' => 'bar'), 'item' => 'foo')
+return array('obj' => new TwigTestFoo(), 'method' => 'foo', 'array' => array('foo' => 'bar'), 'item' => 'foo')
--EXPECT--
foo
bar
"const" test
--TEMPLATE--
{{ 8 is constant('E_NOTICE') ? 'ok' : 'no' }}
-{{ 'bar' is constant('Foo::BAR_NAME') ? 'ok' : 'no' }}
-{{ value is constant('Foo::BAR_NAME') ? 'ok' : 'no' }}
+{{ 'bar' is constant('TwigTestFoo::BAR_NAME') ? 'ok' : 'no' }}
+{{ value is constant('TwigTestFoo::BAR_NAME') ? 'ok' : 'no' }}
--DATA--
return array('value' => 'bar');
--EXPECT--
'nullVar' => null,
'definedArray' => array(0),
),
- 'object' => new Foo(),
+ 'object' => new TwigTestFoo(),
);
--EXPECT--
ok
'nullVar' => null,
'definedArray' => array(0),
),
- 'object' => new Foo(),
+ 'object' => new TwigTestFoo(),
);
--CONFIG--
return array('strict_variables' => false)
TRUE
{% endif %}
--DATA--
-$foo = new Foo();
-$foo1 = new Foo();
+$foo = new TwigTestFoo();
+$foo1 = new TwigTestFoo();
$foo->position = $foo1;
$foo1->position = $foo;
--- /dev/null
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+// This function is defined to check that escaping strategies
+// like html works even if a function with the same name is defined.
+function html()
+{
+ return 'foo';
+}
+
+class Twig_Tests_IntegrationTest extends Twig_Test_IntegrationTestCase
+{
+ public function getExtensions()
+ {
+ $policy = new Twig_Sandbox_SecurityPolicy(array(), array(), array(), array(), array());
+
+ return array(
+ new Twig_Extension_Debug(),
+ new Twig_Extension_Sandbox($policy, false),
+ new TwigTestExtension(),
+ );
+ }
+
+ public function getFixturesDir()
+ {
+ return dirname(__FILE__).'/Fixtures/';
+ }
+}
+
+function test_foo($value = 'foo')
+{
+ return $value;
+}
+
+class TwigTestFoo implements Iterator
+{
+ const BAR_NAME = 'bar';
+
+ public $position = 0;
+ public $array = array(1, 2);
+
+ public function bar($param1 = null, $param2 = null)
+ {
+ return 'bar'.($param1 ? '_'.$param1 : '').($param2 ? '-'.$param2 : '');
+ }
+
+ public function getFoo()
+ {
+ return 'foo';
+ }
+
+ public function getSelf()
+ {
+ return $this;
+ }
+
+ public function is()
+ {
+ return 'is';
+ }
+
+ public function in()
+ {
+ return 'in';
+ }
+
+ public function not()
+ {
+ return 'not';
+ }
+
+ public function strToLower($value)
+ {
+ return strtolower($value);
+ }
+
+ public function rewind()
+ {
+ $this->position = 0;
+ }
+
+ public function current()
+ {
+ return $this->array[$this->position];
+ }
+
+ public function key()
+ {
+ return 'a';
+ }
+
+ public function next()
+ {
+ ++$this->position;
+ }
+
+ public function valid()
+ {
+ return isset($this->array[$this->position]);
+ }
+}
+
+class TwigTestTokenParser_☃ extends Twig_TokenParser
+{
+ public function parse(Twig_Token $token)
+ {
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+
+ return new Twig_Node_Print(new Twig_Node_Expression_Constant('☃', -1), -1);
+ }
+
+ public function getTag()
+ {
+ return '☃';
+ }
+}
+
+class TwigTestExtension extends Twig_Extension
+{
+ public function getTokenParsers()
+ {
+ return array(
+ new TwigTestTokenParser_☃(),
+ );
+ }
+
+ public function getFilters()
+ {
+ return array(
+ '☃' => new Twig_Filter_Method($this, '☃Filter'),
+ 'escape_and_nl2br' => new Twig_Filter_Method($this, 'escape_and_nl2br', array('needs_environment' => true, 'is_safe' => array('html'))),
+ 'nl2br' => new Twig_Filter_Method($this, 'nl2br', array('pre_escape' => 'html', 'is_safe' => array('html'))),
+ 'escape_something' => new Twig_Filter_Method($this, 'escape_something', array('is_safe' => array('something'))),
+ 'preserves_safety' => new Twig_Filter_Method($this, 'preserves_safety', array('preserves_safety' => array('html'))),
+ '*_path' => new Twig_Filter_Method($this, 'dynamic_path'),
+ '*_foo_*_bar' => new Twig_Filter_Method($this, 'dynamic_foo'),
+ );
+ }
+
+ public function getFunctions()
+ {
+ return array(
+ '☃' => new Twig_Function_Method($this, '☃Function'),
+ 'safe_br' => new Twig_Function_Method($this, 'br', array('is_safe' => array('html'))),
+ 'unsafe_br' => new Twig_Function_Method($this, 'br'),
+ '*_path' => new Twig_Function_Method($this, 'dynamic_path'),
+ '*_foo_*_bar' => new Twig_Function_Method($this, 'dynamic_foo'),
+ );
+ }
+
+ public function ☃Filter($value)
+ {
+ return "☃{$value}☃";
+ }
+
+ public function ☃Function($value)
+ {
+ return "☃{$value}☃";
+ }
+
+ /**
+ * nl2br which also escapes, for testing escaper filters
+ */
+ public function escape_and_nl2br($env, $value, $sep = '<br />')
+ {
+ return $this->nl2br(twig_escape_filter($env, $value, 'html'), $sep);
+ }
+
+ /**
+ * nl2br only, for testing filters with pre_escape
+ */
+ public function nl2br($value, $sep = '<br />')
+ {
+ // not secure if $value contains html tags (not only entities)
+ // don't use
+ return str_replace("\n", "$sep\n", $value);
+ }
+
+ public function dynamic_path($element, $item)
+ {
+ return $element.'/'.$item;
+ }
+
+ public function dynamic_foo($foo, $bar, $item)
+ {
+ return $foo.'/'.$bar.'/'.$item;
+ }
+
+ public function escape_something($value)
+ {
+ return strtoupper($value);
+ }
+
+ public function preserves_safety($value)
+ {
+ return strtoupper($value);
+ }
+
+ public function br()
+ {
+ return '<br />';
+ }
+
+ public function getName()
+ {
+ return 'test';
+ }
+}
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/TestCase.php';
-class Twig_Tests_Node_AutoEscapeTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_AutoEscapeTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_AutoEscape::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/TestCase.php';
-class Twig_Tests_Node_BlockReferenceTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_BlockReferenceTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_BlockReference::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/TestCase.php';
-class Twig_Tests_Node_BlockTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_BlockTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Block::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/TestCase.php';
-class Twig_Tests_Node_DoTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_DoTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Do::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../TestCase.php';
-
-class Twig_Tests_Node_Expression_ArrayTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_ArrayTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Array::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../TestCase.php';
-
-class Twig_Tests_Node_Expression_AssignNameTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_AssignNameTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_AssignName::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../../TestCase.php';
-
-class Twig_Tests_Node_Expression_Binary_AddTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_Binary_AddTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Binary_Add::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../../TestCase.php';
-
-class Twig_Tests_Node_Expression_Binary_AndTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_Binary_AndTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Binary_And::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../../TestCase.php';
-
-class Twig_Tests_Node_Expression_Binary_ConcatTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_Binary_ConcatTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Binary_Concat::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../../TestCase.php';
-
-class Twig_Tests_Node_Expression_Binary_DivTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_Binary_DivTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Binary_Div::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../../TestCase.php';
-
-class Twig_Tests_Node_Expression_Binary_FloorDivTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_Binary_FloorDivTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Binary_FloorDiv::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../../TestCase.php';
-
-class Twig_Tests_Node_Expression_Binary_ModTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_Binary_ModTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Binary_Mod::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../../TestCase.php';
-
-class Twig_Tests_Node_Expression_Binary_MulTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_Binary_MulTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Binary_Mul::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../../TestCase.php';
-
-class Twig_Tests_Node_Expression_Binary_OrTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_Binary_OrTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Binary_Or::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../../TestCase.php';
-
-class Twig_Tests_Node_Expression_Binary_SubTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_Binary_SubTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Binary_Sub::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../TestCase.php';
-
-class Twig_Tests_Node_Expression_ConditionalTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_ConditionalTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Conditional::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../TestCase.php';
-
-class Twig_Tests_Node_Expression_ConstantTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_ConstantTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Constant::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../TestCase.php';
-
-class Twig_Tests_Node_Expression_FilterTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_FilterTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Filter::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../TestCase.php';
-
-class Twig_Tests_Node_Expression_FunctionTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_FunctionTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Function::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../TestCase.php';
-
-class Twig_Tests_Node_Expression_GetAttrTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_GetAttrTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_GetAttr::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../TestCase.php';
-
-class Twig_Tests_Node_Expression_NameTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_NameTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Name::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../TestCase.php';
-
-class Twig_Tests_Node_Expression_ParentTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_ParentTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Parent::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../TestCase.php';
-
-class Twig_Tests_Node_Expression_TestTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_TestTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Test::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../../TestCase.php';
-
-class Twig_Tests_Node_Expression_Unary_NegTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_Unary_NegTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Unary_Neg::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../../TestCase.php';
-
-class Twig_Tests_Node_Expression_Unary_NotTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_Unary_NotTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Unary_Not::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/../../TestCase.php';
-
-class Twig_Tests_Node_Expression_Unary_PosTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_Expression_Unary_PosTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Expression_Unary_Pos::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/TestCase.php';
-class Twig_Tests_Node_ForTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_ForTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_For::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/TestCase.php';
-class Twig_Tests_Node_IfTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_IfTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_If::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/TestCase.php';
-class Twig_Tests_Node_ImportTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_ImportTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Import::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/TestCase.php';
-class Twig_Tests_Node_IncludeTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_IncludeTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Include::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/TestCase.php';
-class Twig_Tests_Node_MacroTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_MacroTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Macro::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/TestCase.php';
-class Twig_Tests_Node_ModuleTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_ModuleTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Module::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/TestCase.php';
-class Twig_Tests_Node_PrintTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_PrintTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Print::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/TestCase.php';
-class Twig_Tests_Node_SandboxTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_SandboxTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Sandbox::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/TestCase.php';
-class Twig_Tests_Node_SandboxedModuleTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_SandboxedModuleTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_SandboxedModule::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/TestCase.php';
-class Twig_Tests_Node_SandboxedPrintTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_SandboxedPrintTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_SandboxedPrint::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/TestCase.php';
-class Twig_Tests_Node_SetTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_SetTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Set::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/TestCase.php';
-class Twig_Tests_Node_SpacelessTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_SpacelessTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Spaceless::__construct
* file that was distributed with this source code.
*/
-require_once dirname(__FILE__).'/TestCase.php';
-class Twig_Tests_Node_TextTest extends Twig_Tests_Node_TestCase
+class Twig_Tests_Node_TextTest extends Twig_Test_NodeTestCase
{
/**
* @covers Twig_Node_Text::__construct
+++ /dev/null
-<?php
-
-/*
- * This file is part of Twig.
- *
- * (c) Fabien Potencier
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-// This function is defined to check that escaping strategies
-// like html works even if a function with the same name is defined.
-function html()
-{
- return 'foo';
-}
-
-class Twig_Tests_IntegrationTest extends PHPUnit_Framework_TestCase
-{
- public function getTests()
- {
- $fixturesDir = realpath(dirname(__FILE__).'/Fixtures/');
- $tests = array();
-
- foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fixturesDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
- if (!preg_match('/\.test$/', $file)) {
- continue;
- }
-
- $test = file_get_contents($file->getRealpath());
-
- if (preg_match('/
- --TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)\s*(?:--DATA--\s*(.*))?\s*--EXCEPTION--\s*(.*)/sx', $test, $match)) {
- $message = $match[1];
- $condition = $match[2];
- $templates = $this->parseTemplates($match[3]);
- $exception = $match[5];
- $outputs = array(array(null, $match[4], null, ''));
- } elseif (preg_match('/--TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)--DATA--.*?--EXPECT--.*/s', $test, $match)) {
- $message = $match[1];
- $condition = $match[2];
- $templates = $this->parseTemplates($match[3]);
- $exception = false;
- preg_match_all('/--DATA--(.*?)(?:--CONFIG--(.*?))?--EXPECT--(.*?)(?=\-\-DATA\-\-|$)/s', $test, $outputs, PREG_SET_ORDER);
- } else {
- throw new InvalidArgumentException(sprintf('Test "%s" is not valid.', str_replace($fixturesDir.'/', '', $file)));
- }
-
- $tests[] = array(str_replace($fixturesDir.'/', '', $file), $message, $condition, $templates, $exception, $outputs);
- }
-
- return $tests;
- }
-
- /**
- * @dataProvider getTests
- */
- public function testIntegration($file, $message, $condition, $templates, $exception, $outputs)
- {
- if ($condition) {
- eval('$ret = '.$condition.';');
- if (!$ret) {
- $this->markTestSkipped($condition);
- }
- }
-
- $loader = new Twig_Loader_Array($templates);
-
- foreach ($outputs as $match) {
- $config = array_merge(array(
- 'cache' => false,
- 'strict_variables' => true,
- ), $match[2] ? eval($match[2].';') : array());
- $twig = new Twig_Environment($loader, $config);
- $twig->addExtension(new TestExtension());
- $twig->addExtension(new Twig_Extension_Debug());
- $policy = new Twig_Sandbox_SecurityPolicy(array(), array(), array(), array(), array());
- $twig->addExtension(new Twig_Extension_Sandbox($policy, false));
- $twig->addGlobal('global', 'global');
-
- try {
- $template = $twig->loadTemplate('index.twig');
- } catch (Exception $e) {
- if (false !== $exception) {
- $this->assertEquals(trim($exception), trim(sprintf('%s: %s', get_class($e), $e->getMessage())));
-
- return;
- }
-
- if ($e instanceof Twig_Error_Syntax) {
- $e->setTemplateFile($file);
-
- throw $e;
- }
-
- throw new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e);
- }
-
- try {
- $output = trim($template->render(eval($match[1].';')), "\n ");
- } catch (Exception $e) {
- if (false !== $exception) {
- $this->assertEquals(trim($exception), trim(sprintf('%s: %s', get_class($e), $e->getMessage())));
-
- return;
- }
-
- if ($e instanceof Twig_Error_Syntax) {
- $e->setTemplateFile($file);
- } else {
- $e = new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e);
- }
-
- $output = trim(sprintf('%s: %s', get_class($e), $e->getMessage()));
- }
-
- if (false !== $exception) {
- list($class, ) = explode(':', $exception);
- $this->assertThat(NULL, new PHPUnit_Framework_Constraint_Exception($class));
- }
-
- $expected = trim($match[3], "\n ");
-
- if ($expected != $output) {
- echo 'Compiled template that failed:';
-
- foreach (array_keys($templates) as $name) {
- echo "Template: $name\n";
- $source = $loader->getSource($name);
- echo $twig->compile($twig->parse($twig->tokenize($source, $name)));
- }
- }
- $this->assertEquals($expected, $output, $message.' (in '.$file.')');
- }
- }
-
- protected function parseTemplates($test)
- {
- $templates = array();
- preg_match_all('/--TEMPLATE(?:\((.*?)\))?--(.*?)(?=\-\-TEMPLATE|$)/s', $test, $matches, PREG_SET_ORDER);
- foreach ($matches as $match) {
- $templates[($match[1] ? $match[1] : 'index.twig')] = $match[2];
- }
-
- return $templates;
- }
-}
-
-function test_foo($value = 'foo')
-{
- return $value;
-}
-
-class Foo implements Iterator
-{
- const BAR_NAME = 'bar';
-
- public $position = 0;
- public $array = array(1, 2);
-
- public function bar($param1 = null, $param2 = null)
- {
- return 'bar'.($param1 ? '_'.$param1 : '').($param2 ? '-'.$param2 : '');
- }
-
- public function getFoo()
- {
- return 'foo';
- }
-
- public function getSelf()
- {
- return $this;
- }
-
- public function is()
- {
- return 'is';
- }
-
- public function in()
- {
- return 'in';
- }
-
- public function not()
- {
- return 'not';
- }
-
- public function strToLower($value)
- {
- return strtolower($value);
- }
-
- public function rewind()
- {
- $this->position = 0;
- }
-
- public function current()
- {
- return $this->array[$this->position];
- }
-
- public function key()
- {
- return 'a';
- }
-
- public function next()
- {
- ++$this->position;
- }
-
- public function valid()
- {
- return isset($this->array[$this->position]);
- }
-}
-
-class TestTokenParser_☃ extends Twig_TokenParser
-{
- public function parse(Twig_Token $token)
- {
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
-
- return new Twig_Node_Print(new Twig_Node_Expression_Constant('☃', -1), -1);
- }
-
- public function getTag()
- {
- return '☃';
- }
-}
-
-class TestExtension extends Twig_Extension
-{
- public function getTokenParsers()
- {
- return array(
- new TestTokenParser_☃(),
- );
- }
-
- public function getFilters()
- {
- return array(
- '☃' => new Twig_Filter_Method($this, '☃Filter'),
- 'escape_and_nl2br' => new Twig_Filter_Method($this, 'escape_and_nl2br', array('needs_environment' => true, 'is_safe' => array('html'))),
- 'nl2br' => new Twig_Filter_Method($this, 'nl2br', array('pre_escape' => 'html', 'is_safe' => array('html'))),
- 'escape_something' => new Twig_Filter_Method($this, 'escape_something', array('is_safe' => array('something'))),
- 'preserves_safety' => new Twig_Filter_Method($this, 'preserves_safety', array('preserves_safety' => array('html'))),
- '*_path' => new Twig_Filter_Method($this, 'dynamic_path'),
- '*_foo_*_bar' => new Twig_Filter_Method($this, 'dynamic_foo'),
- );
- }
-
- public function getFunctions()
- {
- return array(
- '☃' => new Twig_Function_Method($this, '☃Function'),
- 'safe_br' => new Twig_Function_Method($this, 'br', array('is_safe' => array('html'))),
- 'unsafe_br' => new Twig_Function_Method($this, 'br'),
- '*_path' => new Twig_Function_Method($this, 'dynamic_path'),
- '*_foo_*_bar' => new Twig_Function_Method($this, 'dynamic_foo'),
- );
- }
-
- public function ☃Filter($value)
- {
- return "☃{$value}☃";
- }
-
- public function ☃Function($value)
- {
- return "☃{$value}☃";
- }
-
- /**
- * nl2br which also escapes, for testing escaper filters
- */
- public function escape_and_nl2br($env, $value, $sep = '<br />')
- {
- return $this->nl2br(twig_escape_filter($env, $value, 'html'), $sep);
- }
-
- /**
- * nl2br only, for testing filters with pre_escape
- */
- public function nl2br($value, $sep = '<br />')
- {
- // not secure if $value contains html tags (not only entities)
- // don't use
- return str_replace("\n", "$sep\n", $value);
- }
-
- public function dynamic_path($element, $item)
- {
- return $element.'/'.$item;
- }
-
- public function dynamic_foo($foo, $bar, $item)
- {
- return $foo.'/'.$bar.'/'.$item;
- }
-
- public function escape_something($value)
- {
- return strtoupper($value);
- }
-
- public function preserves_safety($value)
- {
- return strtoupper($value);
- }
-
- public function br()
- {
- return '<br />';
- }
-
- public function getName()
- {
- return 'test';
- }
-}