1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-06-05 05:55:15 +02:00
php-phpbb/tests/template/template_test.php
Oleg Pudeyev a2c75f6053 [feature/template-engine] Deleted $template from phpbb_template_compile class.
phpbb_template_compile is now much simpler. It takes complete file paths
as inputs, either source template path or source template path and output
compiled template path. The number of methods also went down to two -
compile template and returned compiled text or compile and write to file.

phpbb_compile class is responsible for determining source and compiled
paths. It already had all the data necessary for this, now the code is
in the same place as the data it uses.

PHPBB3-9726
2011-04-24 21:18:18 -04:00

533 lines
12 KiB
PHP

<?php
/**
*
* @package testing
* @copyright (c) 2008 phpBB Group
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/
require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
require_once dirname(__FILE__) . '/../../phpBB/includes/template.php';
class phpbb_template_template_test extends phpbb_test_case
{
private $template;
private $template_path;
// Keep the contents of the cache for debugging?
const PRESERVE_CACHE = true;
private function display($handle)
{
ob_start();
$this->assertTrue($this->template->display($handle, false));
return self::trim_template_result(ob_get_clean());
}
private static function trim_template_result($result)
{
return str_replace("\n\n", "\n", implode("\n", array_map('trim', explode("\n", trim($result)))));
}
private function setup_engine()
{
$this->template_path = dirname(__FILE__) . '/templates';
$this->template = new template();
$this->template->set_custom_template($this->template_path, 'tests');
}
protected function setUp()
{
// $this->markTestIncomplete("template::display raises notices.");
// Test the engine can be used
$this->setup_engine();
if (!is_writable(dirname($this->template->cachepath)))
{
$this->markTestSkipped("Template cache directory is not writable.");
}
foreach (glob($this->template->cachepath . '*') as $file)
{
unlink($file);
}
$GLOBALS['config'] = array(
'load_tplcompile' => true,
'tpl_allow_php' => false,
);
}
protected function tearDown()
{
if (is_object($this->template))
{
foreach (glob($this->template->cachepath . '*') as $file)
{
unlink($file);
}
}
}
/**
* @todo put test data into templates/xyz.test
*/
public static function template_data()
{
return array(
/*
array(
'', // File
array(), // vars
array(), // block vars
array(), // destroy
'', // Expected result
),
*/
array(
'basic.html',
array(),
array(),
array(),
"pass\npass\n<!-- DUMMY var -->",
),
array(
'variable.html',
array('VARIABLE' => 'value'),
array(),
array(),
'value',
),
array(
'if.html',
array(),
array(),
array(),
'03',
),
array(
'if.html',
array('S_VALUE' => true),
array(),
array(),
'1',
),
array(
'if.html',
array('S_VALUE' => true, 'S_OTHER_VALUE' => true),
array(),
array(),
'1',
),
array(
'if.html',
array('S_VALUE' => false, 'S_OTHER_VALUE' => true),
array(),
array(),
'2',
),
array(
'loop.html',
array(),
array(),
array(),
"noloop\nnoloop",
),
array(
'loop.html',
array(),
array('loop' => array(array())),
array(),
"loop\nloop",
),
array(
'loop.html',
array(),
array('loop' => array(array(), array()), 'loop.block' => array(array())),
array(),
"loop\nloop\nloop\nloop",
),
array(
'loop.html',
array(),
array('loop' => array(array(), array()), 'loop.block' => array(array()), 'block' => array(array(), array())),
array(),
"loop\nloop\nloop\nloop\nloop#0-block#0\nloop#0-block#1\nloop#1-block#0\nloop#1-block#1",
),
array(
'loop_vars.html',
array(),
array('loop' => array(array('VARIABLE' => 'x'))),
array(),
"first\n0 - a\nx - b\nset\nlast",
),
array(
'loop_vars.html',
array(),
array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y'))),
array(),
"first\n0 - a\nx - b\nset\n1 - a\ny - b\nset\nlast",
),
array(
'loop_vars.html',
array(),
array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y')), 'loop.inner' => array(array(), array())),
array(),
"first\n0 - a\nx - b\nset\n1 - a\ny - b\nset\nlast\n0 - c\n1 - c\nlast inner\ninner loop",
),
array(
'loop_advanced.html',
array(),
array('loop' => array(array(), array(), array(), array(), array(), array(), array())),
array(),
"101234561\nx\n101234561\nx\n101234561\nx\n1234561\nx\n1\nx\n101\nx\n234\nx\n10\nx\n561\nx\n561",
),
array(
'define.html',
array(),
array('loop' => array(array(), array(), array(), array(), array(), array(), array()), 'test' => array(array()), 'test.deep' => array(array()), 'test.deep.defines' => array(array())),
array(),
"xyz\nabc",
),
array(
'expressions.html',
array(),
array(),
array(),
trim(str_repeat("pass\n", 10) . "\n"
. str_repeat("pass\n", 4) . "\n"
. str_repeat("pass\n", 2) . "\n"
. str_repeat("pass\n", 6) . "\n"
. str_repeat("pass\n", 2) . "\n"
. str_repeat("pass\n", 6) . "\n"
. str_repeat("pass\n", 2) . "\n"
. str_repeat("pass\n", 2) . "\n"
. str_repeat("pass\n", 3) . "\n"
. str_repeat("pass\n", 2) . "\n"),
),
array(
'php.html',
array(),
array(),
array(),
'',
),
array(
'include.html',
array('VARIABLE' => 'value'),
array(),
array(),
'value',
),
array(
'loop_vars.html',
array(),
array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y')), 'loop.inner' => array(array(), array())),
array('loop'),
'',
),/* no top level nested loops
array(
'loop_vars.html',
array(),
array('loop' => array(array('VARIABLE' => 'x'), array('VARIABLE' => 'y')), 'loop.inner' => array(array(), array())),
array('loop.inner'),
"first\n0\n0\n2\nx\nset\n1\n1\n2\ny\nset\nlast",
),*/
array(
// Just like a regular loop but the name begins
// with an underscore
'loop_underscore.html',
array(),
array(),
array(),
"noloop\nnoloop",
),
array(
'lang.html',
array(),
array(),
array(),
"{ VARIABLE }\n{ VARIABLE }",
),
array(
'lang.html',
array('L_VARIABLE' => "Value'"),
array(),
array(),
"Value'\nValue\'",
),
array(
'lang.html',
array('LA_VARIABLE' => "Value'"),
array(),
array(),
"{ VARIABLE }\nValue'",
),
);
}
public function test_missing_file()
{
$filename = 'file_not_found.html';
$this->template->set_filenames(array('test' => $filename));
$this->assertFileNotExists($this->template_path . '/' . $filename, 'Testing missing file, file cannot exist');
$expecting = sprintf('_source_file_for_handle(): File %s does not exist', realpath($this->template_path . '/../') . '/templates/' . $filename);
$this->setExpectedTriggerError(E_USER_ERROR, $expecting);
$this->display('test');
}
public function test_empty_file()
{
$expecting = 'template->set_filenames: Empty filename specified for test';
$this->setExpectedTriggerError(E_USER_ERROR, $expecting);
$this->template->set_filenames(array('test' => ''));
}
public function test_invalid_handle()
{
$expecting = 'template->_tpl_load(): No file specified for handle test';
$this->setExpectedTriggerError(E_USER_ERROR, $expecting);
$this->display('test');
}
private function run_template($file, array $vars, array $block_vars, array $destroy, $expected, $cache_file)
{
$this->template->set_filenames(array('test' => $file));
$this->template->assign_vars($vars);
foreach ($block_vars as $block => $loops)
{
foreach ($loops as $_vars)
{
$this->template->assign_block_vars($block, $_vars);
}
}
foreach ($destroy as $block)
{
$this->template->destroy_block_vars($block);
}
try
{
$this->assertEquals($expected, $this->display('test'), "Testing $file");
$this->assertFileExists($cache_file);
}
catch (ErrorException $e)
{
if (file_exists($cache_file))
{
copy($cache_file, str_replace('ctpl_', 'tests_ctpl_', $cache_file));
}
throw $e;
}
// TODO: Figure out why this wasn't considered.
catch (Exception $e)
{
}
// For debugging
if (self::PRESERVE_CACHE)
{
copy($cache_file, str_replace('ctpl_', 'tests_ctpl_', $cache_file));
}
}
/**
* @dataProvider template_data
*/
public function test_template($file, array $vars, array $block_vars, array $destroy, $expected)
{
$cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.php';
$this->assertFileNotExists($cache_file);
$this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file);
// Reset the engine state
$this->setup_engine();
$this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file);
}
/**
* @dataProvider template_data
*/
public function test_assign_display($file, array $vars, array $block_vars, array $destroy, $expected)
{
$this->template->set_filenames(array(
'test' => $file,
'container' => 'variable.html',
));
$this->template->assign_vars($vars);
foreach ($block_vars as $block => $loops)
{
foreach ($loops as $_vars)
{
$this->template->assign_block_vars($block, $_vars);
}
}
foreach ($destroy as $block)
{
$this->template->destroy_block_vars($block);
}
$error_level = error_reporting();
error_reporting($error_level & ~E_NOTICE);
$this->assertEquals($expected, self::trim_template_result($this->template->assign_display('test')), "Testing assign_display($file)");
$this->template->assign_display('test', 'VARIABLE', false);
error_reporting($error_level);
$this->assertEquals($expected, $this->display('container'), "Testing assign_display($file)");
}
public function test_php()
{
$GLOBALS['config']['tpl_allow_php'] = true;
$cache_file = $this->template->cachepath . 'php.html.php';
$this->assertFileNotExists($cache_file);
$this->run_template('php.html', array(), array(), array(), 'test', $cache_file);
$GLOBALS['config']['tpl_allow_php'] = false;
}
public function test_includephp()
{
$GLOBALS['config']['tpl_allow_php'] = true;
$cache_file = $this->template->cachepath . 'includephp.html.php';
$this->run_template('includephp.html', array(), array(), array(), 'testing included php', $cache_file);
$this->template->set_filenames(array('test' => 'includephp.html'));
$this->assertEquals('testing included php', $this->display('test'), "Testing INCLUDEPHP");
$GLOBALS['config']['tpl_allow_php'] = false;
}
public static function alter_block_array_data()
{
return array(
array(
'outer',
array('VARIABLE' => 'before'),
false,
'insert',
<<<EOT
outer - 0 - before
outer - 1
middle - 0
middle - 1
outer - 2
middle - 0
middle - 1
outer - 3
middle - 0
middle - 1
EOT
,
'Test inserting before on top level block',
),
array(
'outer',
array('VARIABLE' => 'after'),
true,
'insert',
<<<EOT
outer - 0
middle - 0
middle - 1
outer - 1
middle - 0
middle - 1
outer - 2
middle - 0
middle - 1
outer - 3 - after
EOT
,
'Test inserting after on top level block',
),
array(
'outer',
array('VARIABLE' => 'pos #1'),
1,
'insert',
<<<EOT
outer - 0
middle - 0
middle - 1
outer - 1 - pos #1
outer - 2
middle - 0
middle - 1
outer - 3
middle - 0
middle - 1
EOT
,
'Test inserting at 1 on top level block',
),
array(
'outer',
array('VARIABLE' => 'pos #1'),
0,
'change',
<<<EOT
outer - 0 - pos #1
middle - 0
middle - 1
outer - 1
middle - 0
middle - 1
outer - 2
middle - 0
middle - 1
EOT
,
'Test inserting at 1 on top level block',
),
);
}
/**
* @dataProvider alter_block_array_data
*/
public function test_alter_block_array($alter_block, array $vararray, $key, $mode, $expect, $description)
{
$this->template->set_filenames(array('test' => 'loop_nested.html'));
// @todo Change this
$this->template->assign_block_vars('outer', array());
$this->template->assign_block_vars('outer.middle', array());
$this->template->assign_block_vars('outer.middle', array());
$this->template->assign_block_vars('outer', array());
$this->template->assign_block_vars('outer.middle', array());
$this->template->assign_block_vars('outer.middle', array());
$this->template->assign_block_vars('outer', array());
$this->template->assign_block_vars('outer.middle', array());
$this->template->assign_block_vars('outer.middle', array());
$this->assertEquals("outer - 0\nmiddle - 0\nmiddle - 1\nouter - 1\nmiddle - 0\nmiddle - 1\nouter - 2\nmiddle - 0\nmiddle - 1", $this->display('test'), 'Ensuring template is built correctly before modification');
$this->template->alter_block_array($alter_block, $vararray, $key, $mode);
$this->assertEquals($expect, $this->display('test'), $description);
}
}