diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php
new file mode 100644
index 00000000..370c6aaa
--- /dev/null
+++ b/tests/Bootstrap.php
@@ -0,0 +1,32 @@
+ array('config', 'pdo', 'init'),
+ );
+
+ /**
+ * This method is called before the first test of this test class is run.
+ *
+ */
+ public static function setUpBeforeClass()
+ {
+ error_reporting(E_ALL | E_STRICT);
+ self::$init = true;
+ self::$pdo = null;
+ if (self::$config == null) {
+ $xml = simplexml_load_file(__DIR__ . '/config.xml');
+ $json_string = json_encode($xml);
+ self::$config = json_decode($json_string, true);
+ if (empty(self::$config['mysql']['DB_PASSWD'])) {
+ self::$config['mysql']['DB_PASSWD'] = null;
+ }
+ }
+ }
+
+ /**
+ * This method is called after the last test of this test class is run.
+ *
+ */
+ public static function tearDownAfterClass()
+ {
+ self::$pdo = null;
+ }
+
+ /**
+ * Constructs a test case with the given name.
+ *
+ * @param string $name
+ * @param array $data
+ * @param string $dataName
+ */
+ public function __construct($name = null, array $data = array(), $dataName = '')
+ {
+ parent::__construct($name, $data, $dataName);
+ $this->backupStaticAttributesBlacklist[get_class($this)] = array('init', 'config', 'pdo');
+ }
+
+ /**
+ * Setup Smarty instance called for each test
+ *
+ * @param null $dir working directory
+ */
+ public function setUpSmarty($dir = null)
+ {
+ // set up current working directory
+ chdir($dir);
+ self::$cwd = getcwd();
+ // create missing folders for test
+ if (self::$init) {
+ if (!is_dir($dir . '/templates')) {
+ mkdir($dir . '/templates');
+ }
+ if (!is_dir($dir . '/configs')) {
+ mkdir($dir . '/configs');
+ }
+ if (self::$config['individualFolders'] != 'true') {
+ $dir = __DIR__;
+ }
+ if (!is_dir($dir . '/templates_c')) {
+ mkdir($dir . '/templates_c');
+ chmod($dir . '/templates_c', 0775);
+ }
+ if (!is_dir($dir . '/cache')) {
+ mkdir($dir . '/cache');
+ chmod($dir . '/cache', 0775);
+ }
+ self::$init = false;
+ }
+ clearstatcache();
+ // instance Smarty class
+ if ($this->loadSmarty) {
+ $this->smarty = new Smarty;
+ if (self::$config['individualFolders'] != 'true') {
+ $this->smarty->setCompileDir(__DIR__ . '/templates_c');
+ $this->smarty->setCacheDir(__DIR__ . '/cache');
+ }
+ }
+ // instance SmartyBC class
+ if ($this->loadSmartyBC) {
+ $this->smartyBC = new SmartyBC;
+ if (self::$config['individualFolders'] != 'true') {
+ $this->smartyBC->setCompileDir(__DIR__ . '/templates_c');
+ $this->smartyBC->setCacheDir(__DIR__ . '/cache');
+ }
+ }
+ }
+
+ /**
+ * Create Mysql PDO object
+ *
+ */
+ final public function getConnection()
+ {
+ if (self::$pdo == null) {
+ try {
+ self::$pdo = new PDO(self::$config['mysql']['DB_DSN'], self::$config['mysql']['DB_USER'], self::$config['mysql']['DB_PASSWD']);
+ }
+ catch (PDOException $e) {
+ throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
+ }
+ $timezone = date_default_timezone_get();
+ self::$pdo->exec("SET time_zone = '{$timezone}';");
+ }
+ }
+
+
+ /**
+ * Create table for Mysql resource
+ *
+ */
+ public function initMysqlResource()
+ {
+ $this->getConnection();
+ self::$pdo->exec("DROP TABLE `templates`");
+ self::$pdo->exec("CREATE TABLE IF NOT EXISTS `templates` (
+ `name` varchar(100) NOT NULL,
+ `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `source` text,
+PRIMARY KEY (`name`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8");
+ }
+
+ /**
+ * Create table for Mysql cache resource
+ *
+ */
+ public function initMysqlCache()
+ {
+ $this->getConnection();
+ self::$pdo->exec("DROP TABLE `output_cache`");
+ self::$pdo->exec("CREATE TABLE IF NOT EXISTS `output_cache` (
+`id` char(40) NOT NULL COMMENT 'sha1 hash',
+`name` varchar(250) NOT NULL,
+`cache_id` varchar(250) DEFAULT NULL,
+`compile_id` varchar(250) DEFAULT NULL,
+`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+`expire` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+`content` mediumblob NOT NULL,
+PRIMARY KEY (`id`),
+KEY `name` (`name`),
+KEY `cache_id` (`cache_id`),
+KEY `compile_id` (`compile_id`),
+KEY `modified` (`modified`),
+KEY `expire` (`expire`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8");
+ }
+
+ /**
+ * Delete files in templates_c and cache folders
+ *
+ */
+ public function cleanDirs()
+ {
+ $this->cleanCompileDir();
+ $this->cleanCacheDir();
+ }
+
+ /**
+ * Delete files in templates_c folder
+ *
+ */
+ public function cleanCompileDir()
+ {
+ if (isset($this->smarty)) {
+ $this->cleanDir($this->smarty->getCompileDir());
+ } elseif (isset($this->smartyBC)) {
+ $this->cleanDir($this->smartyBC->getCompileDir());
+ }
+ }
+
+ /**
+ * Delete files in cache folder
+ *
+ */
+ public function cleanCacheDir()
+ {
+ if (isset($this->smarty)) {
+ $this->cleanDir($this->smarty->getCacheDir());
+ } elseif (isset($this->smartyBC)) {
+ $this->cleanDir($this->smartyBC->getCacheDir());
+ }
+ }
+
+ /**
+ * Delete files and sub folders
+ *
+ * @param string $dir
+ */
+ public function cleanDir($dir)
+ {
+ $di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
+ $ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
+ foreach ($ri as $file) {
+ $file->isDir() ? rmdir($file) : unlink($file);
+ }
+ }
+
+ /**
+ * Get PDO object
+ *
+ * @return null|PDO
+ */
+ final public function getPDO()
+ {
+ return self::$pdo;
+ }
+
+ /**
+ * Remove "\r" and replace "\t" with spaces
+ *
+ * @param string $in
+ *
+ * @return mixed
+ */
+ public function normalizeString($in)
+ {
+ if (is_string($in)) {
+ $in = str_replace("\r", '', $in);
+ $in = str_replace("\t", ' ', $in);
+ }
+ return $in;
+ }
+
+ /**
+ * Return source path
+ *
+ * @param Smarty_Internal_TemplateBase $tpl template object
+ * @param null|string $name optional template name
+ * @param null|string $type optional template type
+ * @param null|string $dir optional template folder
+ *
+ * @return string
+ * @throws \Exception
+ */
+ public function buildSourcePath($tpl, $name = null, $type = null, $dir = null)
+ {
+ $name = isset($name) ? $name : $tpl->source->name;
+ $type = isset($type) ? $type : $tpl->source->type;
+ $dir = isset($dir) ? $dir : $this->smarty->getTemplateDir(0);
+ switch ($type) {
+ case 'file':
+ case 'php':
+ return $this->normalizePath($dir . $name, true);
+ case 'mysqltest':
+ case 'mysql':
+ return sha1($type . ':' . $name);
+ case 'string':
+ return sha1($name);
+ default:
+ throw new Exception("Unhandled source resource type '{$type}'");
+ }
+ }
+
+ /**
+ * Build template uid
+ *
+ * @param Smarty_Internal_TemplateBase $tpl template object
+ * @param null|string $value
+ * @param null|string $name optional template name
+ * @param null|string $type optional template type
+ *
+ * @return string
+ * @throws \Exception
+ */
+ public function buildUid($tpl, $value = null, $name = null, $type = null)
+ {
+ $type = isset($type) ? $type : $tpl->source->type;
+ $name = isset($name) ? $name : $tpl->source->name;
+ switch ($type) {
+ case 'file':
+ if ($tpl instanceof Smarty) {
+ return sha1($this->normalizePath($this->smarty->getTemplateDir(0) . $name, true));
+ }
+ return sha1($tpl->source->filepath);
+ case 'php':
+ return sha1($tpl->source->filepath);
+ case 'mysqltest':
+ case 'mysql':
+ return sha1($type . ':' . $name);
+ case 'string':
+ return sha1($name);
+ default:
+ throw new Exception("Unhandled source resource type '{$type}'");
+ }
+ }
+
+ /**
+ * Normalize file path
+ *
+ * @param string $path input path
+ * @param bool $ds if true use system directory separator
+ *
+ * @return string
+ */
+ public function normalizePath($path, $ds = false)
+ {
+ $path = str_replace(array('\\', '/./'), '/', $path);
+ while ($path !== $new = preg_replace('#[^\.\/]+/\.\./#', '', $path)) {
+ $path = $new;
+ }
+ if (DS !== '/' && $ds) {
+ $path = str_replace('/', DS, $path);
+ }
+ return $path;
+ }
+
+ /**
+ * Return base name
+ *
+ * @param \Smarty_Internal_Template|\Smarty_Internal_TemplateBase $tpl template object
+ * @param null|string $name optional template name
+ * @param null|string $type optional template type
+ *
+ * @return null|string
+ */
+ public function getBasename(Smarty_Internal_Template $tpl, $name = null, $type = null)
+ {
+ $name = isset($name) ? $name : $tpl->source->name;
+ $type = isset($type) ? $type : $tpl->source->type;
+ switch ($type) {
+ case 'file':
+ if (($_pos = strpos($name, ']')) !== false) {
+ $name = substr($name, $_pos + 1);
+ }
+ return basename($name);
+ case 'mysqltest':
+ case 'mysql':
+ return $name;
+ case 'string':
+ return '';
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Return compiled file path
+ *
+ * @param \Smarty_Internal_Template|\Smarty_Internal_TemplateBase $tpl template object
+ * @param bool $sub use sub directory flag
+ * @param bool $caching caching flag
+ * @param null|string $compile_id optional compile id
+ * @param null|string $name optional template name
+ * @param null|string $type optional template type
+ * @param null|string $dir optional template folder
+ *
+ * @return string
+ * @throws \Exception
+ */
+ public function buildCompiledPath(Smarty_Internal_Template $tpl, $sub = true, $caching = false, $compile_id = null, $name = null, $type = null, $dir = null)
+ {
+ $sep = DS;
+ $_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null;
+ $sp = $this->buildSourcePath($tpl, $name, $type, $dir);
+ $uid = $this->buildUid($tpl, $sp, $name, $type);
+ $_flag = '';
+ $_filepath = $uid . $_flag;
+ // if use_sub_dirs, break file into directories
+ if ($sub) {
+ $_filepath = substr($_filepath, 0, 2) . $sep
+ . substr($_filepath, 2, 2) . $sep
+ . substr($_filepath, 4, 2) . $sep
+ . $_filepath;
+ }
+ $_compile_dir_sep = $sub ? $sep : '^';
+ if (isset($_compile_id)) {
+ $_filepath = $_compile_id . $_compile_dir_sep . $_filepath;
+ }
+ // caching token
+ if ($caching) {
+ $_cache = '.cache';
+ } else {
+ $_cache = '';
+ }
+ $_compile_dir = $tpl->smarty->getCompileDir();
+ // set basename if not specified
+ $_basename = $this->getBasename($tpl, $name, $type);
+ if ($_basename === null) {
+ $_basename = basename(preg_replace('![^\w\/]+!', '_', $name));
+ }
+ // separate (optional) basename by dot
+ if ($_basename) {
+ $_basename = '.' . $_basename;
+ }
+
+ return $_compile_dir . $_filepath . '.' . $type . $_basename . $_cache . '.php';
+ }
+
+ /**
+ * Return cache file path
+ *
+ * @param Smarty_Internal_TemplateBase $tpl template object
+ * @param bool $sub use sub directory flag
+ * @param null|string $cache_id optional cache id
+ * @param null|string $compile_id optional compile id
+ * @param null|string $name optional template name
+ * @param null|string $type optional template type
+ * @param null|string $dir optional template folder
+ * @param null|string $cacheType optional cache resource type
+ *
+ * @return string
+ * @throws \Exception
+ */
+ public function buildCachedPath($tpl, $sub = true, $cache_id = null, $compile_id = null, $name = null, $type = null, $dir = null, $cacheType = null)
+ {
+ $cacheType = isset($cacheType) ? $cacheType : $tpl->smarty->caching_type;
+ switch ($cacheType) {
+ case 'file':$sep = DS;
+ $_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null;
+ $_cache_id = isset($cache_id) ? preg_replace('![^\w\|]+!', '_', $cache_id) : null;
+ $sp = $this->buildSourcePath($tpl, $name, $type, $dir);
+ $uid = $this->buildUid($tpl, $sp, $name, $type);
+ $_filepath = $uid;
+ // if use_sub_dirs, break file into directories
+ if ($sub) {
+ $_filepath = substr($_filepath, 0, 2) . $sep
+ . substr($_filepath, 2, 2) . $sep
+ . substr($_filepath, 4, 2) . $sep
+ . $_filepath;
+ }
+ $_compile_dir_sep = $sub ? $sep : '^';
+ if (isset($_cache_id)) {
+ $_cache_id = str_replace('|', $_compile_dir_sep, $_cache_id) . $_compile_dir_sep;
+ } else {
+ $_cache_id = '';
+ }
+ if (isset($_compile_id)) {
+ $_compile_id = $_compile_id . $_compile_dir_sep;
+ } else {
+ $_compile_id = '';
+ }
+ $smarty = isset($tpl->smarty) ? $tpl->smarty : $tpl;
+ $_cache_dir = $smarty->getCacheDir();
+ return $_cache_dir . $_cache_id . $_compile_id . $_filepath . '.' . basename($sp) . '.php';
+ case 'mysql':
+ case 'mysqltest':
+ case 'pdo':
+ case 'foobar':
+ $sp = $this->buildSourcePath($tpl, $name, $type, $dir);
+ $_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null;
+ $_cache_id = isset($cache_id) ? preg_replace('![^\w\|]+!', '_', $cache_id) : null;
+ return sha1($sp . $_cache_id . $_compile_id);
+ default:
+ throw new Exception("Unhandled cache resource type '{$cacheType}'");
+ }
+ }
+
+ /**
+ * Prefilter to remove \r from template source
+ *
+ * @param string $tpl_source
+ * @param $template
+ *
+ * @return mixed
+ */
+ function remove_cr($tpl_source, $template)
+ {
+ return str_replace(array("\r\n", "\r"), "\n", $tpl_source);
+ }
+
+ /**
+ * Remove Smarty object from cached resources
+ *
+ */
+ public function clearResourceCache()
+ {
+ if (class_exists('Smarty_Resource', false)) {
+ if (isset(Smarty_Resource::$sources) && !empty(Smarty_Resource::$sources)) {
+ foreach (Smarty_Resource::$sources as $obj) {
+ if (isset($obj->smarty)) {
+ $obj->smarty = null;
+ }
+ }
+ Smarty_Resource::$sources = array();
+ }
+ if (isset(Smarty_Resource::$compileds) && !empty(Smarty_Resource::$compileds)) {
+ foreach (Smarty_Resource::$compileds as $obj) {
+ if (isset($obj->smarty)) {
+ $obj->smarty = null;
+ }
+ }
+ Smarty_Resource::$compileds = array();
+ }
+ if (isset(Smarty_Resource::$resources) && !empty(Smarty_Resource::$resources)) {
+ foreach (Smarty_Resource::$resources as $obj) {
+ if (isset($obj->smarty)) {
+ $obj->smarty = null;
+ }
+ }
+ Smarty_Resource::$resources = array();
+ }
+ }
+ if (class_exists('Smarty_CacheResource', false)) {
+ if (isset(Smarty_CacheResource::$resources) && !empty(Smarty_CacheResource::$resources)) {
+ foreach (Smarty_CacheResource::$resources as $obj) {
+ if (isset($obj->smarty)) {
+ $obj->smarty = null;
+ }
+ }
+ Smarty_CacheResource::$resources = array();
+ }
+ }
+ }
+
+ /**
+ * Tears down the fixture
+ * This method is called after a test is executed.
+ *
+ */
+ protected function tearDown()
+ {
+ $this->clearResourceCache();
+ if (isset($this->smarty->smarty)) {
+ $this->smarty->smarty = null;
+ }
+ if (isset($this->smarty)) {
+ $this->smarty = null;
+ }
+ if (isset($this->smartyBC->smarty)) {
+ $this->smartyBC->smarty = null;
+ }
+ if (isset($this->smartyBC)) {
+ $this->smartyBC = null;
+ }
+ }
+}
diff --git a/tests/README.md b/tests/README.md
index 86d6ef18..fbb78824 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -1 +1,17 @@
-# phpunit
+#Smarty 3 template engine
+##PHPUnit repository
+
+For installing the PHPUnit test by composer use the following:
+
+ "require-dev": {
+ "smarty/smarty-phpunit": "3.1.12"
+ }
+
+Replace 3.1.12 with the installed Smarty version number.
+
+Starting with Smarty version 3.1.22 the "require-dev" section will be added
+to the composer.json file of the Smarty distribution.
+
+The tests for the custom template and cache resources Mysql, Memcache and APC can
+be enabled in config.xml.
+
diff --git a/tests/UnitTests/CacheModify/ModifiedSince/HttpModifiedSinceTest.php b/tests/UnitTests/CacheModify/ModifiedSince/HttpModifiedSinceTest.php
new file mode 100644
index 00000000..99f0495f
--- /dev/null
+++ b/tests/UnitTests/CacheModify/ModifiedSince/HttpModifiedSinceTest.php
@@ -0,0 +1,144 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ *
+ */
+ public function testDisabled()
+ {
+ $_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS'] = true;
+ $_SERVER['SMARTY_PHPUNIT_HEADERS'] = array();
+
+ $this->smarty->setCacheModifiedCheck(false);
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 20;
+ ob_start();
+ $this->smarty->display('helloworld.tpl');
+ $output = ob_get_contents();
+ ob_end_clean();
+ $this->assertEquals('hello world', $output);
+ $this->assertEquals('', join("\r\n", $_SERVER['SMARTY_PHPUNIT_HEADERS']));
+
+ unset($_SERVER['HTTP_IF_MODIFIED_SINCE']);
+ unset($_SERVER['SMARTY_PHPUNIT_HEADERS']);
+ unset($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS']);
+ }
+
+ /**
+ *
+ */
+ public function testEnabledUncached()
+ {
+ $_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS'] = true;
+ $_SERVER['SMARTY_PHPUNIT_HEADERS'] = array();
+
+ $this->smarty->setCacheModifiedCheck(true);
+ $this->smarty->caching = false;
+ $this->smarty->cache_lifetime = 20;
+ ob_start();
+ $this->smarty->display('helloworld.tpl');
+ $output = ob_get_contents();
+ ob_end_clean();
+ $this->assertEquals('hello world', $output);
+ $this->assertEquals('', join("\r\n", $_SERVER['SMARTY_PHPUNIT_HEADERS']));
+
+ unset($_SERVER['HTTP_IF_MODIFIED_SINCE']);
+ unset($_SERVER['SMARTY_PHPUNIT_HEADERS']);
+ unset($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS']);
+ }
+
+ /**
+ *
+ */
+ public function testEnabledCached()
+ {
+ $_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS'] = true;
+ $_SERVER['SMARTY_PHPUNIT_HEADERS'] = array();
+
+ $this->smarty->setCacheModifiedCheck(true);
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 20;
+
+ ob_start();
+ $l1 = ob_get_level();
+ $this->smarty->display('helloworld.tpl');
+ $l2 = ob_get_level();
+ $output = ob_get_contents();
+ ob_end_clean();
+ $this->assertEquals('hello world', $output);
+ $t1 = time();
+ $t2 = strtotime(substr( $_SERVER['SMARTY_PHPUNIT_HEADERS'][0],15));
+ $this->assertTrue(($t2-$t1) <= 1);
+ }
+
+ /**
+ *
+ */
+ public function testEnabledCached2()
+ {
+
+ $_SERVER['SMARTY_PHPUNIT_HEADERS'] = array();
+ $_SERVER['HTTP_IF_MODIFIED_SINCE'] = gmdate('D, d M Y H:i:s', time() - 3600) . ' GMT';
+ $this->smarty->setCacheModifiedCheck(true);
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 20;
+ ob_start();
+ $l3 = ob_get_level();
+ $this->smarty->display('helloworld.tpl');
+ $l4 = ob_get_level();
+ $output = ob_get_contents();
+ ob_end_clean();
+ $this->assertEquals('hello world', $output);
+ $t1 = time();
+ $t2 = strtotime(substr( $_SERVER['SMARTY_PHPUNIT_HEADERS'][0],15));
+ $this->assertTrue(($t2-$t1) <= 1);
+ }
+
+ /**
+ *
+ */
+ public function testEnabledCached3()
+ {
+
+ $_SERVER['SMARTY_PHPUNIT_HEADERS'] = array();
+ $_SERVER['HTTP_IF_MODIFIED_SINCE'] = gmdate('D, d M Y H:i:s', time() + 10) . ' GMT';
+ $this->smarty->setCacheModifiedCheck(true);
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 20;
+ ob_start();
+ $l5 = ob_get_level();
+ $this->smarty->display('helloworld.tpl');
+ $l6 = ob_get_level();
+ $output = ob_get_contents();
+ ob_end_clean();
+ $this->assertEquals('', $output);
+ $this->assertEquals('304 Not Modified', join("\r\n", $_SERVER['SMARTY_PHPUNIT_HEADERS']));
+
+ unset($_SERVER['HTTP_IF_MODIFIED_SINCE']);
+ unset($_SERVER['SMARTY_PHPUNIT_HEADERS']);
+ unset($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS']);
+ }
+}
diff --git a/tests/UnitTests/CacheModify/ModifiedSince/templates/helloworld.tpl b/tests/UnitTests/CacheModify/ModifiedSince/templates/helloworld.tpl
new file mode 100644
index 00000000..95d09f2b
--- /dev/null
+++ b/tests/UnitTests/CacheModify/ModifiedSince/templates/helloworld.tpl
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/tests/UnitTests/CacheResourceTests/Apc/CacheResourceCustomApcTest.php b/tests/UnitTests/CacheResourceTests/Apc/CacheResourceCustomApcTest.php
new file mode 100644
index 00000000..be5111e1
--- /dev/null
+++ b/tests/UnitTests/CacheResourceTests/Apc/CacheResourceCustomApcTest.php
@@ -0,0 +1,31 @@
+markTestSkipped('Apc tests are disabled');
+ } else {
+ if (!function_exists('apc_cache_info') || ini_get('apc.enable_cli')) {
+ $this->markTestSkipped('APC cache not available');
+ }
+ }
+ $this->setUpSmarty(__DIR__);
+ parent::setUp();
+ $this->smarty->addPluginsDir(SMARTY_DIR . '../demo/plugins/');
+ }
+}
diff --git a/tests/UnitTests/CacheResourceTests/File/CacheResourceFileTest.php b/tests/UnitTests/CacheResourceTests/File/CacheResourceFileTest.php
new file mode 100644
index 00000000..1f066c60
--- /dev/null
+++ b/tests/UnitTests/CacheResourceTests/File/CacheResourceFileTest.php
@@ -0,0 +1,379 @@
+setUpSmarty(__DIR__);
+ parent::setUp();
+ }
+
+
+ public function testInit()
+
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test getCachedFilepath with configuration['useSubDirs'] enabled
+ */
+ public function testGetCachedFilepathSubDirs()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setUseSubDirs(true);
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->assertEquals($this->buildCachedPath($tpl, true, null, null, 'helloworld.tpl', $type = 'file', $this->smarty->getTemplateDir(0), 'file')
+ , $tpl->cached->filepath);
+ }
+
+ /**
+ * test getCachedFilepath with cache_id
+ */
+ public function testGetCachedFilepathCacheId()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setUseSubDirs(true);
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar');
+ $this->assertEquals($this->buildCachedPath($tpl, true, 'foo|bar', null, 'helloworld.tpl', $type = 'file', $this->smarty->getTemplateDir(0), 'file')
+ , $tpl->cached->filepath);
+ }
+
+ /**
+ * test getCachedFilepath with compile_id
+ */
+ public function testGetCachedFilepathCompileId()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setUseSubDirs(true);
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', null, 'blar');
+ $this->assertEquals($this->buildCachedPath($tpl, true, null, 'blar', 'helloworld.tpl', $type = 'file', $this->smarty->getTemplateDir(0), 'file')
+ , $tpl->cached->filepath);
+ }
+
+ /**
+ * test getCachedFilepath with cache_id and compile_id
+ */
+ public function testGetCachedFilepathCacheIdCompileId()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setUseSubDirs(true);
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $this->assertEquals($this->buildCachedPath($tpl, true, 'foo|bar', 'blar', 'helloworld.tpl', $type = 'file', $this->smarty->getTemplateDir(0), 'file')
+ , $tpl->cached->filepath);
+ }
+
+ /**
+ * test cache->clear_all with cache_id and compile_id
+ */
+ public function testClearCacheAllCacheIdCompileId()
+ {
+ $this->cleanCacheDir();
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setUseSubDirs(true);
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl);
+ $this->assertTrue(file_exists($tpl->cached->filepath));
+ $this->assertEquals(1, $this->smarty->clearAllCache());
+ }
+
+ /**
+ * test cache->clear with cache_id and compile_id
+ */
+ public function testClearCacheCacheIdCompileId()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->cleanCacheDir();
+ $this->smarty->setUseSubDirs(false);
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl);
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar2', 'blar');
+ $this->writeCachedContent($tpl2);
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl3);
+ $this->assertTrue(file_exists($tpl->cached->filepath));
+ $this->assertTrue(file_exists($tpl2->cached->filepath));
+ $this->assertTrue(file_exists($tpl3->cached->filepath));
+ $this->assertEquals(2, $this->smarty->clearCache(null, 'foo|bar'));
+ $this->assertFalse(file_exists($tpl->cached->filepath));
+ $this->assertTrue(file_exists($tpl2->cached->filepath));
+ $this->assertFalse(file_exists($tpl3->cached->filepath));
+ }
+
+ public function testClearCacheCacheIdCompileId2()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setUseSubDirs(false);
+ $this->cleanCacheDir();
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl);
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar2', 'blar');
+ $this->writeCachedContent($tpl2);
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl3);
+ $this->assertTrue(file_exists($tpl->cached->filepath));
+ $this->assertTrue(file_exists($tpl2->cached->filepath));
+ $this->assertTrue(file_exists($tpl3->cached->filepath));
+ $this->assertEquals(2, $this->smarty->clearCache('helloworld.tpl'));
+ $this->assertFalse(file_exists($tpl->cached->filepath));
+ $this->assertFalse(file_exists($tpl2->cached->filepath));
+ $this->assertTrue(file_exists($tpl3->cached->filepath));
+ }
+
+ public function testClearCacheCacheIdCompileId2Sub()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setUseSubDirs(true);
+ $this->cleanCacheDir();
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl);
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar2', 'blar');
+ $this->writeCachedContent($tpl2);
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl3);
+ $this->assertTrue(file_exists($tpl->cached->filepath));
+ $this->assertTrue(file_exists($tpl2->cached->filepath));
+ $this->assertTrue(file_exists($tpl3->cached->filepath));
+ $this->assertEquals(2, $this->smarty->clearCache('helloworld.tpl'));
+ $this->assertFalse(file_exists($tpl->cached->filepath));
+ $this->assertFalse(file_exists($tpl2->cached->filepath));
+ $this->assertTrue(file_exists($tpl3->cached->filepath));
+ }
+
+ public function testClearCacheCacheIdCompileId3()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->cleanCacheDir();
+ $this->smarty->setUseSubDirs(false);
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl);
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar2');
+ $this->writeCachedContent($tpl2);
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl3);
+ $this->assertTrue(file_exists($tpl->cached->filepath));
+ $this->assertTrue(file_exists($tpl2->cached->filepath));
+ $this->assertTrue(file_exists($tpl3->cached->filepath));
+ $this->assertEquals(1, $this->smarty->clearCache('helloworld.tpl', null, 'blar2'));
+ $this->assertTrue(file_exists($tpl->cached->filepath));
+ $this->assertFalse(file_exists($tpl2->cached->filepath));
+ $this->assertTrue(file_exists($tpl3->cached->filepath));
+ }
+
+ public function testClearCacheCacheIdCompileId3Sub()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->cleanCacheDir();
+ $this->smarty->setUseSubDirs(true);
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl);
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar2');
+ $this->writeCachedContent($tpl2);
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl3);
+ $this->assertTrue(file_exists($tpl->cached->filepath));
+ $this->assertTrue(file_exists($tpl2->cached->filepath));
+ $this->assertTrue(file_exists($tpl3->cached->filepath));
+ $this->assertEquals(1, $this->smarty->clearCache('helloworld.tpl', null, 'blar2'));
+ $this->assertTrue(file_exists($tpl->cached->filepath));
+ $this->assertFalse(file_exists($tpl2->cached->filepath));
+ $this->assertTrue(file_exists($tpl3->cached->filepath));
+ }
+
+ public function testClearCacheCacheIdCompileId4()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setUseSubDirs(false);
+ $this->cleanCacheDir();
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl);
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar2');
+ $this->writeCachedContent($tpl2);
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl3);
+ $this->assertTrue(file_exists($tpl->cached->filepath));
+ $this->assertTrue(file_exists($tpl2->cached->filepath));
+ $this->assertTrue(file_exists($tpl3->cached->filepath));
+ $this->assertEquals(1, $this->smarty->clearCache('helloworld.tpl', null, 'blar2'));
+ $this->assertTrue(file_exists($tpl->cached->filepath));
+ $this->assertFalse(file_exists($tpl2->cached->filepath));
+ $this->assertTrue(file_exists($tpl3->cached->filepath));
+ }
+
+ public function testClearCacheCacheIdCompileId4Sub()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setUseSubDirs(true);
+ $this->cleanCacheDir();
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl);
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar2');
+ $this->writeCachedContent($tpl2);
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl3);
+ $this->assertTrue(file_exists($tpl->cached->filepath));
+ $this->assertTrue(file_exists($tpl2->cached->filepath));
+ $this->assertTrue(file_exists($tpl3->cached->filepath));
+ $this->assertEquals(1, $this->smarty->clearCache('helloworld.tpl', null, 'blar2'));
+ $this->assertTrue(file_exists($tpl->cached->filepath));
+ $this->assertFalse(file_exists($tpl2->cached->filepath));
+ $this->assertTrue(file_exists($tpl3->cached->filepath));
+ }
+
+ public function testClearCacheCacheIdCompileId5()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setUseSubDirs(false);
+ $this->cleanCacheDir();
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl);
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar2');
+ $this->writeCachedContent($tpl2);
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl3);
+ $this->assertTrue(file_exists($tpl->cached->filepath));
+ $this->assertTrue(file_exists($tpl2->cached->filepath));
+ $this->assertTrue(file_exists($tpl3->cached->filepath));
+ $this->assertEquals(2, $this->smarty->clearCache(null, null, 'blar'));
+ $this->assertFalse(file_exists($tpl->cached->filepath));
+ $this->assertTrue(file_exists($tpl2->cached->filepath));
+ $this->assertFalse(file_exists($tpl3->cached->filepath));
+ }
+
+ public function testClearCacheCacheIdCompileId5Sub()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setUseSubDirs(true);
+ $this->cleanCacheDir();
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl);
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar2');
+ $this->writeCachedContent($tpl2);
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $this->writeCachedContent($tpl3);
+ $this->assertTrue(file_exists($tpl->cached->filepath));
+ $this->assertTrue(file_exists($tpl2->cached->filepath));
+ $this->assertTrue(file_exists($tpl3->cached->filepath));
+ $this->assertEquals(2, $this->smarty->clearCache(null, null, 'blar'));
+ $this->assertFalse(file_exists($tpl->cached->filepath));
+ $this->assertTrue(file_exists($tpl2->cached->filepath));
+ $this->assertFalse(file_exists($tpl3->cached->filepath));
+ }
+
+ public function testClearCacheCacheFile()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setUseSubDirs(false);
+ $this->cleanCacheDir();
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->writeCachedContent($tpl);
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', null, 'bar');
+ $this->writeCachedContent($tpl2);
+ $tpl3 = $this->smarty->createTemplate('helloworld.tpl', 'buh|blar');
+ $this->writeCachedContent($tpl3);
+ $tpl4 = $this->smarty->createTemplate('helloworld2.tpl');
+ $this->writeCachedContent($tpl4);
+ $this->assertTrue(file_exists($tpl->cached->filepath));
+ $this->assertTrue(file_exists($tpl2->cached->filepath));
+ $this->assertTrue(file_exists($tpl3->cached->filepath));
+ $this->assertTrue(file_exists($tpl4->cached->filepath));
+ $this->assertEquals(3, $this->smarty->clearCache('helloworld.tpl'));
+ $this->assertFalse(file_exists($tpl->cached->filepath));
+ $this->assertFalse(file_exists($tpl2->cached->filepath));
+ $this->assertFalse(file_exists($tpl3->cached->filepath));
+ $this->assertTrue(file_exists($tpl4->cached->filepath));
+ }
+
+ public function testClearCacheCacheFileSub()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setUseSubDirs(true);
+ $this->cleanCacheDir();
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->writeCachedContent($tpl);
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', null, 'bar');
+ $this->writeCachedContent($tpl2);
+ $tpl3 = $this->smarty->createTemplate('helloworld.tpl', 'buh|blar');
+ $this->writeCachedContent($tpl3);
+ $tpl4 = $this->smarty->createTemplate('helloworld2.tpl');
+ $this->writeCachedContent($tpl4);
+ $this->assertTrue(file_exists($tpl->cached->filepath));
+ $this->assertTrue(file_exists($tpl2->cached->filepath));
+ $this->assertTrue(file_exists($tpl3->cached->filepath));
+ $this->assertTrue(file_exists($tpl4->cached->filepath));
+ $this->assertEquals(3, $this->smarty->clearCache('helloworld.tpl'));
+ $this->assertFalse(file_exists($tpl->cached->filepath));
+ $this->assertFalse(file_exists($tpl2->cached->filepath));
+ $this->assertFalse(file_exists($tpl3->cached->filepath));
+ $this->assertTrue(file_exists($tpl4->cached->filepath));
+ }
+
+ /**
+ * test cache->clear_all method
+ */
+ public function testClearCacheAll()
+ {
+ $this->cleanCacheDir();
+ file_put_contents($this->smarty->getCacheDir() . 'dummy.php', 'test');
+ $this->assertEquals(1, $this->smarty->clearAllCache());
+ }
+
+ /**
+ * test cache->clear_all method not expired
+ */
+ public function testClearCacheAllNotExpired()
+ {
+ $this->cleanCacheDir();
+ file_put_contents($this->smarty->getCacheDir() . 'dummy.php', 'test');
+ touch($this->smarty->getCacheDir() . 'dummy.php', time() - 1000);
+ clearstatcache();
+ $this->assertEquals(0, $this->smarty->clearAllCache(2000));
+ }
+
+ /**
+ * test cache->clear_all method expired
+ */
+ public function testClearCacheAllExpired()
+ {
+ $this->cleanCacheDir();
+ file_put_contents($this->smarty->getCacheDir() . 'dummy.php', 'test');
+ touch($this->smarty->getCacheDir() . 'dummy.php', time() - 1000);
+ clearstatcache();
+ $this->assertEquals(1, $this->smarty->clearAllCache(500));
+ }
+
+ private function writeCachedContent($tpl)
+ {
+ $tpl->writeCachedContent("echo 'hello world';\n");
+ }
+}
diff --git a/tests/UnitTests/CacheResourceTests/Memcache/CacheResourceCustomMemcacheTest.php b/tests/UnitTests/CacheResourceTests/Memcache/CacheResourceCustomMemcacheTest.php
new file mode 100644
index 00000000..ff1709a0
--- /dev/null
+++ b/tests/UnitTests/CacheResourceTests/Memcache/CacheResourceCustomMemcacheTest.php
@@ -0,0 +1,92 @@
+markTestSkipped('Memcache tests are disabled');
+ } else {
+ if (!class_exists('Memcache')) {
+ $this->markTestSkipped('Memcache not available');
+ }
+ }
+ $this->setUpSmarty(__DIR__);
+ parent::setUp();
+ $this->smarty->setCachingType('memcachetest');
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ protected function doClearCacheAssertion($a, $b)
+ {
+ $this->assertEquals(- 1, $b);
+ }
+
+ public function testGetCachedFilepathSubDirs()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $sha1 = $tpl->source->uid . '#helloworld_tpl##';
+ $this->assertEquals($sha1, $tpl->cached->filepath);
+ }
+
+ /**
+ * test getCachedFilepath with cache_id
+ */
+ public function testGetCachedFilepathCacheId()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar');
+ $sha1 = $tpl->source->uid . '#helloworld_tpl#foo|bar#';
+ $this->assertEquals($sha1, $tpl->cached->filepath);
+ }
+
+ /**
+ * test getCachedFilepath with compile_id
+ */
+ public function testGetCachedFilepathCompileId()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', null, 'blar');
+ $sha1 = $tpl->source->uid . '#helloworld_tpl##blar';
+ $this->assertEquals($sha1, $tpl->cached->filepath);
+ }
+
+ /**
+ * test getCachedFilepath with cache_id and compile_id
+ */
+ public function testGetCachedFilepathCacheIdCompileId()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $sha1 = $tpl->source->uid . '#helloworld_tpl#foo|bar#blar';
+ $this->assertEquals($sha1, $tpl->cached->filepath);
+ }
+}
diff --git a/tests/UnitTests/CacheResourceTests/Mysql/CacheResourceCustomMysqlTest.php b/tests/UnitTests/CacheResourceTests/Mysql/CacheResourceCustomMysqlTest.php
new file mode 100644
index 00000000..9de60529
--- /dev/null
+++ b/tests/UnitTests/CacheResourceTests/Mysql/CacheResourceCustomMysqlTest.php
@@ -0,0 +1,36 @@
+markTestSkipped('mysql tests are disabled');
+ }
+ if (self::$init) {
+ $this->getConnection();
+ }
+ $this->setUpSmarty(__DIR__);
+ parent::setUp();
+ $this->smarty->setCachingType('mysqltest');
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ $this->initMysqlCache();
+ }
+}
diff --git a/tests/UnitTests/CacheResourceTests/Registered/CacheResourceCustomRegisteredTest.php b/tests/UnitTests/CacheResourceTests/Registered/CacheResourceCustomRegisteredTest.php
new file mode 100644
index 00000000..d7be7e6e
--- /dev/null
+++ b/tests/UnitTests/CacheResourceTests/Registered/CacheResourceCustomRegisteredTest.php
@@ -0,0 +1,39 @@
+markTestSkipped('mysql tests are disabled');
+ }
+ if (self::$init) {
+ $this->getConnection();
+ }
+ $this->setUpSmarty(__DIR__);
+ parent::setUp();
+ if (!class_exists('Smarty_CacheResource_Mysqltest', false)) {
+ require_once(__DIR__ . "/../_shared/PHPunitplugins/cacheresource.mysqltest.php");
+ }
+ $this->smarty->setCachingType('foobar');
+ $this->smarty->registerCacheResource('foobar', new Smarty_CacheResource_Mysqltest());
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ $this->initMysqlCache();
+ }
+}
diff --git a/tests/UnitTests/CacheResourceTests/_shared/CacheResourceTestCommon.php b/tests/UnitTests/CacheResourceTests/_shared/CacheResourceTestCommon.php
new file mode 100644
index 00000000..51cc55ee
--- /dev/null
+++ b/tests/UnitTests/CacheResourceTests/_shared/CacheResourceTestCommon.php
@@ -0,0 +1,522 @@
+smarty->setTemplateDir(__DIR__ . '/../_shared/templates');
+ $this->smarty->addPluginsDir(__DIR__ . '/../_shared/PHPunitplugins');
+ $this->smarty->registerFilter('pre', array($this, 'compiledPrefilter'));
+ }
+
+
+ protected function doClearCacheAssertion($a, $b)
+ {
+ $this->assertEquals($a, $b);
+ }
+
+ public function compiledPrefilter($text, Smarty_Internal_Template $tpl)
+ {
+ return str_replace('#', $tpl->getVariable('test'), $text);
+ }
+
+ /**
+ * test getCachedFilepath with configuration['useSubDirs'] enabled
+ */
+ public function testGetCachedFilepathSubDirs()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setUseSubDirs(true);
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->assertEquals($this->buildCachedPath($tpl), $tpl->cached->filepath);
+ }
+
+ /**
+ * test getCachedFilepath with cache_id
+ */
+ public function testGetCachedFilepathCacheId()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar');
+ $this->assertEquals($this->buildCachedPath($tpl, true, 'foo|bar'), $tpl->cached->filepath);
+ }
+
+ /**
+ * test getCachedFilepath with compile_id
+ */
+ public function testGetCachedFilepathCompileId()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', null, 'blar');
+ $this->assertEquals($this->buildCachedPath($tpl, true, null, 'blar'), $tpl->cached->filepath);
+ }
+
+ /**
+ * test getCachedFilepath with cache_id and compile_id
+ */
+ public function testGetCachedFilepathCacheIdCompileId()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $this->assertEquals($this->buildCachedPath($tpl, true, 'foo|bar', 'blar'), $tpl->cached->filepath);
+ }
+
+ /**
+ * test cache->clear_all with cache_id and compile_id
+ */
+ public function testClearCacheAllCacheIdCompileId()
+ {
+ $this->smarty->clearAllCache();
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $tpl->writeCachedContent('hello world');
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl));
+ // Custom CacheResources may return -1 if they can't tell the number of deleted elements
+ $this->assertEquals(-1, $this->smarty->clearAllCache());
+ }
+
+ /**
+ * test cache->clear with cache_id and compile_id
+ */
+ public function testClearCacheCacheIdCompileId()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->clearAllCache();
+ // create and cache templates
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $tpl->writeCachedContent('hello world 1');
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar2', 'blar');
+ $tpl2->writeCachedContent('hello world 2');
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $tpl3->writeCachedContent('hello world 3');
+ // test cached content
+ $this->assertEquals('hello world 1', $tpl->cached->handler->getCachedContent($tpl));
+ $this->assertEquals('hello world 2', $tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertEquals('hello world 3', $tpl->cached->handler->getCachedContent($tpl3));
+ // test number of deleted caches
+ $this->doClearCacheAssertion(2, $this->smarty->clearCache(null, 'foo|bar'));
+ // test that caches are deleted properly
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl));
+ $this->assertEquals('hello world 2', $tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl3));
+ }
+
+ public function testClearCacheCacheIdCompileId2()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->clearAllCache();
+ // create and cache templates
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $tpl->writeCachedContent('hello world');
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar2', 'blar');
+ $tpl2->writeCachedContent('hello world');
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $tpl3->writeCachedContent('hello world');
+ // test cached content
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl3));
+ // test number of deleted caches
+ $this->doClearCacheAssertion(2, $this->smarty->clearCache('helloworld.tpl'));
+ // test that caches are deleted properly
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl));
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl3));
+ }
+
+ public function testClearCacheCacheIdCompileId2Sub()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->clearAllCache();
+ // create and cache templates
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $tpl->writeCachedContent('hello world');
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar2', 'blar');
+ $tpl2->writeCachedContent('hello world');
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $tpl3->writeCachedContent('hello world');
+ // test cached content
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl3));
+ // test number of deleted caches
+ $this->doClearCacheAssertion(2, $this->smarty->clearCache('helloworld.tpl'));
+ // test that caches are deleted properly
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl));
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl3));
+ }
+
+ public function testClearCacheCacheIdCompileId3()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->clearAllCache();
+ // create and cache templates
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $tpl->writeCachedContent('hello world');
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar2');
+ $tpl2->writeCachedContent('hello world');
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $tpl3->writeCachedContent('hello world');
+ // test cached content
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl3));
+ // test number of deleted caches
+ $this->doClearCacheAssertion(1, $this->smarty->clearCache('helloworld.tpl', null, 'blar2'));
+ // test that caches are deleted properly
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl));
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl3));
+ }
+
+ public function testClearCacheCacheIdCompileId3Sub()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->clearAllCache();
+ // create and cache templates
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $tpl->writeCachedContent('hello world');
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar2');
+ $tpl2->writeCachedContent('hello world');
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $tpl3->writeCachedContent('hello world');
+ // test cached content
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl3));
+ // test number of deleted caches
+ $this->doClearCacheAssertion(1, $this->smarty->clearCache('helloworld.tpl', null, 'blar2'));
+ // test that caches are deleted properly
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl));
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl3));
+ }
+
+ public function testClearCacheCacheIdCompileId4()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->clearAllCache();
+ // create and cache templates
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $tpl->writeCachedContent('hello world');
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar2');
+ $tpl2->writeCachedContent('hello world');
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $tpl3->writeCachedContent('hello world');
+ // test cached content
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl3));
+ // test number of deleted caches
+ $this->doClearCacheAssertion(1, $this->smarty->clearCache('helloworld.tpl', null, 'blar2'));
+ // test that caches are deleted properly
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl));
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl3));
+ }
+
+ public function testClearCacheCacheIdCompileId4Sub()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->clearAllCache();
+ // create and cache templates
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $tpl->writeCachedContent('hello world');
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar2');
+ $tpl2->writeCachedContent('hello world');
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $tpl3->writeCachedContent('hello world');
+ // test cached content
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl3));
+ // test number of deleted caches
+ $this->doClearCacheAssertion(1, $this->smarty->clearCache('helloworld.tpl', null, 'blar2'));
+ // test that caches are deleted properly
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl));
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl3));
+ }
+
+ public function testClearCacheCacheIdCompileId5()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->clearAllCache();
+ // create and cache templates
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $tpl->writeCachedContent('hello world');
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar2');
+ $tpl2->writeCachedContent('hello world');
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $tpl3->writeCachedContent('hello world');
+ // test cached content
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl3));
+ // test number of deleted caches
+ $this->doClearCacheAssertion(2, $this->smarty->clearCache(null, null, 'blar'));
+ // test that caches are deleted properly
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl3));
+ }
+
+ public function testClearCacheCacheIdCompileId5Sub()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->clearAllCache();
+ // create and cache templates
+ $tpl = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar');
+ $tpl->writeCachedContent('hello world');
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', 'foo|bar', 'blar2');
+ $tpl2->writeCachedContent('hello world');
+ $tpl3 = $this->smarty->createTemplate('helloworld2.tpl', 'foo|bar', 'blar');
+ $tpl3->writeCachedContent('hello world');
+ // test cached content
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl3));
+ // test number of deleted caches
+ $this->doClearCacheAssertion(2, $this->smarty->clearCache(null, null, 'blar'));
+ // test that caches are deleted properly
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl3));
+ }
+
+ public function testClearCacheCacheFile()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->clearAllCache();
+ // create and cache templates
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $tpl->writeCachedContent('hello world');
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', null, 'bar');
+ $tpl2->writeCachedContent('hello world');
+ $tpl3 = $this->smarty->createTemplate('helloworld.tpl', 'buh|blar');
+ $tpl3->writeCachedContent('hello world');
+ $tpl4 = $this->smarty->createTemplate('helloworld2.tpl');
+ $tpl4->writeCachedContent('hello world');
+ // test cached content
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl3));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl4));
+ // test number of deleted caches
+ $this->doClearCacheAssertion(3, $this->smarty->clearCache('helloworld.tpl'));
+ // test that caches are deleted properly
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl));
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl3));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl4));
+ }
+
+ public function testClearCacheCacheFileSub()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->clearAllCache();
+ // create and cache templates
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $tpl->writeCachedContent('hello world');
+ $tpl2 = $this->smarty->createTemplate('helloworld.tpl', null, 'bar');
+ $tpl2->writeCachedContent('hello world');
+ $tpl3 = $this->smarty->createTemplate('helloworld.tpl', 'buh|blar');
+ $tpl3->writeCachedContent('hello world');
+ $tpl4 = $this->smarty->createTemplate('helloworld2.tpl');
+ $tpl4->writeCachedContent('hello world');
+ // test cached content
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl3));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl4));
+ // test number of deleted caches
+ $this->doClearCacheAssertion(3, $this->smarty->clearCache('helloworld.tpl'));
+ // test that caches are deleted properly
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl));
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl2));
+ $this->assertNull($tpl->cached->handler->getCachedContent($tpl3));
+ $this->assertEquals('hello world', $tpl->cached->handler->getCachedContent($tpl4));
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testIsCachedPrepare()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->assign('test', 1);
+ // compile and cache
+ $this->assertEquals('cache resource test:1 compiled:1 rendered:1', $this->smarty->fetch('cacheresource.tpl'));
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testIsCached()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->assign('test', 2);
+ $tpl = $this->smarty->createTemplate('cacheresource.tpl', $this->smarty);
+ $this->assertTrue($tpl->isCached());
+ $this->assertEquals('cache resource test:2 compiled:1 rendered:1', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testIsCachedCachingDisabled()
+ {
+ $this->smarty->assign('test', 3);
+ $tpl = $this->smarty->createTemplate('cacheresource.tpl', $this->smarty);
+ $this->assertFalse($tpl->isCached());
+ $this->assertEquals('cache resource test:3 compiled:3 rendered:3', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testForceCache()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->setForceCache(true);
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->assign('test', 4);
+ $tpl = $this->smarty->createTemplate('cacheresource.tpl', $this->smarty);
+ $this->assertFalse($tpl->isCached(), 'isCached() must be false at forceCache');
+ $this->assertEquals('cache resource test:4 compiled:1 rendered:4', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testIsCachedAftertestForceCache()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->assign('test', 5);
+ $tpl = $this->smarty->createTemplate('cacheresource.tpl', $this->smarty);
+ $this->assertTrue($tpl->isCached(), 'isCached() must be true after forceCache');
+ $this->assertEquals('cache resource test:5 compiled:1 rendered:4', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * @runInSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testIsCachedTouchedSource()
+ {
+ sleep(2);
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->assign('test', 6);
+ $filepath = $this->buildSourcePath(null, 'cacheresource.tpl', 'file');
+ touch($filepath);
+ sleep(2);
+ clearstatcache();
+ $tpl = $this->smarty->createTemplate('cacheresource.tpl', $this->smarty);
+ $isCached = $tpl->isCached();
+ $mustCompile = $tpl->mustCompile();
+ $this->assertFalse($isCached, 'isCached() must be false after touch of source');
+ $this->assertTrue($mustCompile, 'mustCompile() must be true after touch of source');
+ $this->assertEquals('cache resource test:6 compiled:6 rendered:6', $this->smarty->fetch($tpl), 'recompile failed');
+ $this->assertFalse($isCached, 'isCached() must be false after touch of source');
+ $this->assertTrue($mustCompile, 'mustCompile() must be true after touch of source');
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testIsCachedAfterTouch()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->assign('test', 7);
+ $tpl = $this->smarty->createTemplate('cacheresource.tpl', $this->smarty);
+ $this->assertTrue($tpl->isCached(), 'isCached() must be true after recompilation');
+ $this->assertEquals('cache resource test:7 compiled:6 rendered:6', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testIsCachedForceCompile()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setForceCompile(true);
+ $this->smarty->assign('test', 8);
+ $tpl = $this->smarty->createTemplate('cacheresource.tpl', $this->smarty);
+ $this->assertFalse($tpl->isCached(), 'isCached() must be false at force compile');
+ $this->assertEquals('cache resource test:8 compiled:8 rendered:8', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testIsCachedAfterForceCompile()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->assign('test', 9);
+ $tpl = $this->smarty->createTemplate('cacheresource.tpl', $this->smarty);
+ $this->assertTrue($tpl->isCached(), 'isCached() must be true after recompilation');
+ $this->assertEquals('cache resource test:9 compiled:8 rendered:8', $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/CacheResourceTests/_shared/PHPunitplugins/cacheresource.apctest.php b/tests/UnitTests/CacheResourceTests/_shared/PHPunitplugins/cacheresource.apctest.php
new file mode 100644
index 00000000..1e599d5d
--- /dev/null
+++ b/tests/UnitTests/CacheResourceTests/_shared/PHPunitplugins/cacheresource.apctest.php
@@ -0,0 +1,25 @@
+contents = array();
+ $this->timestamps = array();
+ $t = $this->getContent($_template);
+
+ return $t ? $t : null;
+ }
+
+ public function __sleep()
+ {
+ return array();
+ }
+
+ public function __wakeup()
+ {
+ $this->__construct();
+ }
+}
diff --git a/tests/UnitTests/CacheResourceTests/_shared/PHPunitplugins/cacheresource.memcachetest.php b/tests/UnitTests/CacheResourceTests/_shared/PHPunitplugins/cacheresource.memcachetest.php
new file mode 100644
index 00000000..b342b875
--- /dev/null
+++ b/tests/UnitTests/CacheResourceTests/_shared/PHPunitplugins/cacheresource.memcachetest.php
@@ -0,0 +1,25 @@
+contents = array();
+ $this->timestamps = array();
+ $t = $this->getContent($_template);
+
+ return $t ? $t : null;
+ }
+
+ public function __sleep()
+ {
+ return array();
+ }
+
+ public function __wakeup()
+ {
+ $this->__construct();
+ }
+}
diff --git a/tests/UnitTests/CacheResourceTests/_shared/PHPunitplugins/cacheresource.mysqltest.php b/tests/UnitTests/CacheResourceTests/_shared/PHPunitplugins/cacheresource.mysqltest.php
new file mode 100644
index 00000000..5a034319
--- /dev/null
+++ b/tests/UnitTests/CacheResourceTests/_shared/PHPunitplugins/cacheresource.mysqltest.php
@@ -0,0 +1,18 @@
+db = PHPUnit_Smarty::$pdo;
+ } catch (PDOException $e) {
+ throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
+ }
+ $this->fetch = $this->db->prepare('SELECT modified, content FROM output_cache WHERE id = :id');
+ $this->fetchTimestamp = $this->db->prepare('SELECT modified FROM output_cache WHERE id = :id');
+ $this->save = $this->db->prepare('REPLACE INTO output_cache (id, name, cache_id, compile_id, content)
+ VALUES (:id, :name, :cache_id, :compile_id, :content)');
+ }
+}
diff --git a/tests/UnitTests/CacheResourceTests/_shared/PHPunitplugins/resource.filetest.php b/tests/UnitTests/CacheResourceTests/_shared/PHPunitplugins/resource.filetest.php
new file mode 100644
index 00000000..d5676d61
--- /dev/null
+++ b/tests/UnitTests/CacheResourceTests/_shared/PHPunitplugins/resource.filetest.php
@@ -0,0 +1,22 @@
+exists) {
+ if (isset(CacheResourceTestCommon::$touchResource[$source->filepath])) {
+ $source->timestamp = CacheResourceTestCommon::$touchResource[$source->filepath];
+ }
+ }
+ }
+
+}
+
diff --git a/tests/UnitTests/CacheResourceTests/_shared/templates/cacheresource.tpl b/tests/UnitTests/CacheResourceTests/_shared/templates/cacheresource.tpl
new file mode 100644
index 00000000..5340ec3f
--- /dev/null
+++ b/tests/UnitTests/CacheResourceTests/_shared/templates/cacheresource.tpl
@@ -0,0 +1 @@
+cache resource test:{$test nocache} compiled:# rendered:{$test}
\ No newline at end of file
diff --git a/tests/UnitTests/CacheResourceTests/_shared/templates/helloworld.tpl b/tests/UnitTests/CacheResourceTests/_shared/templates/helloworld.tpl
new file mode 100644
index 00000000..95d09f2b
--- /dev/null
+++ b/tests/UnitTests/CacheResourceTests/_shared/templates/helloworld.tpl
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/tests/UnitTests/CacheResourceTests/_shared/templates/helloworld2.tpl b/tests/UnitTests/CacheResourceTests/_shared/templates/helloworld2.tpl
new file mode 100644
index 00000000..95d09f2b
--- /dev/null
+++ b/tests/UnitTests/CacheResourceTests/_shared/templates/helloworld2.tpl
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/tests/UnitTests/Compiler/CompilerPlugin/CompileCompilerPluginTest.php b/tests/UnitTests/Compiler/CompilerPlugin/CompileCompilerPluginTest.php
new file mode 100644
index 00000000..84a10403
--- /dev/null
+++ b/tests/UnitTests/Compiler/CompilerPlugin/CompileCompilerPluginTest.php
@@ -0,0 +1,40 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test compiler plugin tag in template file
+ */
+ public function testCompilerPlugin()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_COMPILER, 'compilerplugin', 'mycompilerplugin');
+ $tpl = $this->smarty->createTemplate('compilerplugintest.tpl');
+ $this->assertEquals("Hello World", $this->smarty->fetch($tpl));
+ }
+}
+
+function mycompilerplugin($params, $compiler)
+{
+ return '';
+}
diff --git a/tests/UnitTests/Compiler/CompilerPlugin/templates/compilerplugintest.tpl b/tests/UnitTests/Compiler/CompilerPlugin/templates/compilerplugintest.tpl
new file mode 100644
index 00000000..b608d569
--- /dev/null
+++ b/tests/UnitTests/Compiler/CompilerPlugin/templates/compilerplugintest.tpl
@@ -0,0 +1 @@
+{compilerplugin}
\ No newline at end of file
diff --git a/tests/UnitTests/Compiler/Delimiter/DelimiterTest.php b/tests/UnitTests/Compiler/Delimiter/DelimiterTest.php
new file mode 100644
index 00000000..17a89c6f
--- /dev/null
+++ b/tests/UnitTests/Compiler/Delimiter/DelimiterTest.php
@@ -0,0 +1,70 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test <{ }> delimiter
+ */
+ public function testDelimiter1()
+ {
+ $this->smarty->left_delimiter = '<{';
+ $this->smarty->right_delimiter = '}>';
+ $tpl = $this->smarty->createTemplate('eval:<{* comment *}><{if true}><{"hello world"}><{/if}>');
+ $this->assertEquals("hello world", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test <-{ }-> delimiter
+ */
+ public function testDelimiter2()
+ {
+ $this->smarty->left_delimiter = '<-{';
+ $this->smarty->right_delimiter = '}->';
+ $tpl = $this->smarty->createTemplate('eval:<-{* comment *}-><-{if true}-><-{"hello world"}-><-{/if}->');
+ $this->assertEquals("hello world", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test <--{ }--> delimiter
+ */
+ public function testDelimiter3()
+ {
+ $this->smarty->left_delimiter = '<--{';
+ $this->smarty->right_delimiter = '}-->';
+ $tpl = $this->smarty->createTemplate('eval:<--{* comment *}--><--{if true}--><--{"hello world"}--><--{/if}-->');
+ $this->assertEquals("hello world", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test {{ }} delimiter
+ */
+ public function testDelimiter4()
+ {
+ $this->smarty->left_delimiter = '{{';
+ $this->smarty->right_delimiter = '}}';
+ $tpl = $this->smarty->createTemplate('eval:{{* comment *}}{{if true}}{{"hello world"}}{{/if}}');
+ $this->assertEquals("hello world", $this->smarty->fetch($tpl));
+ }
+
+}
diff --git a/tests/UnitTests/ConfigFileTests/ConfigVarTest.php b/tests/UnitTests/ConfigFileTests/ConfigVarTest.php
new file mode 100644
index 00000000..9638535d
--- /dev/null
+++ b/tests/UnitTests/ConfigFileTests/ConfigVarTest.php
@@ -0,0 +1,379 @@
+setUpSmarty(__DIR__);
+ }
+
+ /**
+ * empty templat_c and cache folders
+ */
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test number config variable
+ */
+ public function testConfigNumber()
+ {
+ $this->smarty->configLoad('test.conf');
+ $this->assertEquals("123.4", $this->smarty->fetch('eval:{#Number#}'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ * test string config variable
+ */
+ public function testConfigText()
+ {
+ $this->smarty->configLoad('test.conf');
+ $this->assertEquals("123bvc", $this->smarty->fetch('eval:{#text#}'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ * test line string config variable
+ */
+ public function testConfigLine()
+ {
+ $this->smarty->configLoad('test.conf');
+ $this->assertEquals("123 This is a line", $this->smarty->fetch('eval:{#line#}'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ * test config variables in global sections
+ */
+ public function testConfigVariableGlobalSections()
+ {
+ $this->smarty->configLoad('test.conf');
+ $this->assertEquals("Welcome to Smarty! Global Section1 Global Section2", $this->smarty->fetch('eval:{#title#} {#sec1#} {#sec2#}'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ * test config variables loading section2
+ */
+ public function testConfigVariableSection2()
+ {
+ $this->smarty->configLoad('test.conf', 'section2');
+ $this->assertEquals("Welcome to Smarty! Global Section1 Hello Section2", $this->smarty->fetch('eval:{#title#} {#sec1#} {#sec2#}'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ * test config variables loading section special char
+ */
+ public function testConfigVariableSectionSpecialChar()
+ {
+ $this->smarty->configLoad('test.conf', '/');
+ $this->assertEquals("Welcome to Smarty! special char", $this->smarty->fetch('eval:{#title#} {#sec#}'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ * test config variables loading section foo/bar
+ */
+ public function testConfigVariableSectionFooBar()
+ {
+ $this->smarty->configLoad('test.conf', 'foo/bar');
+ $this->assertEquals("Welcome to Smarty! section foo/bar", $this->smarty->fetch('eval:{#title#} {#sec#}'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ * test config variables loaded in different scopes from different sections (Smarty and template)
+ */
+ public function testConfigDifferentScope()
+ {
+ $this->smarty->configLoad('test.conf', 'section2');
+ $tpl = $this->smarty->createTemplate('eval:{#title#} {#sec1#} {#sec2#}');
+ $tpl->configLoad('test.conf', 'section1');
+ $this->assertEquals("Welcome to Smarty! Global Section1 Hello Section2", $this->smarty->fetch('eval:{#title#} {#sec1#} {#sec2#}'));
+ $this->assertEquals("Welcome to Smarty! Hello Section1 Global Section2", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test config variables of hidden sections
+ * shall display variables from hidden section
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigVariableHidden()
+ {
+ $this->smarty->config_read_hidden = true;
+ $this->smarty->configLoad('test.conf', 'hidden');
+ $this->assertEquals("Welcome to Smarty!Hidden Section", $this->smarty->fetch('eval:{#title#}{#hiddentext#}'));
+ }
+
+ /**
+ * test config variables of disabled hidden sections
+ * shall display not variables from hidden section
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigVariableHiddenDisable()
+ {
+ $this->smarty->setErrorReporting(error_reporting() & ~(E_NOTICE | E_USER_NOTICE));
+ $this->smarty->config_read_hidden = false;
+ $this->smarty->configLoad('test.conf', 'hidden');
+ $this->assertEquals("Welcome to Smarty!", $this->smarty->fetch('eval:{#title#}{#hiddentext#}'));
+ }
+
+ /**
+ * test getConfigVars
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigGetSingleConfigVar()
+ {
+ $this->smarty->configLoad('test.conf');
+ $this->assertEquals("Welcome to Smarty!", $this->smarty->getConfigVars('title'));
+ }
+
+ /**
+ * test getConfigVars return all variables
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigGetAllConfigVars()
+ {
+ $this->smarty->configLoad('test.conf');
+ $vars = $this->smarty->getConfigVars();
+ $this->assertTrue(is_array($vars));
+ $this->assertEquals("Welcome to Smarty!", $vars['title']);
+ $this->assertEquals("Global Section1", $vars['sec1']);
+ }
+
+ /**
+ * test clearConfig for single variable
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigClearSingleConfigVar()
+ {
+ $this->smarty->configLoad('test.conf');
+ $this->smarty->clearConfig('title');
+ $this->assertEquals("", $this->smarty->getConfigVars('title'));
+ }
+
+ /**
+ * test clearConfig for all variables
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigClearConfigAll()
+ {
+ $this->smarty->configLoad('test.conf');
+ $this->smarty->clearConfig();
+ $vars = $this->smarty->getConfigVars();
+ $this->assertTrue(is_array($vars));
+ $this->assertTrue(empty($vars));
+ }
+
+ /**
+ * test config vars on data object
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigTextData()
+ {
+ $data = $this->smarty->createData();
+ $data->configLoad('test.conf');
+ $this->assertEquals("123bvc", $this->smarty->fetch('eval:{#text#}', $data));
+ }
+
+ /**
+ * test getConfigVars on data object
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigGetSingleConfigVarData()
+ {
+ $data = $this->smarty->createData();
+ $data->configLoad('test.conf');
+ $this->assertEquals("Welcome to Smarty!", $data->getConfigVars('title'));
+ }
+
+ /**
+ * test getConfigVars return all variables on data object
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigGetAllConfigVarsData()
+ {
+ $data = $this->smarty->createData();
+ $data->configLoad('test.conf');
+ $vars = $data->getConfigVars();
+ $this->assertTrue(is_array($vars));
+ $this->assertEquals("Welcome to Smarty!", $vars['title']);
+ $this->assertEquals("Global Section1", $vars['sec1']);
+ }
+
+ /**
+ * test clearConfig for single variable on data object
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigClearSingleConfigVarData()
+ {
+ $data = $this->smarty->createData();
+ $data->configLoad('test.conf');
+ $data->clearConfig('title');
+ $this->assertEquals("", $data->getConfigVars('title'));
+ $this->assertEquals("Global Section1", $data->getConfigVars('sec1'));
+ }
+
+ /**
+ * test clearConfig for all variables on data object
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigClearConfigAllData()
+ {
+ $data = $this->smarty->createData();
+ $data->configLoad('test.conf');
+ $data->clearConfig();
+ $vars = $data->getConfigVars();
+ $this->assertTrue(is_array($vars));
+ $this->assertTrue(empty($vars));
+ }
+
+ /**
+ * test config vars on template object
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigTextTemplate()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{#text#}');
+ $tpl->configLoad('test.conf');
+ $this->assertEquals("123bvc", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test getConfigVars on template object
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigGetSingleConfigVarTemplate()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{#text#}');
+ $tpl->configLoad('test.conf');
+ $this->assertEquals("Welcome to Smarty!", $tpl->getConfigVars('title'));
+ }
+
+ /**
+ * test getConfigVars return all variables on template object
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigGetAllConfigVarsTemplate()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{#text#}');
+ $tpl->configLoad('test.conf');
+ $vars = $tpl->getConfigVars();
+ $this->assertTrue(is_array($vars));
+ $this->assertEquals("Welcome to Smarty!", $vars['title']);
+ $this->assertEquals("Global Section1", $vars['sec1']);
+ }
+
+ /**
+ * test clearConfig for single variable on template object
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigClearSingleConfigVarTemplate()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{#text#}');
+ $tpl->configLoad('test.conf');
+ $tpl->clearConfig('title');
+ $this->assertEquals("", $tpl->getConfigVars('title'));
+ $this->assertEquals("Global Section1", $tpl->getConfigVars('sec1'));
+ }
+
+ /**
+ * test clearConfig for all variables on template object
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigClearConfigAllTemplate()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{#text#}');
+ $tpl->configLoad('test.conf');
+ $tpl->clearConfig();
+ $vars = $tpl->getConfigVars();
+ $this->assertTrue(is_array($vars));
+ $this->assertTrue(empty($vars));
+ }
+
+ /**
+ * test config variables loading from absolute file path
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigAbsolutePath()
+ {
+ $file = realpath($this->smarty->getConfigDir(0) . 'test.conf');
+ $this->smarty->configLoad($file);
+ $this->assertEquals("123.4", $this->smarty->fetch('eval:{#Number#}'));
+ }
+
+ public function testConfigResourceDb4()
+ {
+ $this->smarty->addPluginsDir(dirname(__FILE__) . "/PHPunitplugins/");
+ $this->smarty->configLoad('db4:foo.conf');
+ $this->assertEquals("bar", $this->smarty->fetch('eval:{#foo#}'));
+ }
+}
diff --git a/tests/UnitTests/ConfigFileTests/DefaultConfigHandlerTest.php b/tests/UnitTests/ConfigFileTests/DefaultConfigHandlerTest.php
new file mode 100644
index 00000000..0f87bebb
--- /dev/null
+++ b/tests/UnitTests/ConfigFileTests/DefaultConfigHandlerTest.php
@@ -0,0 +1,143 @@
+setUpSmarty(__DIR__);
+ $this->smarty->setForceCompile(true);
+ }
+
+ /**
+ * @expectedException SmartyException
+ * @expectedExceptionMessage Unable to read
+ * @expectedExceptionMessage file 'foo.conf'
+ *
+ * test unknown config file
+ */
+ public function testUnknownConfigFile()
+ {
+ $this->smarty->configLoad('foo.conf');
+ }
+
+ /**
+ * @expectedException SmartyException
+ * @expectedExceptionMessage Default config handler
+ * @expectedExceptionMessage not callable
+ *
+ * test register unknown default config handler
+ *
+ */
+ public function testRegisterUnknownDefaultConfigHandler()
+ {
+ $this->smarty->registerDefaultConfigHandler('foo');
+ }
+
+ /**
+ * test default config handler replacement (config data)
+ *
+ * @throws \Exception
+ * @throws \SmartyException
+ */
+ public function testDefaultConfigHandlerReplacement()
+ {
+ $this->smarty->registerDefaultConfigHandler('configHandlerData');
+ $this->smarty->configLoad('foo.conf');
+ $this->assertEquals("bar", $this->smarty->fetch('eval:{#foo#}'));
+ }
+
+ /**
+ * test default config handler replacement (other config file)
+ *
+ * @throws \Exception
+ * @throws \SmartyException
+ */
+ public function testDefaultConfigHandlerReplacementByConfigFile()
+ {
+ $this->smarty->registerDefaultConfigHandler('configHandlerFile');
+ $this->smarty->configLoad('foo.conf');
+ $this->assertEquals("123.4", $this->smarty->fetch('eval:{#Number#}'));
+ }
+
+ /**
+ * @expectedException SmartyException
+ * @expectedExceptionMessage Unable to read
+ * @expectedExceptionMessage file 'foo.conf'
+ *
+ * test default config handler replacement (return false)
+ *
+ */
+ public function testDefaultConfigHandlerReplacementReturningFalse()
+ {
+ $this->smarty->configLoad('foo.conf');
+ }
+}
+
+/**
+ * config handler returning config data
+ *
+ * @param $resource_type
+ * @param $resource_name
+ * @param $config_source
+ * @param $config_timestamp
+ * @param \Smarty $smarty
+ *
+ * @return bool
+ */
+function configHandlerData($resource_type, $resource_name, &$config_source, &$config_timestamp, Smarty $smarty)
+{
+ $output = "foo = 'bar'\n";
+ $config_source = $output;
+ $config_timestamp = time();
+
+ return true;
+}
+
+/**
+ * config handler returning config file
+ *
+ * @param $resource_type
+ * @param $resource_name
+ * @param $config_source
+ * @param $config_timestamp
+ * @param \Smarty $smarty
+ *
+ * @return string
+ */
+function configHandlerFile($resource_type, $resource_name, &$config_source, &$config_timestamp, Smarty $smarty)
+{
+ return $smarty->getConfigDir(0) . 'test.conf';
+}
+
+/**
+ * config handler returning false
+ *
+ * @param $resource_type
+ * @param $resource_name
+ * @param $config_source
+ * @param $config_timestamp
+ * @param \Smarty $smarty
+ *
+ * @return bool
+ */
+function configHandlerFalse($resource_type, $resource_name, &$config_source, &$config_timestamp, Smarty $smarty)
+{
+ return false;
+}
diff --git a/tests/UnitTests/ConfigFileTests/PHPunitplugins/resource.db4.php b/tests/UnitTests/ConfigFileTests/PHPunitplugins/resource.db4.php
new file mode 100644
index 00000000..920c349a
--- /dev/null
+++ b/tests/UnitTests/ConfigFileTests/PHPunitplugins/resource.db4.php
@@ -0,0 +1,27 @@
+filepath = 'db4:';
+ $source->uid = sha1($source->resource);
+ $source->timestamp = 0;
+ $source->exists = true;
+ }
+
+ public function getContent(Smarty_Template_Source $source)
+ {
+ return "foo = 'bar'\n";
+ }
+}
diff --git a/tests/UnitTests/ConfigFileTests/configs/test.conf b/tests/UnitTests/ConfigFileTests/configs/test.conf
new file mode 100644
index 00000000..9bd1731c
--- /dev/null
+++ b/tests/UnitTests/ConfigFileTests/configs/test.conf
@@ -0,0 +1,49 @@
+title = Welcome to Smarty!
+
+overwrite = Overwrite1
+overwrite = Overwrite2
+
+booleanon = on
+
+Intro = """This is a value that spans more
+ than one line. you must enclose
+ it in triple quotes."""
+
+Number = 123.4
+
+text = 123bvc
+
+line = 123 This is a line
+
+sec1 = Global Section1
+
+sec2 = Global Section2
+
+sec = Global char
+[/]
+sec = special char
+
+[foo/bar]
+sec = section foo/bar
+
+[section1]
+sec1 = Hello Section1
+
+[section2]
+sec2 = 'Hello Section2'
+
+[.hidden]
+hiddentext = Hidden Section
+
+#Comment
+# Comment with a space first line first
+ #Comment line starting with space
+ # Space before and after #
+#The line below only contains a #
+#
+#
+# title = This is not the correct title
+
+#[section1]
+#sec1 = Wrong text
+
diff --git a/tests/UnitTests/ResourceTests/Custom/Ambiguous/CustomResourceAmbiguousTest.php b/tests/UnitTests/ResourceTests/Custom/Ambiguous/CustomResourceAmbiguousTest.php
new file mode 100644
index 00000000..c206664c
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Custom/Ambiguous/CustomResourceAmbiguousTest.php
@@ -0,0 +1,119 @@
+setUpSmarty(__DIR__);
+ require_once dirname(__FILE__) . '/PHPunitplugins/resource.ambiguous.php';
+
+ // empty the template dir
+ $this->smarty->setTemplateDir(array());
+
+ // kill cache for unit test
+ // Smarty::$_resource_cache = array();
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ protected function relative($path)
+ {
+ $path = str_replace(dirname(__FILE__), '.', $path);
+ if (DS == "\\") {
+ $path = str_replace("\\", "/", $path);
+ }
+
+ return $path;
+ }
+
+ public function testNone()
+ {
+ $resource_handler = new Smarty_Resource_Ambiguous(dirname(__FILE__) . '/templates/ambiguous/');
+ $this->smarty->registerResource('ambiguous', $resource_handler);
+ $this->smarty->setDefaultResourceType('ambiguous');
+ $this->smarty->setAllowAmbiguousResources(true);
+
+ $tpl = $this->smarty->createTemplate('foobar.tpl');
+ $this->assertFalse($tpl->source->exists);
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testCase1()
+ {
+ $resource_handler = new Smarty_Resource_Ambiguous(dirname(__FILE__) . '/templates/ambiguous/');
+ $this->smarty->registerResource('ambiguous', $resource_handler);
+ $this->smarty->setDefaultResourceType('ambiguous');
+ $this->smarty->setAllowAmbiguousResources(true);
+
+ $resource_handler->setSegment('case1');
+
+ $tpl = $this->smarty->createTemplate('foobar.tpl');
+ $this->assertTrue($tpl->source->exists);
+ $this->assertEquals('case1', $tpl->source->content);
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testCase2()
+ {
+ $resource_handler = new Smarty_Resource_Ambiguous(dirname(__FILE__) . '/templates/ambiguous/');
+ $this->smarty->registerResource('ambiguous', $resource_handler);
+ $this->smarty->setDefaultResourceType('ambiguous');
+ $this->smarty->setAllowAmbiguousResources(true);
+
+ $resource_handler->setSegment('case2');
+
+ $tpl = $this->smarty->createTemplate('foobar.tpl');
+ $this->assertTrue($tpl->source->exists);
+ $this->assertEquals('case2', $tpl->source->content);
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testCaseSwitching()
+ {
+ $resource_handler = new Smarty_Resource_Ambiguous(dirname(__FILE__) . '/templates/ambiguous/');
+ $this->smarty->registerResource('ambiguous', $resource_handler);
+ $this->smarty->setDefaultResourceType('ambiguous');
+ $this->smarty->setAllowAmbiguousResources(true);
+
+ $resource_handler->setSegment('case1');
+ $tpl = $this->smarty->createTemplate('foobar.tpl');
+ $this->assertTrue($tpl->source->exists);
+ $this->assertEquals('case1', $tpl->source->content);
+
+ $resource_handler->setSegment('case2');
+ $tpl = $this->smarty->createTemplate('foobar.tpl');
+ $this->assertTrue($tpl->source->exists);
+ $this->assertEquals('case2', $tpl->source->content);
+ }
+}
diff --git a/tests/UnitTests/ResourceTests/Custom/Ambiguous/PHPunitplugins/resource.ambiguous.php b/tests/UnitTests/ResourceTests/Custom/Ambiguous/PHPunitplugins/resource.ambiguous.php
new file mode 100644
index 00000000..697a5c4e
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Custom/Ambiguous/PHPunitplugins/resource.ambiguous.php
@@ -0,0 +1,58 @@
+directory = rtrim($directory, "/\\") . DS;
+ // parent::__construct();
+ }
+
+ public function setSegment($segment)
+ {
+ $this->segment = $segment;
+ }
+
+ /**
+ * modify resource_name according to resource handlers specifications
+ *
+ * @param Smarty $smarty Smarty instance
+ * @param string $resource_name resource_name to make unique
+ *
+ * @return string unique resource name
+ */
+ public function buildUniqueResourceName(Smarty $smarty, $resource_name, $isConfig = false)
+ {
+ return get_class($this) . '#' . $this->segment . '#' . $resource_name;
+ }
+
+ /**
+ * populate Source Object with meta data from Resource
+ *
+ * @param Smarty_Template_Source $source source object
+ * @param Smarty_Internal_Template $_template template object
+ */
+ public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null)
+ {
+ $segment = '';
+ if ($this->segment) {
+ $segment = rtrim($this->segment, "/\\") . DS;
+ }
+
+ $source->filepath = $this->directory . $segment . $source->name;
+ $source->uid = sha1($source->filepath);
+ if ($_template->smarty->getCompileCheck() && !isset($source->timestamp)) {
+ $source->timestamp = @filemtime($source->filepath);
+ $source->exists = !!$source->timestamp;
+ }
+ }
+}
diff --git a/tests/UnitTests/ResourceTests/Custom/Ambiguous/templates/ambiguous/case1/foobar.tpl b/tests/UnitTests/ResourceTests/Custom/Ambiguous/templates/ambiguous/case1/foobar.tpl
new file mode 100644
index 00000000..a5b129ba
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Custom/Ambiguous/templates/ambiguous/case1/foobar.tpl
@@ -0,0 +1 @@
+case1
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/Custom/Ambiguous/templates/ambiguous/case2/foobar.tpl b/tests/UnitTests/ResourceTests/Custom/Ambiguous/templates/ambiguous/case2/foobar.tpl
new file mode 100644
index 00000000..065ab5bc
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Custom/Ambiguous/templates/ambiguous/case2/foobar.tpl
@@ -0,0 +1 @@
+case2
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/ResourceExtendsAllPluginTest.php b/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/ResourceExtendsAllPluginTest.php
new file mode 100644
index 00000000..37578418
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/ResourceExtendsAllPluginTest.php
@@ -0,0 +1,54 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ public function testResourcePluginExtendsall()
+ {
+ $this->smarty->addPluginsDir(SMARTY_DIR . "../demo/plugins/");
+ $this->smarty->setTemplateDir(array(
+ 'root' => './templates',
+ './templates_2',
+ './templates_3',
+ './templates_4',
+ ));
+
+ $expected = "templates\n\n templates_3\n templates\n\ntemplates_4";
+ $this->assertEquals($expected, $this->smarty->fetch('extendsall:extendsall.tpl'));
+ }
+
+ public function testResourcePluginExtendsallOne()
+ {
+ $this->smarty->addPluginsDir(SMARTY_DIR . "../demo/plugins/");
+ $this->smarty->setTemplateDir(array(
+ 'root' => './templates',
+ './templates_2',
+ './templates_3',
+ './templates_4',
+ ));
+
+ $expected = "templates\ntemplates";
+ $this->assertEquals($expected, $this->smarty->fetch('extendsall:extendsall2.tpl'));
+ }
+}
diff --git a/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/templates/extendsall.tpl b/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/templates/extendsall.tpl
new file mode 100644
index 00000000..988c37e0
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/templates/extendsall.tpl
@@ -0,0 +1,2 @@
+{block name="alpha"}templates{/block}
+{block name="bravo_2"}templates{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/templates/extendsall2.tpl b/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/templates/extendsall2.tpl
new file mode 100644
index 00000000..988c37e0
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/templates/extendsall2.tpl
@@ -0,0 +1,2 @@
+{block name="alpha"}templates{/block}
+{block name="bravo_2"}templates{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/templates_2/helloworld.php b/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/templates_2/helloworld.php
new file mode 100644
index 00000000..77eb622a
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/templates_2/helloworld.php
@@ -0,0 +1 @@
+php hello world
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/templates_3/extendsall.tpl b/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/templates_3/extendsall.tpl
new file mode 100644
index 00000000..0b79019d
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/templates_3/extendsall.tpl
@@ -0,0 +1,5 @@
+{block name="alpha"}templates_3{/block}
+{block name="bravo"}
+ {block name="bravo_1"}templates_3{/block}
+ {block name="bravo_2"}templates_3{/block}
+{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/templates_4/extendsall.tpl b/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/templates_4/extendsall.tpl
new file mode 100644
index 00000000..93557dca
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Custom/DemoPluginExtendsAll/templates_4/extendsall.tpl
@@ -0,0 +1,3 @@
+{block name="alpha"}templates_4{/block}
+{block name="bravo"}templates_4{/block}
+{block name="charlie"}templates_4{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/Custom/DemoPluginMysql/PHPunitplugins/resource.mysqlstest.php b/tests/UnitTests/ResourceTests/Custom/DemoPluginMysql/PHPunitplugins/resource.mysqlstest.php
new file mode 100644
index 00000000..f64ab457
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Custom/DemoPluginMysql/PHPunitplugins/resource.mysqlstest.php
@@ -0,0 +1,18 @@
+db = PHPUnit_Smarty::$pdo;
+ }
+ catch
+ (PDOException $e) {
+ throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
+ }
+ $this->fetch = $this->db->prepare('SELECT modified, source FROM templates WHERE name = :name');
+ }
+}
+
diff --git a/tests/UnitTests/ResourceTests/Custom/DemoPluginMysql/PHPunitplugins/resource.mysqltest.php b/tests/UnitTests/ResourceTests/Custom/DemoPluginMysql/PHPunitplugins/resource.mysqltest.php
new file mode 100644
index 00000000..2b05da9d
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Custom/DemoPluginMysql/PHPunitplugins/resource.mysqltest.php
@@ -0,0 +1,19 @@
+db = PHPUnit_Smarty::$pdo;
+ }
+ catch
+ (PDOException $e) {
+ throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
+ }
+ $this->fetch = $this->db->prepare('SELECT modified, source FROM templates WHERE name = :name');
+ $this->mtime = $this->db->prepare('SELECT modified FROM templates WHERE name = :name');
+ }
+}
+
diff --git a/tests/UnitTests/ResourceTests/Custom/DemoPluginMysql/ResourceMysqlPluginTest.php b/tests/UnitTests/ResourceTests/Custom/DemoPluginMysql/ResourceMysqlPluginTest.php
new file mode 100644
index 00000000..e247c847
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Custom/DemoPluginMysql/ResourceMysqlPluginTest.php
@@ -0,0 +1,93 @@
+markTestSkipped('mysql tests are disabled');
+ }
+ if (self::$init) {
+ $this->getConnection();
+ }
+ $this->setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ $this->initMysqlResource();
+ PHPUnit_Smarty::$pdo->exec("REPLACE INTO templates VALUES ('test.tpl', '2010-12-25 22:00:00', '{\$x = \'hello world\'}{\$x}' )");
+ }
+
+ /**
+ * test resource plugin rendering of a custom resource
+ */
+ public function testResourcePluginMysql()
+ {
+ //$this->smarty->addPluginsDir(SMARTY_DIR . "../demo/plugins/");
+ $this->smarty->addPluginsDir("./PHPunitplugins/");
+ $this->assertEquals('hello world', $this->smarty->fetch('mysqltest:test.tpl'));
+ }
+
+ /**
+ * test resource plugin timestamp of a custom resource
+ */
+ public function testResourcePluginMysqlTimestamp()
+ {
+ // $this->smarty->addPluginsDir(SMARTY_DIR . "../demo/plugins/");
+ $this->smarty->addPluginsDir("./PHPunitplugins/");
+ $tpl = $this->smarty->createTemplate('mysqltest:test.tpl');
+ $this->assertEquals(strtotime("2010-12-25 22:00:00"), $tpl->source->timestamp);
+ }
+
+ /**
+ * test resource plugin compiledFilepath of a custom resource
+ */
+ public function testResourcePluginMysqlCompiledFilepath()
+ {
+ // $this->smarty->addPluginsDir(SMARTY_DIR . "../demo/plugins/");
+ $this->smarty->addPluginsDir("./PHPunitplugins/");
+ $tpl = $this->smarty->createTemplate('mysqltest:test.tpl');
+ $this->assertEquals($this->buildCompiledPath($tpl, false, false, null, 'test.tpl', 'mysqltest', $this->smarty->getTemplateDir(0))
+ , $tpl->compiled->filepath
+ );
+ }
+
+ public function testResourcePluginMysqlCompiledFilepathCache()
+ {
+ //$this->smarty->addPluginsDir(SMARTY_DIR . "../demo/plugins/");
+ $this->smarty->addPluginsDir("./PHPunitplugins/");
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setForceCompile(true);
+ $this->smarty->fetch('mysqltest:test.tpl');
+ $tpl = $this->smarty->createTemplate('mysqltest:test.tpl');
+ $this->assertEquals($this->buildCompiledPath($tpl, false, true, null, 'test.tpl', 'mysqltest', $this->smarty->getTemplateDir(0))
+ , $tpl->compiled->filepath
+ );
+ $this->smarty->caching = false;
+ }
+ /**
+ * test resource plugin timestamp of a custom resource with only fetch() implemented
+ */
+ public function testResourcePluginMysqlTimestampWithoutFetchTimestamp()
+ {
+ // $this->smarty->addPluginsDir(SMARTY_DIR . "../demo/plugins/");
+ $this->smarty->addPluginsDir("./PHPunitplugins/");
+ $tpl = $this->smarty->createTemplate('mysqlstest:test.tpl');
+ $this->assertEquals(strtotime("2010-12-25 22:00:00"), $tpl->source->timestamp);
+ }
+}
diff --git a/tests/UnitTests/ResourceTests/Custom/DemoPluginMysql/templates/extendsall.tpl b/tests/UnitTests/ResourceTests/Custom/DemoPluginMysql/templates/extendsall.tpl
new file mode 100644
index 00000000..988c37e0
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Custom/DemoPluginMysql/templates/extendsall.tpl
@@ -0,0 +1,2 @@
+{block name="alpha"}templates{/block}
+{block name="bravo_2"}templates{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/Custom/DemoPluginMysql/templates/extendsall2.tpl b/tests/UnitTests/ResourceTests/Custom/DemoPluginMysql/templates/extendsall2.tpl
new file mode 100644
index 00000000..988c37e0
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Custom/DemoPluginMysql/templates/extendsall2.tpl
@@ -0,0 +1,2 @@
+{block name="alpha"}templates{/block}
+{block name="bravo_2"}templates{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/DefaultHandler/DefaultTemplateHandlerTest.php b/tests/UnitTests/ResourceTests/DefaultHandler/DefaultTemplateHandlerTest.php
new file mode 100644
index 00000000..58ab084c
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/DefaultHandler/DefaultTemplateHandlerTest.php
@@ -0,0 +1,111 @@
+setUpSmarty(__DIR__);
+ $this->smarty->setForceCompile(true);
+ $this->smarty->disableSecurity();
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test error on unknow template
+ */
+ public function testUnknownTemplate()
+ {
+ try {
+ $this->smarty->fetch('foo.tpl');
+ }
+ catch (Exception $e) {
+ $this->assertContains('Unable to load template', $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for none existing template has not been raised.');
+ }
+
+ /**
+ * test error on registration on none existent handler function.
+ */
+ public function testRegisterNoneExistentHandlerFunction()
+ {
+ try {
+ $this->smarty->registerDefaultTemplateHandler('foo');
+ }
+ catch (Exception $e) {
+ $this->assertContains("Default template handler", $e->getMessage());
+ $this->assertContains("not callable", $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for none callable function has not been raised.');
+ }
+ /**
+ * test replacement by default template handler
+ */
+ /**
+ * public function testDefaultTemplateHandlerReplacement()
+ * {
+ * $this->smarty->register->defaultTemplateHandler('my_template_handler');
+ * $this->assertEquals("Recsource foo.tpl of type file not found", $this->smarty->fetch('foo.tpl'));
+ * }
+ */
+ public function testDefaultTemplateHandlerReplacementByTemplateFile()
+ {
+ $this->smarty->registerDefaultTemplateHandler('my_template_handler_file');
+ $this->assertEquals("hello world", $this->smarty->fetch('foo.tpl'));
+ }
+
+ /**
+ * test default template handler returning fals
+ */
+ public function testDefaultTemplateHandlerReturningFalse()
+ {
+ $this->smarty->registerDefaultTemplateHandler('my_false');
+ try {
+ $this->smarty->fetch('foo.tpl');
+ }
+ catch (Exception $e) {
+ $this->assertContains('Unable to load template', $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for none existing template has not been raised.');
+ }
+}
+
+function my_template_handler($resource_type, $resource_name, &$template_source, &$template_timestamp, Smarty $smarty)
+{
+ $output = "Recsource $resource_name of type $resource_type not found";
+ $template_source = $output;
+ $template_timestamp = time();
+
+ return true;
+}
+
+function my_template_handler_file($resource_type, $resource_name, &$template_source, &$template_timestamp, Smarty $smarty)
+{
+ return $smarty->getTemplateDir(0) . 'helloworld.tpl';
+}
+
+function my_false($resource_type, $resource_name, &$template_source, &$template_timestamp, Smarty $smarty)
+{
+ return false;
+}
diff --git a/tests/UnitTests/ResourceTests/DefaultHandler/templates/helloworld.tpl b/tests/UnitTests/ResourceTests/DefaultHandler/templates/helloworld.tpl
new file mode 100644
index 00000000..95d09f2b
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/DefaultHandler/templates/helloworld.tpl
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/Eval/EvalResourceTest.php b/tests/UnitTests/ResourceTests/Eval/EvalResourceTest.php
new file mode 100644
index 00000000..b2d6df98
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Eval/EvalResourceTest.php
@@ -0,0 +1,177 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test template eval exits
+ */
+ public function testTemplateEvalExists1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo}');
+ $this->assertTrue($tpl->source->exists);
+ }
+
+ public function testTemplateEvalExists2()
+ {
+ $this->assertTrue($this->smarty->templateExists('eval:{$foo}'));
+ }
+
+ /**
+ * test getTemplateFilepath
+ */
+ public function testGetTemplateFilepath()
+ {
+ $tpl = $this->smarty->createTemplate('eval:hello world');
+ $this->assertEquals('2aae6c35c94fcfb415dbe95f408b9ce91ee846ed', $tpl->source->filepath);
+ }
+
+ /**
+ * test getTemplateTimestamp
+ */
+ public function testGetTemplateTimestamp()
+ {
+ $tpl = $this->smarty->createTemplate('eval:hello world');
+ $this->assertFalse($tpl->source->timestamp);
+ }
+
+ /**
+ * test getTemplateSource
+ */
+ public function testGetTemplateSource()
+ {
+ $tpl = $this->smarty->createTemplate('eval:hello world{$foo}');
+ $this->assertEquals('hello world{$foo}', $tpl->source->content);
+ }
+
+ /**
+ * test empty templates
+ */
+ public function testEmptyTemplate()
+ {
+ $tpl = $this->smarty->createTemplate('eval:');
+ $this->assertEquals('', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test usesCompiler
+ */
+ public function testUsesCompiler()
+ {
+ $tpl = $this->smarty->createTemplate('eval:hello world');
+ $this->assertFalse($tpl->source->uncompiled);
+ }
+
+ /**
+ * test isEvaluated
+ */
+ public function testIsEvaluated()
+ {
+ $tpl = $this->smarty->createTemplate('eval:hello world');
+ $this->assertTrue($tpl->source->recompiled);
+ }
+
+ /**
+ * test mustCompile
+ */
+ public function testMustCompile()
+ {
+ $tpl = $this->smarty->createTemplate('eval:hello world');
+ $this->assertTrue($tpl->mustCompile());
+ }
+
+ /**
+ * test getCompiledFilepath
+ */
+ public function testGetCompiledFilepath()
+ {
+ $tpl = $this->smarty->createTemplate('eval:hello world');
+ $this->assertFalse($tpl->compiled->filepath);
+ }
+
+ /**
+ * test getCompiledTimestamp
+ */
+ public function testGetCompiledTimestamp()
+ {
+ $tpl = $this->smarty->createTemplate('eval:hello world');
+ $this->assertFalse($tpl->compiled->timestamp);
+ }
+
+ /**
+ * test isCached
+ */
+ public function testIsCached()
+ {
+ $tpl = $this->smarty->createTemplate('eval:hello world');
+ $this->assertFalse($tpl->isCached());
+ }
+
+ /**
+ * test getRenderedTemplate
+ */
+ public function testGetRenderedTemplate()
+ {
+ $tpl = $this->smarty->createTemplate('eval:hello world');
+ $this->assertEquals('hello world', $tpl->fetch());
+ }
+
+ /**
+ * test that no complied template and cache file was produced
+ */
+ public function testNoFiles()
+ {
+ $this->cleanDir($this->smarty->getCacheDir());
+ $this->cleanDir($this->smarty->getCompileDir());
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 20;
+ $tpl = $this->smarty->createTemplate('eval:hello world');
+ $this->assertEquals('hello world', $this->smarty->fetch($tpl));
+ $this->assertEquals(0, $this->smarty->clearAllCache());
+ $this->assertEquals(0, $this->smarty->clearCompiledTemplate());
+ }
+
+ /**
+ * test $smarty->is_cached
+ */
+ public function testSmartyIsCached()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 20;
+ $tpl = $this->smarty->createTemplate('eval:hello world');
+ $this->assertEquals('hello world', $this->smarty->fetch($tpl));
+ $this->assertFalse($this->smarty->isCached($tpl));
+ }
+
+ public function testUrlencodeTemplate()
+ {
+ $tpl = $this->smarty->createTemplate('eval:urlencode:%7B%22foobar%22%7Cescape%7D');
+ $this->assertEquals('foobar', $tpl->fetch());
+ }
+
+ public function testBase64Template()
+ {
+ $tpl = $this->smarty->createTemplate('eval:base64:eyJmb29iYXIifGVzY2FwZX0=');
+ $this->assertEquals('foobar', $tpl->fetch());
+ }
+}
diff --git a/tests/UnitTests/ResourceTests/Extends/ExtendsResourceTest.php b/tests/UnitTests/ResourceTests/Extends/ExtendsResourceTest.php
new file mode 100644
index 00000000..263e730f
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Extends/ExtendsResourceTest.php
@@ -0,0 +1,45 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test child/parent template chain with prepend
+ */
+ public function testCompileBlockChildPrepend_003()
+ {
+ $result = $this->smarty->fetch('extends:003_parent.tpl|003_child_prepend.tpl');
+ $this->assertContains("prepend - Default Title", $result);
+ }
+
+ /**
+ * test child/parent template chain with apppend
+ */
+ public function testCompileBlockChildAppend_004()
+ {
+ $this->smarty->merge_compiled_includes = true;
+ $result = $this->smarty->fetch('extends:004_parent.tpl|004_child_append.tpl');
+ $this->assertContains("Default Title - append", $result);
+ }
+}
+
diff --git a/tests/UnitTests/ResourceTests/Extends/templates/003_child_prepend.tpl b/tests/UnitTests/ResourceTests/Extends/templates/003_child_prepend.tpl
new file mode 100644
index 00000000..0e0d05bf
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Extends/templates/003_child_prepend.tpl
@@ -0,0 +1 @@
+{block name='title' prepend}prepend - {/block}
diff --git a/tests/UnitTests/ResourceTests/Extends/templates/003_parent.tpl b/tests/UnitTests/ResourceTests/Extends/templates/003_parent.tpl
new file mode 100644
index 00000000..e007864b
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Extends/templates/003_parent.tpl
@@ -0,0 +1 @@
+{block name='title'}Default Title{/block}
diff --git a/tests/UnitTests/ResourceTests/Extends/templates/004_child_append.tpl b/tests/UnitTests/ResourceTests/Extends/templates/004_child_append.tpl
new file mode 100644
index 00000000..e18550fb
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Extends/templates/004_child_append.tpl
@@ -0,0 +1 @@
+{block name='title' append} - append{/block}
diff --git a/tests/UnitTests/ResourceTests/Extends/templates/004_parent.tpl b/tests/UnitTests/ResourceTests/Extends/templates/004_parent.tpl
new file mode 100644
index 00000000..e007864b
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Extends/templates/004_parent.tpl
@@ -0,0 +1 @@
+{block name='title'}Default Title{/block}
diff --git a/tests/UnitTests/ResourceTests/Extends/templates/040_child.tpl b/tests/UnitTests/ResourceTests/Extends/templates/040_child.tpl
new file mode 100644
index 00000000..54e64f92
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Extends/templates/040_child.tpl
@@ -0,0 +1 @@
+{$foo = 'bar'}
diff --git a/tests/UnitTests/ResourceTests/Extends/templates/040_parent.tpl b/tests/UnitTests/ResourceTests/Extends/templates/040_parent.tpl
new file mode 100644
index 00000000..901a2b09
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Extends/templates/040_parent.tpl
@@ -0,0 +1 @@
+{block name='test'}-{$foo}-{/block}
diff --git a/tests/UnitTests/ResourceTests/File/FileResourceTest.php b/tests/UnitTests/ResourceTests/File/FileResourceTest.php
new file mode 100644
index 00000000..89c42efe
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/FileResourceTest.php
@@ -0,0 +1,277 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ protected function relative($path)
+ {
+ $path = str_replace(str_replace("\\", "/", dirname(__FILE__)), '.', str_replace("\\", "/", $path));
+
+ return $path;
+ }
+
+ /**
+ *
+ */
+ public function testGetTemplateFilepath()
+ {
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->assertEquals("./templates/helloworld.tpl", str_replace('\\', '/', $tpl->source->filepath));
+ }
+
+ public function testTemplateFileExists1()
+ {
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->assertTrue($tpl->source->exists);
+ }
+
+ public function testTemplateFileExists2()
+ {
+ $this->assertTrue($this->smarty->templateExists('helloworld.tpl'));
+ }
+
+ public function testTemplateFileNotExists1()
+ {
+ $tpl = $this->smarty->createTemplate('notthere.tpl');
+ $this->assertFalse($tpl->source->exists);
+ }
+
+ public function testTemplateFileNotExists2()
+ {
+ $this->assertFalse($this->smarty->templateExists('notthere.tpl'));
+ }
+
+ public function testTemplateFileNotExists3()
+ {
+ try {
+ $result = $this->smarty->fetch('notthere.tpl');
+ }
+ catch (Exception $e) {
+ $this->assertContains('Unable to load template file \'notthere.tpl\'', $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for not existing template is missing');
+ }
+
+ public function testGetTemplateTimestamp()
+ {
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->assertTrue(is_integer($tpl->source->timestamp));
+ $this->assertEquals(10, strlen($tpl->source->timestamp));
+ }
+
+ public function testGetTemplateSource()
+ {
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->assertEquals('hello world', $tpl->source->content);
+ }
+
+ public function testUsesCompiler()
+ {
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->assertFalse($tpl->source->uncompiled);
+ }
+
+ public function testIsEvaluated()
+ {
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->assertFalse($tpl->source->recompiled);
+ }
+
+ public function testGetCompiledFilepath()
+ {
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->assertEquals($this->buildCompiledPath($tpl, false, false, null, 'helloworld.tpl', 'file', $this->smarty->getTemplateDir(0))
+ , $tpl->compiled->filepath
+ );
+ }
+
+ public function testGetCompiledTimestampPrepare()
+ {
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ // create dummy compiled file
+ file_put_contents($tpl->compiled->filepath, '');
+ touch($tpl->compiled->filepath, $tpl->source->timestamp);
+ }
+
+ /**
+ *
+ */
+ public function testGetCompiledTimestamp()
+ {
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->assertTrue(is_integer($tpl->compiled->timestamp));
+ $this->assertEquals(10, strlen($tpl->compiled->timestamp));
+ $this->assertEquals($tpl->compiled->timestamp, $tpl->source->timestamp);
+ }
+
+ public function testMustCompileExisting()
+ {
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->assertFalse($tpl->mustCompile());
+ }
+
+ public function testMustCompileAtForceCompile()
+ {
+ $this->smarty->setForceCompile(true);
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->assertTrue($tpl->mustCompile());
+ }
+
+ public function testMustCompileTouchedSourcePrepare()
+ {
+ // touch to prepare next test
+ sleep(2);
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ touch($tpl->source->filepath);
+ }
+ public function testMustCompileTouchedSource()
+ {
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->assertTrue($tpl->mustCompile());
+ // clean up for next tests
+ $this->cleanDir($this->smarty->getCompileDir());
+ }
+
+ public function testCompileTemplateFile()
+ {
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $tpl->compileTemplateSource();
+ $this->assertTrue(file_exists($tpl->compiled->filepath));
+ }
+
+ public function testGetCachedFilepath()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->assertEquals($this->buildCachedPath($tpl, false, null, null, 'helloworld.tpl', 'file', $this->smarty->getTemplateDir(0), 'file')
+ , $tpl->cached->filepath
+ );
+ }
+
+ public function testGetCachedTimestamp()
+ {
+ // create dummy cache file for the following test
+ file_put_contents($this->buildCachedPath($this->smarty, false, null, null, 'helloworld.tpl', 'file', $this->smarty->getTemplateDir(0), 'file')
+ , '');
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->assertTrue(is_integer($tpl->cached->timestamp));
+ $this->assertEquals(10, strlen($tpl->cached->timestamp));
+ }
+
+
+ public function testGetRenderedTemplate()
+ {
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $this->assertEquals('hello world', $tpl->fetch());
+ }
+
+ public function testRelativeInclude()
+ {
+ $result = $this->smarty->fetch('relative.tpl');
+ $this->assertContains('hello world', $result);
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testRelativeIncludeSub()
+ {
+ $result = $this->smarty->fetch('sub/relative.tpl');
+ $this->assertContains('hello world', $result);
+ }
+
+ public function testRelativeIncludeFail()
+ {
+ try {
+ $this->smarty->fetch('relative_sub.tpl');
+ }
+ catch (Exception $e) {
+ $this->assertContains(htmlentities("Unable to load template"), $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for unknown relative filepath has not been raised.');
+ }
+
+ public function testRelativeIncludeFailOtherDir()
+ {
+ $this->smarty->addTemplateDir('./templates_2');
+ try {
+ $this->smarty->fetch('relative_notexist.tpl');
+ }
+ catch (Exception $e) {
+ $this->assertContains("Unable to load template", $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for unknown relative filepath has not been raised.');
+ }
+
+ protected function _relativeMap($map, $cwd = null)
+ {
+ foreach ($map as $file => $result) {
+ $this->cleanDir($this->smarty->getCompileDir());
+ $this->cleanDir($this->smarty->getCacheDir());
+
+ if ($result === null) {
+ try {
+ $this->smarty->fetch($file);
+ if ($cwd !== null) {
+ chdir($cwd);
+ }
+
+ $this->fail('Exception expected for ' . $file);
+
+ return;
+ }
+ catch (SmartyException $e) {
+ // this was expected to fail
+ }
+ } else {
+ try {
+ $_res = $this->smarty->fetch($file);
+ $this->assertEquals(str_replace("\r", '', $result), $_res, $file);
+ }
+ catch (Exception $e) {
+ if ($cwd !== null) {
+ chdir($cwd);
+ }
+
+ throw $e;
+ }
+ }
+ }
+
+ if ($cwd !== null) {
+ chdir($cwd);
+ }
+ }
+}
diff --git a/tests/UnitTests/ResourceTests/File/IndexedFileResourceTest.php b/tests/UnitTests/ResourceTests/File/IndexedFileResourceTest.php
new file mode 100644
index 00000000..bc9970da
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/IndexedFileResourceTest.php
@@ -0,0 +1,91 @@
+setUpSmarty(__DIR__);
+ $path = str_replace(array("\\", "/"), DS, dirname(__FILE__));
+ $this->smarty->addTemplateDir($path . DS. 'templates_2');
+ // note that 10 is a string!
+ $this->smarty->addTemplateDir($path . DS. 'templates_3', '10');
+ $this->smarty->addTemplateDir($path . DS . 'templates_4', 'foo');
+ }
+
+ protected function relative($path)
+ {
+ $path = str_replace(str_replace("\\", "/", dirname(__FILE__)), '.', str_replace("\\", "/", $path));
+
+ return $path;
+ }
+
+ public function testGetTemplateFilepath()
+ {
+ $tpl = $this->smarty->createTemplate('dirname.tpl');
+ $this->assertEquals("./templates/dirname.tpl", $this->relative($tpl->source->filepath));
+ }
+
+ public function testGetTemplateFilepathNumber()
+ {
+ $tpl = $this->smarty->createTemplate('[1]dirname.tpl');
+ $this->assertEquals('./templates_2/dirname.tpl', $this->relative($tpl->source->filepath));
+ }
+
+ public function testGetTemplateFilepathNumeric()
+ {
+ $tpl = $this->smarty->createTemplate('[10]dirname.tpl');
+ $this->assertEquals('./templates_3/dirname.tpl', $this->relative($tpl->source->filepath));
+ }
+
+ public function testGetTemplateFilepathName()
+ {
+ $tpl = $this->smarty->createTemplate('[foo]dirname.tpl');
+ $this->assertEquals('./templates_4/dirname.tpl', $this->relative($tpl->source->filepath));
+ }
+
+ public function testFetch()
+ {
+ $tpl = $this->smarty->createTemplate('dirname.tpl');
+ $this->assertEquals('templates', $this->smarty->fetch($tpl));
+ }
+
+ public function testFetchNumber()
+ {
+ $tpl = $this->smarty->createTemplate('[1]dirname.tpl');
+ $this->assertEquals('templates_2', $this->smarty->fetch($tpl));
+ }
+
+ public function testFetchNumeric()
+ {
+ $tpl = $this->smarty->createTemplate('[10]dirname.tpl');
+ $this->assertEquals('templates_3', $this->smarty->fetch($tpl));
+ }
+
+ public function testFetchName()
+ {
+ $tpl = $this->smarty->createTemplate('[foo]dirname.tpl');
+ $this->assertEquals('templates_4', $this->smarty->fetch($tpl));
+ }
+
+ public function testGetCompiledFilepath()
+ {
+ $tpl = $this->smarty->createTemplate('[foo]dirname.tpl');
+ $this->assertEquals($this->buildCompiledPath($tpl, false, false, null, 'dirname.tpl', 'file', $this->smarty->getTemplateDir('foo')), $tpl->compiled->filepath);
+ }
+
+ public function testGetCachedFilepath()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('[foo]dirname.tpl');
+ $this->assertEquals($this->buildCachedPath($tpl, false, null, null, 'dirname.tpl', 'file', $this->smarty->getTemplateDir('foo'))
+ , $tpl->cached->filepath);
+ }
+}
diff --git a/tests/UnitTests/ResourceTests/File/templates/dirname.tpl b/tests/UnitTests/ResourceTests/File/templates/dirname.tpl
new file mode 100644
index 00000000..f10e14ab
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates/dirname.tpl
@@ -0,0 +1 @@
+templates
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates/helloworld.tpl b/tests/UnitTests/ResourceTests/File/templates/helloworld.tpl
new file mode 100644
index 00000000..95d09f2b
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates/helloworld.tpl
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates/relative.tpl b/tests/UnitTests/ResourceTests/File/templates/relative.tpl
new file mode 100644
index 00000000..5f34e470
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates/relative.tpl
@@ -0,0 +1 @@
+{include file="./helloworld.tpl"}
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates/relative_notexist.tpl b/tests/UnitTests/ResourceTests/File/templates/relative_notexist.tpl
new file mode 100644
index 00000000..11fad976
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates/relative_notexist.tpl
@@ -0,0 +1 @@
+{include file="./hello.tpl"}
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates/relative_sub.tpl b/tests/UnitTests/ResourceTests/File/templates/relative_sub.tpl
new file mode 100644
index 00000000..0185682d
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates/relative_sub.tpl
@@ -0,0 +1 @@
+{include file="../helloworld.tpl"}
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates/relativity/foo.tpl b/tests/UnitTests/ResourceTests/File/templates/relativity/foo.tpl
new file mode 100644
index 00000000..bf4a29c0
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates/relativity/foo.tpl
@@ -0,0 +1 @@
+relativity
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates/relativity/relativity.tpl b/tests/UnitTests/ResourceTests/File/templates/relativity/relativity.tpl
new file mode 100644
index 00000000..bf4a29c0
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates/relativity/relativity.tpl
@@ -0,0 +1 @@
+relativity
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates/relativity/theory/einstein/einstein.tpl b/tests/UnitTests/ResourceTests/File/templates/relativity/theory/einstein/einstein.tpl
new file mode 100644
index 00000000..88e90d97
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates/relativity/theory/einstein/einstein.tpl
@@ -0,0 +1 @@
+einstein
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates/relativity/theory/einstein/foo.tpl b/tests/UnitTests/ResourceTests/File/templates/relativity/theory/einstein/foo.tpl
new file mode 100644
index 00000000..88e90d97
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates/relativity/theory/einstein/foo.tpl
@@ -0,0 +1 @@
+einstein
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates/relativity/theory/foo.tpl b/tests/UnitTests/ResourceTests/File/templates/relativity/theory/foo.tpl
new file mode 100644
index 00000000..195d46ee
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates/relativity/theory/foo.tpl
@@ -0,0 +1 @@
+theory
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates/relativity/theory/theory.tpl b/tests/UnitTests/ResourceTests/File/templates/relativity/theory/theory.tpl
new file mode 100644
index 00000000..195d46ee
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates/relativity/theory/theory.tpl
@@ -0,0 +1 @@
+theory
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates/sub/relative.tpl b/tests/UnitTests/ResourceTests/File/templates/sub/relative.tpl
new file mode 100644
index 00000000..0185682d
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates/sub/relative.tpl
@@ -0,0 +1 @@
+{include file="../helloworld.tpl"}
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates_2/ambiguous/case1/foobar.tpl b/tests/UnitTests/ResourceTests/File/templates_2/ambiguous/case1/foobar.tpl
new file mode 100644
index 00000000..b6e9ce55
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates_2/ambiguous/case1/foobar.tpl
@@ -0,0 +1 @@
+templates_2
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates_2/dirname.tpl b/tests/UnitTests/ResourceTests/File/templates_2/dirname.tpl
new file mode 100644
index 00000000..b6e9ce55
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates_2/dirname.tpl
@@ -0,0 +1 @@
+templates_2
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates_2/hello.tpl b/tests/UnitTests/ResourceTests/File/templates_2/hello.tpl
new file mode 100644
index 00000000..95d09f2b
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates_2/hello.tpl
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates_2/helloworld.php b/tests/UnitTests/ResourceTests/File/templates_2/helloworld.php
new file mode 100644
index 00000000..6fe5b4ba
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates_2/helloworld.php
@@ -0,0 +1 @@
+php hello world
diff --git a/tests/UnitTests/ResourceTests/File/templates_3/dirname.tpl b/tests/UnitTests/ResourceTests/File/templates_3/dirname.tpl
new file mode 100644
index 00000000..404b4397
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates_3/dirname.tpl
@@ -0,0 +1 @@
+templates_3
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates_3/extendsall.tpl b/tests/UnitTests/ResourceTests/File/templates_3/extendsall.tpl
new file mode 100644
index 00000000..0b79019d
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates_3/extendsall.tpl
@@ -0,0 +1,5 @@
+{block name="alpha"}templates_3{/block}
+{block name="bravo"}
+ {block name="bravo_1"}templates_3{/block}
+ {block name="bravo_2"}templates_3{/block}
+{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates_4/dirname.tpl b/tests/UnitTests/ResourceTests/File/templates_4/dirname.tpl
new file mode 100644
index 00000000..b744ef31
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates_4/dirname.tpl
@@ -0,0 +1 @@
+templates_4
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/File/templates_4/extendsall.tpl b/tests/UnitTests/ResourceTests/File/templates_4/extendsall.tpl
new file mode 100644
index 00000000..93557dca
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/File/templates_4/extendsall.tpl
@@ -0,0 +1,3 @@
+{block name="alpha"}templates_4{/block}
+{block name="bravo"}templates_4{/block}
+{block name="charlie"}templates_4{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/Php/PhpResourceTest.php b/tests/UnitTests/ResourceTests/Php/PhpResourceTest.php
new file mode 100644
index 00000000..d8f6a4db
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Php/PhpResourceTest.php
@@ -0,0 +1,285 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ protected function relative($path)
+ {
+ $path = str_replace(str_replace("\\", "/", dirname(__FILE__)), '.', str_replace("\\", "/", $path));
+
+ return $path;
+ }
+
+ /**
+ * test getTemplateFilepath
+ */
+ public function testGetTemplateFilepath()
+ {
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $this->assertEquals("./templates/phphelloworld.php", str_replace('\\', '/', $tpl->source->filepath));
+ }
+
+ /**
+ * test getTemplateTimestamp
+ */
+ public function testGetTemplateTimestamp()
+ {
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $this->assertTrue(is_integer($tpl->source->timestamp));
+ $this->assertEquals(10, strlen($tpl->source->timestamp));
+ }
+
+ /**
+ * test getTemplateSource
+ *-/
+ * public function testGetTemplateSource()
+ * {
+ * $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ * $this->assertContains('php hello world', $tpl->source->content);
+ * }
+ * /**
+ * test usesCompiler
+ */
+ public function testUsesCompiler()
+ {
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $this->assertTrue($tpl->source->uncompiled);
+ }
+
+ /**
+ * test isEvaluated
+ */
+ public function testIsEvaluated()
+ {
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $this->assertFalse($tpl->source->recompiled);
+ }
+
+ /**
+ * test getCompiledFilepath
+ */
+ public function testGetCompiledFilepath()
+ {
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $this->assertFalse($tpl->compiled->filepath);
+ }
+
+ /**
+ * test getCompiledTimestamp
+ */
+ public function testGetCompiledTimestamp()
+ {
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $this->assertFalse($tpl->compiled->timestamp);
+ }
+
+ /**
+ * test mustCompile
+ */
+ public function testMustCompile()
+ {
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $this->assertFalse($tpl->mustCompile());
+ }
+
+ /**
+ * test getCachedFilepath
+ */
+ public function testGetCachedFilepath()
+ {
+ $this->smarty->setAllowPhpTemplates(true);
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $expected = $this->buildCachedPath($tpl, false, null, null, 'phphelloworld.php', 'php', $this->smarty->getTemplateDir(0), 'file');
+ $this->assertEquals($expected, $tpl->cached->filepath);
+ }
+
+ /**
+ * test create cache file used by the following tests
+ */
+ public function testCreateCacheFile()
+ {
+ // create dummy cache file
+ $this->smarty->setAllowPhpTemplates(true);
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $this->assertContains('php hello world', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test getCachedTimestamp caching enabled
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testGetCachedTimestamp()
+ {
+ $this->smarty->setAllowPhpTemplates(true);
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $this->assertTrue(is_integer($tpl->cached->timestamp));
+ $this->assertEquals(10, strlen($tpl->cached->timestamp));
+ }
+
+ /**
+ * test isCached
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testIsCached()
+ {
+ $this->smarty->setAllowPhpTemplates(true);
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 10000;
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $this->assertTrue($tpl->isCached());
+ }
+
+ /**
+ * test isCached caching disabled
+ */
+ public function testIsCachedCachingDisabled()
+ {
+ $this->smarty->setAllowPhpTemplates(true);
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $this->assertFalse($tpl->isCached());
+ }
+
+ /**
+ * test isCached on touched source
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testIsCachedTouchedSourcePrepare()
+ {
+ $this->smarty->setAllowPhpTemplates(true);
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ sleep(2);
+ touch($tpl->source->filepath);
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testIsCachedTouchedSource()
+ {
+ $this->smarty->setAllowPhpTemplates(true);
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $this->assertFalse($tpl->isCached());
+ }
+
+ /**
+ * test is cache file is written
+ */
+ public function testWriteCachedContent()
+ {
+ $this->smarty->setAllowPhpTemplates(true);
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $this->cleanCacheDir();
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $this->smarty->fetch($tpl);
+ $this->assertTrue(file_exists($tpl->cached->filepath));
+ }
+
+ /**
+ * test getRenderedTemplate
+ */
+ public function testGetRenderedTemplate()
+ {
+ $this->smarty->setAllowPhpTemplates(true);
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $this->assertContains('php hello world', $tpl->fetch());
+ }
+
+ /**
+ * test $smarty->is_cached
+ */
+ public function testSmartyIsCachedPrepare()
+ {
+ // clean up for next tests
+ $this->cleanCacheDir();
+ $this->smarty->setAllowPhpTemplates(true);
+ // prepare files for next test
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $this->smarty->fetch($tpl);
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testSmartyIsCached()
+ {
+ $this->smarty->setAllowPhpTemplates(true);
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $this->assertTrue($this->smarty->isCached($tpl));
+ }
+
+ /**
+ * test $smarty->is_cached caching disabled
+ */
+ public function testSmartyIsCachedCachingDisabled()
+ {
+ $this->smarty->setAllowPhpTemplates(true);
+ $tpl = $this->smarty->createTemplate('php:phphelloworld.php');
+ $this->assertFalse($this->smarty->isCached($tpl));
+ }
+
+ public function testGetTemplateFilepathName()
+ {
+ $this->smarty->addTemplateDir('./templates_2', 'foo');
+ $tpl = $this->smarty->createTemplate('php:[foo]helloworld.php');
+ $this->assertEquals('./templates_2/helloworld.php', $this->relative($tpl->source->filepath));
+ }
+
+ public function testGetCachedFilepathName()
+ {
+ $this->smarty->addTemplateDir('./templates_2', 'foo');
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('php:[foo]helloworld.php');
+ $path = $tpl->cached->filepath;
+ $expected = $this->buildCachedPath($tpl, false, null, null, 'helloworld.php', 'php', $this->smarty->getTemplateDir('foo'), 'file');
+ $this->assertEquals($expected, $path);
+ }
+}
diff --git a/tests/UnitTests/ResourceTests/Php/templates/phphelloworld.php b/tests/UnitTests/ResourceTests/Php/templates/phphelloworld.php
new file mode 100644
index 00000000..6fe5b4ba
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Php/templates/phphelloworld.php
@@ -0,0 +1 @@
+php hello world
diff --git a/tests/UnitTests/ResourceTests/Php/templates_2/helloworld.php b/tests/UnitTests/ResourceTests/Php/templates_2/helloworld.php
new file mode 100644
index 00000000..6fe5b4ba
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Php/templates_2/helloworld.php
@@ -0,0 +1 @@
+php hello world
diff --git a/tests/UnitTests/ResourceTests/Registered/RegisteredResourceTest.php b/tests/UnitTests/ResourceTests/Registered/RegisteredResourceTest.php
new file mode 100644
index 00000000..41b32a76
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Registered/RegisteredResourceTest.php
@@ -0,0 +1,128 @@
+resource
+ *
+ * @package PHPunit
+ * @author Uwe Tews
+ */
+
+/**
+ * class for register->resource tests
+ *
+ * @backupStaticAttributes enabled
+ */
+class RegisteredResourceTest extends PHPUnit_Smarty
+{
+ public function setUp()
+ {
+ $this->setUpSmarty(__DIR__);
+
+ $this->smarty->registerResource("rr", array("rr_get_template",
+ "rr_get_timestamp",
+ "rr_get_secure",
+ "rr_get_trusted"));
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test resource plugin rendering
+ */
+ public function testResourcePlugin()
+ {
+ $this->assertEquals('hello world', $this->smarty->fetch('rr:test'));
+ }
+
+ public function testClearCompiledResourcePlugin()
+ {
+ $this->assertEquals(1, $this->smarty->clearCompiledTemplate('rr:test'));
+ }
+
+ /**
+ * test resource plugin timesatmp
+ */
+ public function testResourcePluginTimestamp()
+ {
+ $tpl = $this->smarty->createTemplate('rr:test');
+ $this->assertTrue(is_integer($tpl->source->timestamp));
+ $this->assertEquals(10, strlen($tpl->source->timestamp));
+ }
+
+ /**
+ * test compile_id change
+ */
+ public function testResourceCompileIdChange()
+ {
+ $this->smarty->registerResource('myresource', array('getSource', 'getTimestamp', 'getSecure', 'getTrusted'));
+ $this->smarty->compile_id = 'a';
+ $this->assertEquals('this is template 1', $this->smarty->fetch('myresource:some'));
+ $this->assertEquals('this is template 1', $this->smarty->fetch('myresource:some'));
+ $this->smarty->compile_id = 'b';
+ $this->assertEquals('this is template 2', $this->smarty->fetch('myresource:some'));
+ $this->assertEquals('this is template 2', $this->smarty->fetch('myresource:some'));
+ }
+}
+
+/**
+ * resource functions
+ */
+function rr_get_template($tpl_name, &$tpl_source, $smarty_obj)
+{
+ // populating $tpl_source
+ $tpl_source = '{$x="hello world"}{$x}';
+
+ return true;
+}
+
+function rr_get_timestamp($tpl_name, &$tpl_timestamp, $smarty_obj)
+{
+ // $tpl_timestamp.
+ $tpl_timestamp = (int) floor(time() / 100) * 100;
+
+ return true;
+}
+
+function rr_get_secure($tpl_name, $smarty_obj)
+{
+ // assume all templates are secure
+ return true;
+}
+
+function rr_get_trusted($tpl_name, $smarty_obj)
+{
+ // not used for templates
+}
+
+// resource functions for compile_id change test
+
+function getSecure($name, $smarty)
+{
+ return true;
+}
+
+function getTrusted($name, $smarty)
+{
+}
+
+function getSource($name, &$source, $smarty)
+{
+ // we update a counter, so that we return a new source for every call
+ static $counter = 0;
+ $counter ++;
+
+ // construct a new source
+ $source = "this is template $counter";
+
+ return true;
+}
+
+function getTimestamp($name, &$timestamp, $smarty)
+{
+ // always pretend the template is brand new
+ $timestamp = time();
+
+ return true;
+}
diff --git a/tests/UnitTests/ResourceTests/ResourcePlugins/PHPunitplugins/resource.db.php b/tests/UnitTests/ResourceTests/ResourcePlugins/PHPunitplugins/resource.db.php
new file mode 100644
index 00000000..3b066db1
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/ResourcePlugins/PHPunitplugins/resource.db.php
@@ -0,0 +1,37 @@
+filepath = 'db2:';
+ $source->uid = sha1($source->resource);
+ $source->timestamp = 0;
+ $source->exists = true;
+ }
+
+ public function getContent(Smarty_Template_Source $source)
+ {
+ return '{$x="hello world"}{$x}';
+ }
+}
diff --git a/tests/UnitTests/ResourceTests/ResourcePlugins/PHPunitplugins/resource.db3.php b/tests/UnitTests/ResourceTests/ResourcePlugins/PHPunitplugins/resource.db3.php
new file mode 100644
index 00000000..0b07233b
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/ResourcePlugins/PHPunitplugins/resource.db3.php
@@ -0,0 +1,32 @@
+filepath = 'db3:';
+ $source->uid = sha1($source->resource);
+ $source->timestamp = 0;
+ $source->exists = true;
+ }
+
+ public function getContent(Smarty_Template_Source $source)
+ {
+ return '{$x="hello world"}{$x}';
+ }
+
+ public function getCompiledFilepath(Smarty_Internal_Template $_template)
+ {
+ return false;
+ }
+}
diff --git a/tests/UnitTests/ResourceTests/ResourcePlugins/PHPunitplugins/resource.db4.php b/tests/UnitTests/ResourceTests/ResourcePlugins/PHPunitplugins/resource.db4.php
new file mode 100644
index 00000000..611d3e43
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/ResourcePlugins/PHPunitplugins/resource.db4.php
@@ -0,0 +1,31 @@
+filepath = 'db4:';
+ $source->uid = sha1($source->resource);
+ $source->timestamp = 0;
+ $source->exists = true;
+ }
+
+ public function getContent(Smarty_Template_Source $source)
+ {
+ if ($source->is_config) {
+ return "foo = 'bar'\n";
+ }
+
+ return '{$x="hello world"}{$x}';
+ }
+}
diff --git a/tests/UnitTests/ResourceTests/ResourcePlugins/ResourcePluginTest.php b/tests/UnitTests/ResourceTests/ResourcePlugins/ResourcePluginTest.php
new file mode 100644
index 00000000..0b91267f
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/ResourcePlugins/ResourcePluginTest.php
@@ -0,0 +1,86 @@
+markTestSkipped('mysql tests are disabled');
+ }
+ if (self::$init) {
+ $this->getConnection();
+ }
+ $this->setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test resource plugin rendering
+ */
+ public function testResourcePlugin()
+ {
+ $this->smarty->addPluginsDir("./PHPunitplugins/");
+ $this->assertEquals('hello world', $this->smarty->fetch('db:test'));
+ }
+
+ /**
+ * test resource plugin rendering
+ */
+ public function testResourcePluginObject()
+ {
+ $this->smarty->addPluginsDir("./PHPunitplugins/");
+ $this->assertEquals('hello world', $this->smarty->fetch('db2:test'));
+ }
+
+ /**
+ * test resource plugin rendering of a registered object
+ */
+ public function testResourcePluginRegisteredInstance()
+ {
+ $this->smarty->addPluginsDir("./PHPunitplugins/");
+ $this->smarty->loadPlugin('Smarty_Resource_Db2');
+ $this->smarty->registerResource('db2a', new Smarty_Resource_Db2('db2a'));
+ $this->assertEquals('hello world', $this->smarty->fetch('db2a:test'));
+ }
+
+
+ /**
+ * test resource plugin non-existent compiled cache of a recompiling resource
+ */
+ public function testResourcePluginRecompiledCompiledFilepath()
+ {
+ $this->smarty->addPluginsDir("./PHPunitplugins/");
+ $tpl = $this->smarty->createTemplate('db2:test.tpl');
+ $expected = realpath('./templates_c/' . sha1('db2:test.tpl') . '.db2.test.tpl.php');
+ $this->assertFalse(!!$expected);
+ $this->assertFalse($tpl->compiled->filepath);
+ }
+
+
+ /**
+ * test resource plugin timestamp
+ */
+ public function testResourcePluginTimestamp()
+ {
+ $this->smarty->addPluginsDir("./PHPunitplugins/");
+ $tpl = $this->smarty->createTemplate('db:test');
+ $this->assertTrue(is_integer($tpl->source->timestamp));
+ $this->assertEquals(10, strlen($tpl->source->timestamp));
+ }
+
+ }
diff --git a/tests/UnitTests/ResourceTests/ResourcePlugins/templates/extendsall.tpl b/tests/UnitTests/ResourceTests/ResourcePlugins/templates/extendsall.tpl
new file mode 100644
index 00000000..988c37e0
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/ResourcePlugins/templates/extendsall.tpl
@@ -0,0 +1,2 @@
+{block name="alpha"}templates{/block}
+{block name="bravo_2"}templates{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/ResourcePlugins/templates/extendsall2.tpl b/tests/UnitTests/ResourceTests/ResourcePlugins/templates/extendsall2.tpl
new file mode 100644
index 00000000..988c37e0
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/ResourcePlugins/templates/extendsall2.tpl
@@ -0,0 +1,2 @@
+{block name="alpha"}templates{/block}
+{block name="bravo_2"}templates{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/ResourcePlugins/templates_2/ambiguous/case1/foobar.tpl b/tests/UnitTests/ResourceTests/ResourcePlugins/templates_2/ambiguous/case1/foobar.tpl
new file mode 100644
index 00000000..b6e9ce55
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/ResourcePlugins/templates_2/ambiguous/case1/foobar.tpl
@@ -0,0 +1 @@
+templates_2
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/ResourcePlugins/templates_2/dirname.tpl b/tests/UnitTests/ResourceTests/ResourcePlugins/templates_2/dirname.tpl
new file mode 100644
index 00000000..b6e9ce55
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/ResourcePlugins/templates_2/dirname.tpl
@@ -0,0 +1 @@
+templates_2
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/ResourcePlugins/templates_2/hello.tpl b/tests/UnitTests/ResourceTests/ResourcePlugins/templates_2/hello.tpl
new file mode 100644
index 00000000..95d09f2b
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/ResourcePlugins/templates_2/hello.tpl
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/ResourcePlugins/templates_2/helloworld.php b/tests/UnitTests/ResourceTests/ResourcePlugins/templates_2/helloworld.php
new file mode 100644
index 00000000..77eb622a
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/ResourcePlugins/templates_2/helloworld.php
@@ -0,0 +1 @@
+php hello world
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/ResourcePlugins/templates_3/dirname.tpl b/tests/UnitTests/ResourceTests/ResourcePlugins/templates_3/dirname.tpl
new file mode 100644
index 00000000..404b4397
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/ResourcePlugins/templates_3/dirname.tpl
@@ -0,0 +1 @@
+templates_3
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/ResourcePlugins/templates_3/extendsall.tpl b/tests/UnitTests/ResourceTests/ResourcePlugins/templates_3/extendsall.tpl
new file mode 100644
index 00000000..0b79019d
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/ResourcePlugins/templates_3/extendsall.tpl
@@ -0,0 +1,5 @@
+{block name="alpha"}templates_3{/block}
+{block name="bravo"}
+ {block name="bravo_1"}templates_3{/block}
+ {block name="bravo_2"}templates_3{/block}
+{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/ResourcePlugins/templates_4/dirname.tpl b/tests/UnitTests/ResourceTests/ResourcePlugins/templates_4/dirname.tpl
new file mode 100644
index 00000000..b744ef31
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/ResourcePlugins/templates_4/dirname.tpl
@@ -0,0 +1 @@
+templates_4
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/ResourcePlugins/templates_4/extendsall.tpl b/tests/UnitTests/ResourceTests/ResourcePlugins/templates_4/extendsall.tpl
new file mode 100644
index 00000000..93557dca
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/ResourcePlugins/templates_4/extendsall.tpl
@@ -0,0 +1,3 @@
+{block name="alpha"}templates_4{/block}
+{block name="bravo"}templates_4{/block}
+{block name="charlie"}templates_4{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/ResourceTests/Stream/StreamResourceTest.php b/tests/UnitTests/ResourceTests/Stream/StreamResourceTest.php
new file mode 100644
index 00000000..6f136403
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/Stream/StreamResourceTest.php
@@ -0,0 +1,277 @@
+setUpSmarty(__DIR__);
+
+ $this->smarty->assign('foo', 'bar');
+ stream_wrapper_register("global", "ResourceStream")
+ or die("Failed to register protocol");
+ $fp = fopen("global://mytest", "r+");
+ fwrite($fp, 'hello world {$foo}');
+ fclose($fp);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ public function tearDown()
+ {
+ parent::tearDown();
+ stream_wrapper_unregister("global");
+ }
+
+ /**
+ * test getTemplateFilepath
+ */
+ public function testGetTemplateFilepath()
+ {
+ $tpl = $this->smarty->createTemplate('global:mytest');
+ $this->assertEquals('global://mytest', $tpl->source->filepath);
+ }
+
+ /**
+ * test getTemplateTimestamp
+ */
+ public function testGetTemplateTimestamp()
+ {
+ $tpl = $this->smarty->createTemplate('global:mytest');
+ $this->assertFalse($tpl->source->timestamp);
+ }
+
+ /**
+ * test getTemplateSource
+ */
+ public function testGetTemplateSource()
+ {
+ $tpl = $this->smarty->createTemplate('global:mytest', null, null, $this->smarty);
+ $this->assertEquals('hello world {$foo}', $tpl->source->content);
+ }
+
+ /**
+ * test usesCompiler
+ */
+ public function testUsesCompiler()
+ {
+ $tpl = $this->smarty->createTemplate('global:mytest');
+ $this->assertFalse($tpl->source->uncompiled);
+ }
+
+ /**
+ * test isEvaluated
+ */
+ public function testIsEvaluated()
+ {
+ $tpl = $this->smarty->createTemplate('global:mytest');
+ $this->assertTrue($tpl->source->recompiled);
+ }
+
+ /**
+ * test mustCompile
+ */
+ public function testMustCompile()
+ {
+ $tpl = $this->smarty->createTemplate('global:mytest');
+ $this->assertTrue($tpl->mustCompile());
+ }
+
+ /**
+ * test getCompiledFilepath
+ */
+ public function testGetCompiledFilepath()
+ {
+ $tpl = $this->smarty->createTemplate('global:mytest');
+ $this->assertFalse($tpl->compiled->filepath);
+ }
+
+ /**
+ * test getCompiledTimestamp
+ */
+ public function testGetCompiledTimestamp()
+ {
+ $tpl = $this->smarty->createTemplate('global:mytest');
+ $this->assertFalse($tpl->compiled->timestamp);
+ }
+
+ /**
+ * test template file exits
+ */
+ public function testTemplateStreamExists1()
+ {
+ $tpl = $this->smarty->createTemplate('global:mytest');
+ $this->assertTrue($tpl->source->exists);
+ }
+
+ public function testTemplateStreamExists2()
+ {
+ $this->assertTrue($this->smarty->templateExists('global:mytest'));
+ }
+
+ /**
+ * test template is not existing
+ */
+ public function testTemplateStreamNotExists1()
+ {
+ $tpl = $this->smarty->createTemplate('global:notthere');
+ $this->assertFalse($tpl->source->exists);
+ }
+
+ public function testTemplateStramNotExists2()
+ {
+ $this->assertFalse($this->smarty->templateExists('global:notthere'));
+ }
+
+ public function testTemplateStramNotExists3()
+ {
+ try {
+ $result = $this->smarty->fetch('global:notthere');
+ }
+ catch (Exception $e) {
+ $this->assertContains('Unable to load template global \'notthere\'', $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for not existing template is missing');
+ }
+
+ /**
+ * test writeCachedContent
+ */
+ public function testWriteCachedContent()
+ {
+ $tpl = $this->smarty->createTemplate('global:mytest');
+ $this->assertFalse($tpl->writeCachedContent('dummy'));
+ }
+
+ /**
+ * test isCached
+ */
+ public function testIsCached()
+ {
+ $tpl = $this->smarty->createTemplate('global:mytest');
+ $this->assertFalse($tpl->isCached());
+ }
+
+ /**
+ * test getRenderedTemplate
+ */
+ public function testGetRenderedTemplate()
+ {
+ $tpl = $this->smarty->createTemplate('global:mytest', null, null, $this->smarty);
+ $this->assertEquals('hello world bar', $tpl->fetch());
+ }
+
+ /**
+ * test that no complied template and cache file was produced
+ */
+ public function testNoFiles()
+ {
+ $this->cleanDir($this->smarty->getCacheDir());
+ $this->cleanDir($this->smarty->getCompileDir());
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 20;
+ $tpl = $this->smarty->createTemplate('global:mytest', null, null, $this->smarty);
+ $this->assertEquals('hello world bar', $this->smarty->fetch($tpl));
+ $this->assertEquals(0, $this->smarty->clearAllCache());
+ $this->assertEquals(0, $this->smarty->clearCompiledTemplate());
+ }
+
+ /**
+ * test $smarty->is_cached
+ */
+ public function testSmartyIsCached()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 20;
+ $tpl = $this->smarty->createTemplate('global:mytest', null, null, $this->smarty);
+ $this->assertEquals('hello world bar', $this->smarty->fetch($tpl));
+ $this->assertFalse($this->smarty->isCached($tpl));
+ }
+}
+
+class ResourceStream
+{
+ private $position;
+ private $varname;
+
+ public function stream_open($path, $mode, $options, &$opened_path)
+ {
+ $url = parse_url($path);
+ $this->varname = $url["host"];
+ $this->position = 0;
+
+ return true;
+ }
+
+ public function stream_read($count)
+ {
+ $p = &$this->position;
+ $ret = substr($GLOBALS[$this->varname], $p, $count);
+ $p += strlen($ret);
+
+ return $ret;
+ }
+
+ public function stream_write($data)
+ {
+ $v = &$GLOBALS[$this->varname];
+ $l = strlen($data);
+ $p = &$this->position;
+ $v = substr($v, 0, $p) . $data . substr($v, $p += $l);
+
+ return $l;
+ }
+
+ public function stream_tell()
+ {
+ return $this->position;
+ }
+
+ public function stream_eof()
+ {
+ if (!isset($GLOBALS[$this->varname])) {
+ return true;
+ }
+
+ return $this->position >= strlen($GLOBALS[$this->varname]);
+ }
+
+ public function stream_seek($offset, $whence)
+ {
+ $l = strlen($GLOBALS[$this->varname]);
+ $p = &$this->position;
+ switch ($whence) {
+ case SEEK_SET:
+ $newPos = $offset;
+ break;
+ case SEEK_CUR:
+ $newPos = $p + $offset;
+ break;
+ case SEEK_END:
+ $newPos = $l + $offset;
+ break;
+ default:
+ return false;
+ }
+ $ret = ($newPos >= 0 && $newPos <= $l);
+ if ($ret) {
+ $p = $newPos;
+ }
+ return $ret;
+ }
+}
diff --git a/tests/UnitTests/ResourceTests/String/StringResourceTest.php b/tests/UnitTests/ResourceTests/String/StringResourceTest.php
new file mode 100644
index 00000000..0db0a255
--- /dev/null
+++ b/tests/UnitTests/ResourceTests/String/StringResourceTest.php
@@ -0,0 +1,191 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ protected function relative($path)
+ {
+ $path = str_replace(dirname(__FILE__), '.', $path);
+ if (DS == "\\") {
+ $path = str_replace("\\", "/", $path);
+ }
+
+ return $path;
+ }
+
+ /**
+ * test template string exits
+ */
+ public function testTemplateStringExists1()
+ {
+ $tpl = $this->smarty->createTemplate('string:{$foo}');
+ $this->assertTrue($tpl->source->exists);
+ }
+
+ public function testTemplateStringExists2()
+ {
+ $this->assertTrue($this->smarty->templateExists('string:{$foo}'));
+ }
+
+ /**
+ * test getTemplateFilepath
+ */
+ public function testGetTemplateFilepath()
+ {
+ $tpl = $this->smarty->createTemplate('string:hello world');
+ $this->assertEquals('2aae6c35c94fcfb415dbe95f408b9ce91ee846ed', $tpl->source->filepath);
+ }
+
+ /**
+ * test getTemplateTimestamp
+ */
+ public function testGetTemplateTimestamp()
+ {
+ $tpl = $this->smarty->createTemplate('string:hello world');
+ $this->assertEquals(0, $tpl->source->timestamp);
+ }
+
+ /**
+ * test getTemplateSource
+ */
+ public function testGetTemplateSource()
+ {
+ $tpl = $this->smarty->createTemplate('string:hello world{$foo}');
+ $this->assertEquals('hello world{$foo}', $tpl->source->content);
+ }
+
+ /**
+ * test usesCompiler
+ */
+ public function testUsesCompiler()
+ {
+ $tpl = $this->smarty->createTemplate('string:hello world');
+ $this->assertFalse($tpl->source->uncompiled);
+ }
+
+ /**
+ * test isEvaluated
+ */
+ public function testIsEvaluated()
+ {
+ $tpl = $this->smarty->createTemplate('string:hello world');
+ $this->assertFalse($tpl->source->recompiled);
+ }
+
+ /**
+ * test mustCompile
+ */
+ public function testMustCompile()
+ {
+ $tpl = $this->smarty->createTemplate('string:hello world');
+ $this->assertTrue($tpl->mustCompile());
+ }
+
+ /**
+ * test getCompiledFilepath
+ */
+ public function testGetCompiledFilepath()
+ {
+ $tpl = $this->smarty->createTemplate('string:hello world');
+ $this->assertEquals($this->buildCompiledPath($tpl, false, false, null, 'hello world', 'string', $this->smarty->getTemplateDir(0)), $tpl->compiled->filepath);
+ }
+
+ /**
+ * test getCompiledTimestamp
+ */
+ public function testGetCompiledTimestamp()
+ {
+ $tpl = $this->smarty->createTemplate('string:hello world');
+ $this->assertFalse($tpl->compiled->timestamp);
+ }
+
+ /**
+ * test empty templates
+ */
+ public function testEmptyTemplate()
+ {
+ $tpl = $this->smarty->createTemplate('string:');
+ $this->assertEquals('', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test getCachedTimestamp
+ */
+ public function testGetCachedTimestamp()
+ {
+ $tpl = $this->smarty->createTemplate('string:hello world');
+ $this->assertFalse($tpl->cached->timestamp);
+ }
+
+ /**
+ * test writeCachedContent
+ */
+ public function testWriteCachedContent()
+ {
+ $tpl = $this->smarty->createTemplate('string:hello world');
+ $this->assertFalse($tpl->writeCachedContent('dummy'));
+ }
+
+ /**
+ * test isCached
+ */
+ public function testIsCached()
+ {
+ $tpl = $this->smarty->createTemplate('string:hello world');
+ $this->assertFalse($tpl->isCached());
+ }
+
+ /**
+ * test getRenderedTemplate
+ */
+ public function testGetRenderedTemplate()
+ {
+ $tpl = $this->smarty->createTemplate('string:hello world');
+ $this->assertEquals('hello world', $tpl->fetch());
+ }
+
+ /**
+ * test $smarty->is_cached
+ */
+ public function testSmartyIsCached()
+ {
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 20;
+ $tpl = $this->smarty->createTemplate('string:hello world');
+ $this->assertEquals('hello world', $this->smarty->fetch($tpl));
+ $this->assertTrue($this->smarty->isCached($tpl));
+ }
+
+ public function testUrlencodeTemplate()
+ {
+ $tpl = $this->smarty->createTemplate('string:urlencode:%7B%22foobar%22%7Cescape%7D');
+ $this->assertEquals('foobar', $tpl->fetch());
+ }
+
+ public function testBase64Template()
+ {
+ $tpl = $this->smarty->createTemplate('string:base64:eyJmb29iYXIifGVzY2FwZX0=');
+ $this->assertEquals('foobar', $tpl->fetch());
+ }
+}
diff --git a/tests/UnitTests/SecurityTests/FunctionTest.php b/tests/UnitTests/SecurityTests/FunctionTest.php
new file mode 100644
index 00000000..a81e655c
--- /dev/null
+++ b/tests/UnitTests/SecurityTests/FunctionTest.php
@@ -0,0 +1,42 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test unknown function error
+ */
+ public function testUnknownFunction()
+ {
+ $this->smarty->enableSecurity();
+ try {
+ $this->smarty->fetch('eval:{unknown()}');
+ }
+ catch (Exception $e) {
+ $this->assertContains("PHP function 'unknown' not allowed by security setting", $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for unknown function has not been raised.');
+ }
+}
diff --git a/tests/UnitTests/SecurityTests/SecurityTest.php b/tests/UnitTests/SecurityTests/SecurityTest.php
new file mode 100644
index 00000000..a040e79c
--- /dev/null
+++ b/tests/UnitTests/SecurityTests/SecurityTest.php
@@ -0,0 +1,383 @@
+setUpSmarty(__DIR__);
+
+ $this->smarty->setForceCompile(true);
+ $this->smarty->enableSecurity();
+ $this->smartyBC->setForceCompile(true);
+ $this->smartyBC->enableSecurity();
+ $this->cleanDir($this->smarty->getCacheDir());
+ $this->cleanDir($this->smarty->getCompileDir());
+ }
+
+ /**
+ * test that security is loaded
+ */
+ public function testSecurityLoaded()
+ {
+ $this->assertTrue(is_object($this->smarty->security_policy));
+ }
+
+ /**
+ * test trusted PHP function
+ */
+ public function testTrustedPHPFunction()
+ {
+ $this->assertEquals("5", $this->smarty->fetch('eval:{assign var=foo value=[1,2,3,4,5]}{count($foo)}'));
+ }
+
+ /**
+ * test not trusted PHP function
+ */
+ public function testNotTrustedPHPFunction()
+ {
+ $this->smarty->security_policy->php_functions = array('null');
+ try {
+ $this->smarty->fetch('eval:{assign var=foo value=[1,2,3,4,5]}{count($foo)}');
+ }
+ catch (Exception $e) {
+ $this->assertContains(htmlentities("PHP function 'count' not allowed by security setting"), $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for not trusted modifier has not been raised.');
+ }
+
+ /**
+ * test not trusted PHP function at disabled security
+ */
+ public function testDisabledTrustedPHPFunction()
+ {
+ $this->smarty->security_policy->php_functions = array('null');
+ $this->smarty->disableSecurity();
+ $this->assertEquals("5", $this->smarty->fetch('eval:{assign var=foo value=[1,2,3,4,5]}{count($foo)}'));
+ }
+
+ /**
+ * test trusted modifier
+ */
+ public function testTrustedModifier()
+ {
+ $this->assertEquals("5", $this->smarty->fetch('eval:{assign var=foo value=[1,2,3,4,5]}{$foo|@count}'));
+ }
+
+ /**
+ * test not trusted modifier
+ */
+ public function testNotTrustedModifier()
+ {
+ $this->smarty->security_policy->php_modifiers = array('null');
+ try {
+ $this->smarty->fetch('eval:{assign var=foo value=[1,2,3,4,5]}{$foo|@count}');
+ }
+ catch (Exception $e) {
+ $this->assertContains(htmlentities("modifier 'count' not allowed by security setting"), $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for not trusted modifier has not been raised.');
+ }
+
+ /**
+ * test not trusted modifier at disabled security
+ */
+ public function testDisabledTrustedModifier()
+ {
+ $this->smarty->security_policy->php_modifiers = array('null');
+ $this->smarty->disableSecurity();
+ $this->assertEquals("5", $this->smarty->fetch('eval:{assign var=foo value=[1,2,3,4,5]}{$foo|@count}'));
+ }
+
+ /**
+ * test allowed tags
+ */
+ public function testAllowedTags1()
+ {
+ $this->smarty->security_policy->allowed_tags = array('counter');
+ $this->assertEquals("1", $this->smarty->fetch('eval:{counter start=1}'));
+ }
+
+ /**
+ * test not allowed tag
+ */
+ public function testNotAllowedTags2()
+ {
+ $this->smarty->security_policy->allowed_tags = array('counter');
+ try {
+ $this->smarty->fetch('eval:{counter}{cycle values="1,2"}');
+ }
+ catch (Exception $e) {
+ $this->assertContains(htmlentities("tag 'cycle' not allowed by security setting"), $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for not allowed tag has not been raised.');
+ }
+
+ /**
+ * test disabled tag
+ */
+ public function testDisabledTags()
+ {
+ $this->smarty->security_policy->disabled_tags = array('cycle');
+ try {
+ $this->smarty->fetch('eval:{counter}{cycle values="1,2"}');
+ }
+ catch (Exception $e) {
+ $this->assertContains(htmlentities("tag 'cycle' disabled by security setting"), $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for disabled tag has not been raised.');
+ }
+
+ /**
+ * test allowed modifier
+ */
+ public function testAllowedModifier1()
+ {
+ error_reporting(E_ALL & ~E_DEPRECATED | E_STRICT);
+ $this->smarty->security_policy->allowed_modifiers = array('capitalize');
+ $this->assertEquals("Hello World", $this->smarty->fetch('eval:{"hello world"|capitalize}'));
+ error_reporting(E_ALL | E_STRICT);
+ }
+
+ public function testAllowedModifier2()
+ {
+ $this->smarty->security_policy->allowed_modifiers = array('upper');
+ $this->assertEquals("HELLO WORLD", $this->smarty->fetch('eval:{"hello world"|upper}'));
+ }
+
+ /**
+ * test not allowed modifier
+ */
+ public function testNotAllowedModifier()
+ {
+ $this->smarty->security_policy->allowed_modifiers = array('upper');
+ try {
+ $this->smarty->fetch('eval:{"hello"|upper}{"world"|lower}');
+ }
+ catch (Exception $e) {
+ $this->assertContains(htmlentities("modifier 'lower' not allowed by security setting"), $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for not allowed tag has not been raised.');
+ }
+
+ /**
+ * test disabled modifier
+ */
+ public function testDisabledModifier()
+ {
+ $this->smarty->security_policy->disabled_modifiers = array('lower');
+ try {
+ $this->smarty->fetch('eval:{"hello"|upper}{"world"|lower}');
+ }
+ catch (Exception $e) {
+ $this->assertContains(htmlentities("modifier 'lower' disabled by security setting"), $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for disabled tag has not been raised.');
+ }
+
+ /**
+ * test Smarty::PHP_QUOTE
+ */
+ public function testSmartyPhpQuote()
+ {
+ $this->smarty->security_policy->php_handling = Smarty::PHP_QUOTE;
+ $this->assertEquals('<?php echo "hello world"; ?>', $this->smarty->fetch('eval:'));
+ }
+
+ public function testSmartyPhpQuoteAsp()
+ {
+ // NOTE: asp_tags cannot be changed by ini_set()
+ if (!ini_get('asp_tags')) {
+ $this->markTestSkipped('asp tags disabled in php.ini');
+ }
+ $this->smarty->security_policy->php_handling = Smarty::PHP_QUOTE;
+ $this->assertEquals('<% echo "hello world"; %>', $this->smarty->fetch('eval:<% echo "hello world"; %>'));
+ }
+
+ /**
+ * test Smarty::PHP_REMOVE
+ */
+ public function testSmartyPhpRemove()
+ {
+ $this->smarty->security_policy->php_handling = Smarty::PHP_REMOVE;
+ $this->assertEquals(' echo "hello world"; ', $this->smarty->fetch('eval:'));
+ }
+
+ public function testSmartyPhpRemoveAsp()
+ {
+ // NOTE: asp_tags cannot be changed by ini_set()
+ if (!ini_get('asp_tags')) {
+ $this->markTestSkipped('asp tags disabled in php.ini');
+ }
+ $this->smarty->security_policy->php_handling = Smarty::PHP_REMOVE;
+ $this->assertEquals(' echo "hello world"; ', $this->smarty->fetch('eval:<% echo "hello world"; %>'));
+ }
+
+ /**
+ * test Smarty::PHP_ALLOW
+ */
+ public function testSmartyPhpAllow()
+ {
+ $this->smartyBC->security_policy->php_handling = Smarty::PHP_ALLOW;
+ $this->assertEquals('hello world', $this->smartyBC->fetch('eval:'));
+ }
+
+ public function testSmartyPhpAllowAsp()
+ {
+ // NOTE: asp_tags cannot be changed by ini_set()
+ if (!ini_get('asp_tags')) {
+ $this->markTestSkipped('asp tags disabled in php.ini');
+ }
+ $this->smartyBC->security_policy->php_handling = Smarty::PHP_ALLOW;
+ $this->assertEquals('hello world', $this->smartyBC->fetch('eval:<% echo "hello world"; %>'));
+ }
+
+ /**
+ * test standard directory
+ */
+ public function testStandardDirectory()
+ {
+ $content = $this->smarty->fetch('eval:{include file="helloworld.tpl"}');
+ $this->assertEquals("hello world", $content);
+ }
+
+ /**
+ * test trusted directory
+ */
+ public function testTrustedDirectory()
+ {
+ $this->smarty->security_policy->secure_dir = array('.' . DIRECTORY_SEPARATOR . 'templates_2' . DIRECTORY_SEPARATOR);
+ $this->assertEquals("hello world", $this->smarty->fetch('eval:{include file="templates_2/hello.tpl"}'));
+ }
+
+ /**
+ * test not trusted directory
+ */
+ public function testNotTrustedDirectory()
+ {
+ $this->smarty->security_policy->secure_dir = array(str_replace('\\', '/', __DIR__ . '/templates_3/'));
+ try {
+ $this->smarty->fetch('eval:{include file="templates_2/hello.tpl"}');
+ }
+ catch (Exception $e) {
+ $this->assertContains(str_replace('\\', '/', __DIR__ . "/templates_2/hello.tpl' not allowed by security setting"), str_replace('\\', '/', $e->getMessage()));
+
+ return;
+ }
+ $this->fail('Exception for not trusted directory has not been raised.');
+ }
+
+ /**
+ * test disabled security for not trusted dir
+ */
+ public function testDisabledTrustedDirectory()
+ {
+ $this->smarty->disableSecurity();
+ $this->assertEquals("hello world", $this->smarty->fetch('eval:{include file="templates_2/hello.tpl"}'));
+ }
+
+ /**
+ * test trusted static class
+ */
+ public function testTrustedStaticClass()
+ {
+ $this->smarty->security_policy->static_classes = array('mysecuritystaticclass');
+ $tpl = $this->smarty->createTemplate('eval:{mysecuritystaticclass::square(5)}');
+ $this->assertEquals('25', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test not trusted PHP function
+ */
+ public function testNotTrustedStaticClass()
+ {
+ $this->smarty->security_policy->static_classes = array('null');
+ try {
+ $this->smarty->fetch('eval:{mysecuritystaticclass::square(5)}');
+ }
+ catch (Exception $e) {
+ $this->assertContains(htmlentities("access to static class 'mysecuritystaticclass' not allowed by security setting"), $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for not trusted static class has not been raised.');
+ }
+
+ public function testChangedTrustedDirectory()
+ {
+ $this->smarty->security_policy->secure_dir = array(
+ '.' . DS . 'templates_2' . DS,
+ );
+ $this->assertEquals("hello world", $this->smarty->fetch('eval:{include file="templates_2/hello.tpl"}'));
+
+ $this->smarty->security_policy->secure_dir = array(
+ '.' . DS . 'templates_2' . DS,
+ '.' . DS . 'templates_3' . DS,
+ );
+ $this->assertEquals("templates_3", $this->smarty->fetch('eval:{include file="templates_3/dirname.tpl"}'));
+ }
+
+ public function testTrustedUri()
+ {
+ $this->smarty->security_policy->trusted_uri = array(
+ '#^http://.+smarty\.net$#i'
+ );
+
+ try {
+ $this->smarty->fetch('eval:{fetch file="http://www.smarty.net/foo.bar"}');
+ }
+ catch (SmartyException $e) {
+ $this->assertNotContains(htmlentities("not allowed by security setting"), $e->getMessage());
+ }
+
+ try {
+ $this->smarty->fetch('eval:{fetch file="https://www.smarty.net/foo.bar"}');
+ $this->fail("Exception for unknown resource not thrown (protocol)");
+ }
+ catch (SmartyException $e) {
+ $this->assertContains(htmlentities("not allowed by security setting"), $e->getMessage());
+ }
+
+ try {
+ $this->smarty->fetch('eval:{fetch file="http://www.smarty.com/foo.bar"}');
+ $this->fail("Exception for unknown resource not thrown (domain)");
+ }
+ catch (SmartyException $e) {
+ $this->assertContains(htmlentities("not allowed by security setting"), $e->getMessage());
+ }
+ }
+}
+
+class mysecuritystaticclass
+{
+ const STATIC_CONSTANT_VALUE = 3;
+ static $static_var = 5;
+
+ static function square($i)
+ {
+ return $i * $i;
+ }
+}
diff --git a/tests/UnitTests/SecurityTests/templates/helloworld.tpl b/tests/UnitTests/SecurityTests/templates/helloworld.tpl
new file mode 100644
index 00000000..95d09f2b
--- /dev/null
+++ b/tests/UnitTests/SecurityTests/templates/helloworld.tpl
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/tests/UnitTests/SecurityTests/templates_2/hello.tpl b/tests/UnitTests/SecurityTests/templates_2/hello.tpl
new file mode 100644
index 00000000..95d09f2b
--- /dev/null
+++ b/tests/UnitTests/SecurityTests/templates_2/hello.tpl
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/tests/UnitTests/SecurityTests/templates_3/dirname.tpl b/tests/UnitTests/SecurityTests/templates_3/dirname.tpl
new file mode 100644
index 00000000..404b4397
--- /dev/null
+++ b/tests/UnitTests/SecurityTests/templates_3/dirname.tpl
@@ -0,0 +1 @@
+templates_3
\ No newline at end of file
diff --git a/tests/UnitTests/SmartyMethodsTests/Append/AppendTest.php b/tests/UnitTests/SmartyMethodsTests/Append/AppendTest.php
new file mode 100644
index 00000000..22746c33
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/Append/AppendTest.php
@@ -0,0 +1,84 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test append
+ */
+ public function testAppend()
+ {
+ $this->smarty->assign('foo', 'bar');
+ $this->smarty->append('foo', 'bar2');
+ $this->assertEquals('bar bar2', $this->smarty->fetch('eval:{$foo[0]} {$foo[1]}'));
+ }
+
+ /**
+ * test append to unassigned variable
+ */
+ public function testAppendUnassigned()
+ {
+ $this->smarty->append('foo', 'bar');
+ $this->assertEquals('bar', $this->smarty->fetch('eval:{$foo[0]}'));
+ }
+
+ /**
+ * test append merge
+ */
+ public function testAppendMerge()
+ {
+ $this->smarty->assign('foo', array('a' => 'a', 'b' => 'b', 'c' => 'c'));
+ $this->smarty->append('foo', array('b' => 'd'), true);
+ $this->assertEquals('a d c', $this->smarty->fetch('eval:{$foo["a"]} {$foo["b"]} {$foo["c"]}'));
+ }
+
+ /**
+ * test append array merge
+ */
+ public function testAppendArrayMerge()
+ {
+ $this->smarty->assign('foo', array('b' => 'd'));
+ $this->smarty->append('foo', array('a' => 'a', 'b' => 'b', 'c' => 'c'), true);
+ $this->assertEquals('a b c', $this->smarty->fetch('eval:{$foo["a"]} {$foo["b"]} {$foo["c"]}'));
+ }
+
+ /**
+ * test array append
+ */
+ public function testArrayAppend()
+ {
+ $this->smarty->assign('foo', 'foo');
+ $this->smarty->append(array('bar' => 'bar2', 'foo' => 'foo2'));
+ $this->assertEquals('foo foo2 bar2', $this->smarty->fetch('eval:{$foo[0]} {$foo[1]} {$bar[0]}'));
+ }
+
+ /**
+ * test array append array merge
+ */
+ public function testArrayAppendArrayMerge()
+ {
+ $this->smarty->assign('foo', array('b' => 'd'));
+ $this->smarty->append(array('bar' => 'bar', 'foo' => array('a' => 'a', 'b' => 'b', 'c' => 'c')), null, true);
+ $this->assertEquals('a b c bar', $this->smarty->fetch('eval:{$foo["a"]} {$foo["b"]} {$foo["c"]} {$bar[0]}'));
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/AppendByRef/AppendByRefBCTest.php b/tests/UnitTests/SmartyMethodsTests/AppendByRef/AppendByRefBCTest.php
new file mode 100644
index 00000000..27f809fa
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/AppendByRef/AppendByRefBCTest.php
@@ -0,0 +1,46 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ public function testSmarty2AppendByRef()
+ {
+ $bar = 'bar';
+ $bar2 = 'bar2';
+ $this->smartyBC->append_by_ref('foo', $bar);
+ $this->smartyBC->append_by_ref('foo', $bar2);
+ $bar = 'newbar';
+ $bar2 = 'newbar2';
+ $this->assertEquals('newbar newbar2', $this->smartyBC->fetch('eval:{$foo[0]} {$foo[1]}'));
+ }
+
+ public function testSmarty2AppendByRefUnassigned()
+ {
+ $bar2 = 'bar2';
+ $this->smartyBC->append_by_ref('foo', $bar2);
+ $bar2 = 'newbar2';
+ $this->assertEquals('newbar2', $this->smartyBC->fetch('eval:{$foo[0]}'));
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/AppendByRef/AppendByRefTest.php b/tests/UnitTests/SmartyMethodsTests/AppendByRef/AppendByRefTest.php
new file mode 100644
index 00000000..01e5073c
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/AppendByRef/AppendByRefTest.php
@@ -0,0 +1,62 @@
+setUpSmarty(__DIR__);
+ }
+
+ /**
+ * test appendByRef
+ */
+ public function testAppendByRef()
+ {
+ $bar = 'bar';
+ $bar2 = 'bar2';
+ $this->smarty->appendByRef('foo', $bar);
+ $this->smarty->appendByRef('foo', $bar2);
+ $bar = 'newbar';
+ $bar2 = 'newbar2';
+ $this->assertEquals('newbar newbar2', $this->smarty->fetch('eval:{$foo[0]} {$foo[1]}'));
+ }
+
+ /**
+ * test appendByRef to unassigned variable
+ */
+ public function testAppendByRefUnassigned()
+ {
+ $bar2 = 'bar2';
+ $this->smarty->appendByRef('foo', $bar2);
+ $bar2 = 'newbar2';
+ $this->assertEquals('newbar2', $this->smarty->fetch('eval:{$foo[0]}'));
+ }
+
+ /**
+ * test appendByRef merge
+ *
+ * @todo fix testAppendByRefMerge
+ */
+ public function testAppendByRefMerge()
+ {
+ $foo = array('a' => 'a', 'b' => 'b', 'c' => 'c');
+ $bar = array('b' => 'd');
+ $this->smarty->assignByRef('foo', $foo);
+ $this->smarty->appendByRef('foo', $bar, true);
+ $this->assertEquals('a d c', $this->smarty->fetch('eval:{$foo["a"]} {$foo["b"]} {$foo["c"]}'));
+ $bar = array('b' => 'newd');
+ $this->smarty->appendByRef('foo', $bar, true);
+ $this->assertEquals('a newd c', $this->smarty->fetch('eval:{$foo["a"]} {$foo["b"]} {$foo["c"]}'));
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/Assign/AssignTest.php b/tests/UnitTests/SmartyMethodsTests/Assign/AssignTest.php
new file mode 100644
index 00000000..8a03fad1
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/Assign/AssignTest.php
@@ -0,0 +1,43 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test simple assign
+ */
+ public function testSimpleAssign()
+ {
+ $this->smarty->assign('foo', 'bar');
+ $this->assertEquals('bar', $this->smarty->fetch('eval:{$foo}'));
+ }
+
+ /**
+ * test assign array of variables
+ */
+ public function testArrayAssign()
+ {
+ $this->smarty->assign(array('foo' => 'bar', 'foo2' => 'bar2'));
+ $this->assertEquals('bar bar2', $this->smarty->fetch('eval:{$foo} {$foo2}'));
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/AssignByRef/AssignByRefBCTest.php b/tests/UnitTests/SmartyMethodsTests/AssignByRef/AssignByRefBCTest.php
new file mode 100644
index 00000000..587ec7e7
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/AssignByRef/AssignByRefBCTest.php
@@ -0,0 +1,49 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test Smarty2 assign_By_Ref
+ */
+ public function testSmarty2AssignByRef()
+ {
+ $bar = 'bar';
+ $this->smartyBC->assign_by_ref('foo', $bar);
+ $bar = 'newbar';
+ $this->assertEquals('newbar', $this->smartyBC->fetch('eval:{$foo}'));
+ }
+
+ /**
+ * test Smarty2's behaviour of assign_By_Ref (Issue 88)
+ */
+ public function testSmarty2AssignByRef2()
+ {
+ $bar = 'bar';
+ $this->smartyBC->assign_by_ref('foo', $bar);
+ $this->smartyBC->fetch('eval:{$foo = "newbar"}');
+ $this->assertEquals('newbar', $bar);
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/AssignByRef/AssignByRefTest.php b/tests/UnitTests/SmartyMethodsTests/AssignByRef/AssignByRefTest.php
new file mode 100644
index 00000000..960d00a5
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/AssignByRef/AssignByRefTest.php
@@ -0,0 +1,31 @@
+setUpSmarty(__DIR__);
+ }
+
+ /**
+ * test simple assignByRef
+ */
+ public function testSimpleAssignByRef()
+ {
+ $bar = 'bar';
+ $this->smarty->assignByRef('foo', $bar);
+ $bar = 'newbar';
+ $this->assertEquals('newbar', $this->smarty->fetch('eval:{$foo}'));
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/AssignGlobal/AssignGlobalTest.php b/tests/UnitTests/SmartyMethodsTests/AssignGlobal/AssignGlobalTest.php
new file mode 100644
index 00000000..de281332
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/AssignGlobal/AssignGlobalTest.php
@@ -0,0 +1,68 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test assignGlobal and getGlobal
+ */
+ public function testAssignGlobalGetGlobal()
+ {
+ $this->smarty->assignGlobal('foo', 'bar');
+ $this->assertEquals('bar', $this->smarty->getGlobal('foo'));
+ }
+
+ /**
+ * test assignGlobal and getGlobal on arrays
+ */
+ public function testAssignGlobalGetGlobalArray()
+ {
+ $this->smarty->assignGlobal('foo', array('foo' => 'bar', 'foo2' => 'bar2'));
+ $a1 = array('foo' => array('foo' => 'bar', 'foo2' => 'bar2'));
+ $a2 = $this->smarty->getGlobal();
+ unset($a2['SCRIPT_NAME']);
+ $this->assertTrue($a1 === $a2);
+ }
+
+ /**
+ * test assignGlobal tag
+ */
+ public function testAssignGlobalTag()
+ {
+ $this->smarty->assignGlobal('foo', 'bar');
+ $this->assertEquals('bar', $this->smarty->fetch('eval:{$foo}'));
+ $this->assertEquals('buh', $this->smarty->fetch('eval:{assign var=foo value=buh scope=global}{$foo}'));
+ $this->assertEquals('buh', $this->smarty->fetch('eval:{$foo}'));
+ $this->assertEquals('buh', $this->smarty->getGlobal('foo'));
+ }
+
+ /**
+ * test global var array element tag
+ */
+ public function testGlobalVarArrayTag()
+ {
+ $this->smarty->assignGlobal('foo', array('foo' => 'bar', 'foo2' => 'bar2'));
+ $this->assertEquals('bar2', $this->smarty->fetch('eval:{$foo.foo2}'));
+ $this->assertEquals('bar', $this->smarty->fetch('eval:{$foo.foo}'));
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/ClearAllAssign/ClearAllAssignBCTest.php b/tests/UnitTests/SmartyMethodsTests/ClearAllAssign/ClearAllAssignBCTest.php
new file mode 100644
index 00000000..135f1127
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/ClearAllAssign/ClearAllAssignBCTest.php
@@ -0,0 +1,38 @@
+setUpSmarty(__DIR__);
+
+ $this->smartyBC->assign('foo', 'foo');
+ $this->_dataBC = new Smarty_Data($this->smartyBC);
+ $this->_dataBC->assign('bar', 'bar');
+ $this->_tplBC = $this->smartyBC->createTemplate('eval:{$foo}{$bar}{$blar}', null, null, $this->_dataBC);
+ $this->_tplBC->assign('blar', 'blar');
+ }
+
+ public function testSmarty2ClearAllAssignInSmarty()
+ {
+ error_reporting((error_reporting() & ~(E_NOTICE | E_USER_NOTICE)));
+ $this->smartyBC->clear_all_assign();
+ $this->assertEquals('barblar', $this->smartyBC->fetch($this->_tplBC));
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/ClearAllAssign/ClearAllAssignTest.php b/tests/UnitTests/SmartyMethodsTests/ClearAllAssign/ClearAllAssignTest.php
new file mode 100644
index 00000000..2e1b5406
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/ClearAllAssign/ClearAllAssignTest.php
@@ -0,0 +1,67 @@
+setUpSmarty(__DIR__);
+
+ $this->smarty->assign('foo', 'foo');
+ $this->_data = new Smarty_Data($this->smarty);
+ $this->_data->assign('bar', 'bar');
+ $this->_tpl = $this->smarty->createTemplate('eval:{$foo}{$bar}{$blar}', null, null, $this->_data);
+ $this->_tpl->assign('blar', 'blar');
+ }
+
+ /**
+ * test all variables accessable
+ */
+ public function testAllVariablesAccessable()
+ {
+ $this->assertEquals('foobarblar', $this->smarty->fetch($this->_tpl));
+ }
+
+ /**
+ * test clear all assign in template
+ */
+ public function testClearAllAssignInTemplate()
+ {
+ error_reporting((error_reporting() & ~(E_NOTICE | E_USER_NOTICE)));
+ $this->_tpl->clearAllAssign();
+ $this->assertEquals('foobar', $this->smarty->fetch($this->_tpl));
+ }
+
+ /**
+ * test clear all assign in data
+ */
+ public function testClearAllAssignInData()
+ {
+ error_reporting((error_reporting() & ~(E_NOTICE | E_USER_NOTICE)));
+ $this->_data->clearAllAssign();
+ $this->assertEquals('fooblar', $this->smarty->fetch($this->_tpl));
+ }
+
+ /**
+ * test clear all assign in Smarty object
+ */
+ public function testClearAllAssignInSmarty()
+ {
+ error_reporting((error_reporting() & ~(E_NOTICE | E_USER_NOTICE)));
+ $this->smarty->clearAllAssign();
+ $this->assertEquals('barblar', $this->smarty->fetch($this->_tpl));
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/ClearAssign/ClearAssignBCTest.php b/tests/UnitTests/SmartyMethodsTests/ClearAssign/ClearAssignBCTest.php
new file mode 100644
index 00000000..3d7a5209
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/ClearAssign/ClearAssignBCTest.php
@@ -0,0 +1,45 @@
+setUpSmarty(__DIR__);
+
+ $this->smartyBC->assign('foo', 'foo');
+ $this->smartyBC->assign('bar', 'bar');
+ $this->smartyBC->assign('blar', 'blar');
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ public function testSmarty2ClearAssign()
+ {
+ $this->smartyBC->setErrorReporting(error_reporting() & ~(E_NOTICE | E_USER_NOTICE));
+ $this->smartyBC->clear_assign('blar');
+ $this->assertEquals('foobar', $this->smartyBC->fetch('eval:{$foo}{$bar}{$blar}'));
+ }
+
+ public function testSmarty2ArrayClearAssign()
+ {
+ $this->smartyBC->setErrorReporting(error_reporting() & ~(E_NOTICE | E_USER_NOTICE));
+ $this->smartyBC->clear_assign(array('blar', 'foo'));
+ $this->assertEquals('bar', $this->smartyBC->fetch('eval:{$foo}{$bar}{$blar}'));
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/ClearAssign/ClearAssignTest.php b/tests/UnitTests/SmartyMethodsTests/ClearAssign/ClearAssignTest.php
new file mode 100644
index 00000000..018e9c6d
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/ClearAssign/ClearAssignTest.php
@@ -0,0 +1,51 @@
+setUpSmarty(__DIR__);
+ $this->smarty->assign('foo', 'foo');
+ $this->smarty->assign('bar', 'bar');
+ $this->smarty->assign('blar', 'blar');
+ }
+
+ /**
+ * test all variables accessable
+ */
+ public function testAllVariablesAccessable()
+ {
+ $this->assertEquals('foobarblar', $this->smarty->fetch('eval:{$foo}{$bar}{$blar}'));
+ }
+
+ /**
+ * test simple clear assign
+ */
+ public function testClearAssign()
+ {
+ $this->smarty->setErrorReporting(error_reporting() & ~(E_NOTICE | E_USER_NOTICE));
+ $this->smarty->clearAssign('blar');
+ $this->assertEquals('foobar', $this->smarty->fetch('eval:{$foo}{$bar}{$blar}'));
+ }
+
+ /**
+ * test clear assign array of variables
+ */
+ public function testArrayClearAssign()
+ {
+ $this->smarty->setErrorReporting(error_reporting() & ~(E_NOTICE | E_USER_NOTICE));
+ $this->smarty->clearAssign(array('blar', 'foo'));
+ $this->assertEquals('bar', $this->smarty->fetch('eval:{$foo}{$bar}{$blar}'));
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/ClearCompiledTest.php b/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/ClearCompiledTest.php
new file mode 100644
index 00000000..cc213a6e
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/ClearCompiledTest.php
@@ -0,0 +1,470 @@
+setUpSmarty(__DIR__);
+ $this->smarty->addTemplateDir('./templates_2/');
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ // helpers
+ /**
+ * clear $smarty->compile_dir
+ *
+ * @return void
+ */
+ protected function clearFiles()
+ {
+ $directory = realpath($this->smarty->getCompileDir());
+ if (!$directory) {
+ return;
+ }
+
+ $di = new RecursiveDirectoryIterator($directory);
+ // $it = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST | FilesystemIterator::SKIP_DOTS);
+ $it = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
+ foreach ($it as $file) {
+ $_file = $file->__toString();
+
+ if (preg_match("#[\\\\/]\.#", $_file)) {
+ continue;
+ }
+
+ if ($file->isDir()) {
+ rmdir($_file);
+ } else {
+ unlink($_file);
+ }
+ }
+ }
+
+ /**
+ * list of compiled files
+ *
+ * @var array
+ */
+ protected $_files = array();
+
+ /**
+ * generate compiled files
+ *
+ * @uses $_files to store references
+ * @return array list of files array( id => path )
+ */
+ protected function makeFiles()
+ {
+ $this->_files = array();
+ $directory_length = strlen($this->smarty->getCompileDir());
+ $templates = array(
+ 'helloworld.tpl' => array(null, 'compile1', 'compile2'),
+ 'helloworld2.tpl' => array(null, 'compile1', 'compile2'),
+ 'ambiguous/case1/foobar.tpl' => array(null, 'compile1', 'compile2'),
+ '[1]ambiguous/case1/foobar.tpl' => array(null, 'compile1', 'compile2'),
+ );
+
+ foreach ($templates as $template => $compile_ids) {
+ foreach ($compile_ids as $compile_id) {
+ $tpl = $this->smarty->createTemplate($template, null, $compile_id);
+ $tpl->fetch();
+ $this->_files[$template . '#' . $compile_id] = substr($tpl->compiled->filepath, $directory_length);
+ }
+ }
+ // TODO
+ //Smarty::$_resource_cache = array();
+ $this->smarty->template_objects = array();
+
+ return $this->_files;
+ }
+
+ /**
+ * Transform $id to $path
+ *
+ * @param array $keys IDs like "template#compile_id"
+ *
+ * @return array list of (sorted) compiled file paths
+ */
+ protected function expectFiles($keys)
+ {
+ $files = array();
+ foreach ($keys as $key) {
+ if (isset($this->_files[$key])) {
+ $files[] = $this->_files[$key];
+ }
+ }
+ sort($files);
+
+ return $files;
+ }
+
+ /**
+ * update mtime of compiled files
+ *
+ * @param array $keys IDs like "template#compile_id"
+ * @param string $offset time offset added to time()
+ *
+ * @return void
+ */
+ protected function touchFiles($keys, $offset = 0)
+ {
+ $base = $this->smarty->getCompileDir();
+ $time = time();
+ foreach ($keys as $key) {
+ if (isset($this->_files[$key])) {
+ file_put_contents($base . $this->_files[$key], ' #');
+ touch($base . $this->_files[$key], $time + $offset);
+ }
+ }
+ clearstatcache();
+ }
+
+ /**
+ * find all compiled files
+ *
+ * @return array list of (sorted) compiled file paths
+ */
+ protected function getFiles()
+ {
+ $directory = realpath($this->smarty->getCompileDir());
+ if (!$directory) {
+ return array();
+ }
+
+ $directory_length = strlen($directory);
+ $files = array();
+
+ $di = new RecursiveDirectoryIterator($directory);
+ $it = new RecursiveIteratorIterator($di);
+ foreach ($it as $file) {
+ $_file = $file->__toString();
+ // skip anything with a /. in it.
+ if (preg_match("#[\\\\/]\.#", $_file) || !$file->isFile()) {
+ continue;
+ }
+
+ $files[] = substr($file->__toString(), $directory_length + 1);
+ }
+ sort($files);
+
+ return $files;
+ }
+
+ // Smarty::clearCompiledTemplate(null, null, null)
+ public function testClearAll()
+ {
+ $this->runClearAll(false);
+ }
+
+ public function testSubsClearAll()
+ {
+ $this->runClearAll(true);
+ }
+
+ public function runClearAll($useSubDirs)
+ {
+ $this->smarty->setUseSubDirs($useSubDirs);
+ $this->clearFiles();
+ $this->makeFiles();
+
+ $expected = array();
+ $this->assertEquals(12, $this->smarty->clearCompiledTemplate());
+
+ $this->assertEquals($this->expectFiles($expected), $this->getFiles());
+ $this->clearFiles();
+ }
+
+ // Smarty::clearCompiledTemplate($template, null, null)
+ public function testClearTemplate()
+ {
+ $this->runClearTemplate(false);
+ }
+
+ public function testSubsClearTemplate()
+ {
+ $this->runClearTemplate(true);
+ }
+
+ public function testClearOtherTemplate()
+ {
+ $this->runClearOtherTemplate(false);
+ }
+
+ public function testSubsClearOtherTemplate()
+ {
+ $this->runClearOtherTemplate(true);
+ }
+
+ public function runClearTemplate($useSubDirs)
+ {
+ $this->smarty->setUseSubDirs($useSubDirs);
+ $this->clearFiles();
+ $this->makeFiles();
+
+ $expected = array(
+ 'helloworld2.tpl#', 'helloworld2.tpl#compile1', 'helloworld2.tpl#compile2',
+ 'ambiguous/case1/foobar.tpl#', 'ambiguous/case1/foobar.tpl#compile1', 'ambiguous/case1/foobar.tpl#compile2',
+ '[1]ambiguous/case1/foobar.tpl#', '[1]ambiguous/case1/foobar.tpl#compile1', '[1]ambiguous/case1/foobar.tpl#compile2',
+ );
+ $this->assertEquals(3, $this->smarty->clearCompiledTemplate('helloworld.tpl'));
+
+ $this->assertEquals($this->expectFiles($expected), $this->getFiles());
+ $this->clearFiles();
+ }
+
+ public function runClearOtherTemplate($useSubDirs)
+ {
+ $this->smarty->setUseSubDirs($useSubDirs);
+ $this->clearFiles();
+ $this->makeFiles();
+
+ $expected = array_keys($this->_files);
+ $this->assertEquals(0, $this->smarty->clearCompiledTemplate('foobar.tpl'));
+
+ $this->assertEquals($this->expectFiles($expected), $this->getFiles());
+ $this->clearFiles();
+ }
+
+ // Smarty::clearCompiledTemplate(null, $cache_id, null)
+ public function testClearCompileid()
+ {
+ $this->runClearCompileid(false);
+ }
+
+ public function testSubsClearCompileid()
+ {
+ $this->runClearCompileid(true);
+ }
+
+ public function testClearOtherCompileid()
+ {
+ $this->runClearOtherCompileid(false);
+ }
+
+ public function testSubsClearOtherCompileid()
+ {
+ $this->runClearOtherCompileid(true);
+ }
+
+ public function runClearCompileid($useSubDirs)
+ {
+ $this->smarty->setUseSubDirs($useSubDirs);
+ $this->clearFiles();
+ $this->makeFiles();
+
+ $expected = array(
+ 'helloworld.tpl#', 'helloworld.tpl#compile2',
+ 'helloworld2.tpl#', 'helloworld2.tpl#compile2',
+ 'ambiguous/case1/foobar.tpl#', 'ambiguous/case1/foobar.tpl#compile2',
+ '[1]ambiguous/case1/foobar.tpl#', '[1]ambiguous/case1/foobar.tpl#compile2',
+ );
+ $count = $this->smarty->clearCompiledTemplate(null, 'compile1');
+ $this->assertEquals(4, $count);
+
+ $this->assertEquals($this->expectFiles($expected), $this->getFiles());
+ $this->clearFiles();
+ }
+
+ public function runClearOtherCompileid($useSubDirs)
+ {
+ $this->smarty->setUseSubDirs($useSubDirs);
+ $this->clearFiles();
+ $this->makeFiles();
+
+ $expected = array_keys($this->_files);
+ $this->assertEquals(0, $this->smarty->clearCompiledTemplate(null, 'other'));
+
+ $this->assertEquals($this->expectFiles($expected), $this->getFiles());
+ $this->clearFiles();
+ }
+
+ // Smarty::clearCompiledTemplate(null, null, $expired)
+ public function testClearExpired()
+ {
+ $this->runClearExpired(false);
+ }
+
+ public function testSubsClearExpired()
+ {
+ $this->runClearExpired(true);
+ }
+
+ public function runClearExpired($useSubDirs)
+ {
+ $this->smarty->setUseSubDirs($useSubDirs);
+ $this->clearFiles();
+ $this->makeFiles();
+
+ $expected = array('helloworld.tpl#', 'helloworld2.tpl#');
+ $this->touchFiles(array_diff(array_keys($this->_files), $expected), - 1000);
+ $this->assertEquals(10, $this->smarty->clearCompiledTemplate(null, null, 500));
+
+ $this->assertEquals($this->expectFiles($expected), $this->getFiles());
+ $this->clearFiles();
+ }
+
+ // Smarty::clearCompiledTemplate($template, null, $expired)
+ public function testClearTemplateExpired()
+ {
+ $this->runClearTemplateExpired(false);
+ }
+
+ public function testSubsClearTemplateExpired()
+ {
+ $this->runClearTemplateExpired(true);
+ }
+
+ public function runClearTemplateExpired($useSubDirs)
+ {
+ $this->smarty->setUseSubDirs($useSubDirs);
+ $this->clearFiles();
+ $this->makeFiles();
+
+ $expected = array(
+ 'helloworld.tpl#', 'helloworld.tpl#compile2',
+ 'helloworld2.tpl#', 'helloworld2.tpl#compile1', 'helloworld2.tpl#compile2',
+ 'ambiguous/case1/foobar.tpl#', 'ambiguous/case1/foobar.tpl#compile1', 'ambiguous/case1/foobar.tpl#compile2',
+ '[1]ambiguous/case1/foobar.tpl#', '[1]ambiguous/case1/foobar.tpl#compile1', '[1]ambiguous/case1/foobar.tpl#compile2',
+ );
+ $this->touchFiles(array('helloworld.tpl#compile1'), - 1000);
+ $this->assertEquals(1, $this->smarty->clearCompiledTemplate("helloworld.tpl", null, 500));
+
+ $this->assertEquals($this->expectFiles($expected), $this->getFiles());
+ $this->clearFiles();
+ }
+
+ // Smarty::clearCompiledTemplate($template, $cache_id, $expired)
+ public function testClearTemplateCacheidExpired()
+ {
+ $this->runClearTemplateCacheidExpired(false);
+ }
+
+ public function testSubsClearTemplateCacheidExpired()
+ {
+ $this->runClearTemplateCacheidExpired(true);
+ }
+
+ public function runClearTemplateCacheidExpired($useSubDirs)
+ {
+ $this->smarty->setUseSubDirs($useSubDirs);
+ $this->clearFiles();
+ $this->makeFiles();
+
+ $expected = array(
+ 'helloworld.tpl#', 'helloworld.tpl#compile2',
+ 'helloworld2.tpl#', 'helloworld2.tpl#compile1', 'helloworld2.tpl#compile2',
+ 'ambiguous/case1/foobar.tpl#', 'ambiguous/case1/foobar.tpl#compile1', 'ambiguous/case1/foobar.tpl#compile2',
+ '[1]ambiguous/case1/foobar.tpl#', '[1]ambiguous/case1/foobar.tpl#compile1', '[1]ambiguous/case1/foobar.tpl#compile2',
+ );
+ $this->touchFiles(array('helloworld.tpl#compile1', 'helloworld.tpl#compile2'), - 1000);
+ $this->assertEquals(1, $this->smarty->clearCompiledTemplate("helloworld.tpl", "compile1", 500));
+
+ $this->assertEquals($this->expectFiles($expected), $this->getFiles());
+ $this->clearFiles();
+ }
+
+ // Smarty::clearCompiledTemplate(null, $cache_id, $expired)
+ public function testClearCacheidExpired()
+ {
+ $this->runClearCacheidExpired(false);
+ }
+
+ public function testSubsClearCacheidExpired()
+ {
+ $this->runClearCacheidExpired(true);
+ }
+
+ public function runClearCacheidExpired($useSubDirs)
+ {
+ $this->smarty->setUseSubDirs($useSubDirs);
+ $this->clearFiles();
+ $this->makeFiles();
+
+ $expected = array(
+ 'helloworld.tpl#', 'helloworld.tpl#compile2',
+ 'helloworld2.tpl#', 'helloworld2.tpl#compile1', 'helloworld2.tpl#compile2',
+ 'ambiguous/case1/foobar.tpl#', 'ambiguous/case1/foobar.tpl#compile1', 'ambiguous/case1/foobar.tpl#compile2',
+ '[1]ambiguous/case1/foobar.tpl#', '[1]ambiguous/case1/foobar.tpl#compile1', '[1]ambiguous/case1/foobar.tpl#compile2',
+ );
+ $this->touchFiles(array('helloworld.tpl#compile1'), - 1000);
+ $this->assertEquals(1, $this->smarty->clearCompiledTemplate(null, "compile1", 500));
+
+ $this->assertEquals($this->expectFiles($expected), $this->getFiles());
+ $this->clearFiles();
+ }
+
+ // Smarty::clearCompiledTemplate($template, $cache_id, null)
+ public function testClearTemplateCacheid()
+ {
+ $this->runClearTemplateCacheid(false);
+ }
+
+ public function testSubsClearTemplateCacheid()
+ {
+ $this->runClearTemplateCacheid(true);
+ }
+
+ public function runClearTemplateCacheid($useSubDirs)
+ {
+ $this->smarty->setUseSubDirs($useSubDirs);
+ $this->clearFiles();
+ $this->makeFiles();
+
+ $expected = array(
+ 'helloworld.tpl#', 'helloworld.tpl#compile2',
+ 'helloworld2.tpl#', 'helloworld2.tpl#compile1', 'helloworld2.tpl#compile2',
+ 'ambiguous/case1/foobar.tpl#', 'ambiguous/case1/foobar.tpl#compile1', 'ambiguous/case1/foobar.tpl#compile2',
+ '[1]ambiguous/case1/foobar.tpl#', '[1]ambiguous/case1/foobar.tpl#compile1', '[1]ambiguous/case1/foobar.tpl#compile2',
+ );
+ $this->assertEquals(1, $this->smarty->clearCompiledTemplate("helloworld.tpl", "compile1"));
+
+ $this->assertEquals($this->expectFiles($expected), $this->getFiles());
+ $this->clearFiles();
+ }
+
+ public function testClearAmbiguousTemplate()
+ {
+ $this->runClearAmbiguousTemplate(false);
+ }
+
+ public function testSubsAmbiguousTemplate()
+ {
+ $this->runClearAmbiguousTemplate(true);
+ }
+
+ public function runClearAmbiguousTemplate($useSubDirs)
+ {
+ $this->smarty->setUseSubDirs($useSubDirs);
+ $this->clearFiles();
+ $this->makeFiles();
+
+ // TODO: uwe.tews - shouldn't clearCompiledTemplate("foo.tpl") remove "{$template_dir[0]}/foo.tpl" AND "{$template_dir[1]}/foo.tpl"?
+ // currently it kills only the first one found (through regular template file identification methods)
+
+ $expected = array(
+ 'helloworld.tpl#', 'helloworld.tpl#compile1', 'helloworld.tpl#compile2',
+ 'helloworld2.tpl#', 'helloworld2.tpl#compile1', 'helloworld2.tpl#compile2',
+ '[1]ambiguous/case1/foobar.tpl#', '[1]ambiguous/case1/foobar.tpl#compile1', '[1]ambiguous/case1/foobar.tpl#compile2',
+ );
+ $this->assertEquals(3, $this->smarty->clearCompiledTemplate("ambiguous/case1/foobar.tpl"));
+
+ $this->assertEquals($this->expectFiles($expected), $this->getFiles());
+ $this->clearFiles();
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates/ambiguous/case1/foobar.tpl b/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates/ambiguous/case1/foobar.tpl
new file mode 100644
index 00000000..b6e9ce55
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates/ambiguous/case1/foobar.tpl
@@ -0,0 +1 @@
+templates_2
\ No newline at end of file
diff --git a/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates/helloworld.tpl b/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates/helloworld.tpl
new file mode 100644
index 00000000..95d09f2b
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates/helloworld.tpl
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates/helloworld2.tpl b/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates/helloworld2.tpl
new file mode 100644
index 00000000..95d09f2b
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates/helloworld2.tpl
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates_2/ambiguous/case1/foobar.tpl b/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates_2/ambiguous/case1/foobar.tpl
new file mode 100644
index 00000000..b6e9ce55
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates_2/ambiguous/case1/foobar.tpl
@@ -0,0 +1 @@
+templates_2
\ No newline at end of file
diff --git a/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates_2/dirname.tpl b/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates_2/dirname.tpl
new file mode 100644
index 00000000..b6e9ce55
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates_2/dirname.tpl
@@ -0,0 +1 @@
+templates_2
\ No newline at end of file
diff --git a/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates_2/hello.tpl b/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates_2/hello.tpl
new file mode 100644
index 00000000..95d09f2b
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates_2/hello.tpl
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates_2/helloworld.php b/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates_2/helloworld.php
new file mode 100644
index 00000000..6fe5b4ba
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/ClearCompiledTemplate/templates_2/helloworld.php
@@ -0,0 +1 @@
+php hello world
diff --git a/tests/UnitTests/SmartyMethodsTests/GetTemplateVars/GetTemplateVarsTest.php b/tests/UnitTests/SmartyMethodsTests/GetTemplateVars/GetTemplateVarsTest.php
new file mode 100644
index 00000000..0fdf5aba
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/GetTemplateVars/GetTemplateVarsTest.php
@@ -0,0 +1,110 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test root getTemplateVars single value
+ */
+ public function testGetSingleTemplateVarScopeRoot()
+ {
+ $this->smarty->assign('foo', 'bar');
+ $this->smarty->assign('blar', 'buh');
+ $this->assertEquals("bar", $this->smarty->getTemplateVars('foo'));
+ }
+
+ /**
+ * test root getTemplateVars all values
+ */
+ public function testGetAllTemplateVarsScopeRoot()
+ {
+ $this->smarty->assign('foo', 'bar');
+ $this->smarty->assign('blar', 'buh');
+ $vars = $this->smarty->getTemplateVars();
+ $this->assertTrue(is_array($vars));
+ $this->assertEquals("bar", $vars['foo']);
+ $this->assertEquals("buh", $vars['blar']);
+ }
+
+ /**
+ * test single variable with data object chain
+ */
+ public function testGetSingleTemplateVarScopeAll()
+ {
+ $data1 = new Smarty_Data($this->smarty);
+ $data2 = new Smarty_Data($data1);
+ $this->smarty->assign('foo', 'bar');
+ $this->smarty->assign('blar', 'buh');
+ $this->assertEquals("bar", $this->smarty->getTemplateVars('foo', $data2));
+ }
+
+ /**
+ * test get all variables with data object chain
+ */
+ public function testGetAllTemplateVarsScopeAll()
+ {
+ $data1 = new Smarty_Data($this->smarty);
+ $data2 = new Smarty_Data($data1);
+ $this->smarty->assign('foo', 'bar');
+ $data1->assign('blar', 'buh');
+ $data2->assign('foo2', 'bar2');
+ $vars = $this->smarty->getTemplateVars(null, $data2);
+ $this->assertTrue(is_array($vars));
+ $this->assertEquals("bar", $vars['foo']);
+ $this->assertEquals("bar2", $vars['foo2']);
+ $this->assertEquals("buh", $vars['blar']);
+ }
+
+ /**
+ * test get all variables with data object chain search parents disabled
+ */
+ public function testGetAllTemplateVarsScopeAllNoParents()
+ {
+ $data1 = new Smarty_Data($this->smarty);
+ $data2 = new Smarty_Data($data1);
+ $this->smarty->assign('foo', 'bar');
+ $data1->assign('blar', 'buh');
+ $data2->assign('foo2', 'bar2');
+ $vars = $this->smarty->getTemplateVars(null, $data2, false);
+ $this->assertTrue(is_array($vars));
+ $this->assertFalse(isset($vars['foo']));
+ $this->assertEquals("bar2", $vars['foo2']);
+ $this->assertFalse(isset($vars['blar']));
+ }
+
+ /**
+ * test get single variables with data object chain search parents disabled
+ */
+ public function testGetSingleTemplateVarsScopeAllNoParents()
+ {
+ error_reporting(error_reporting() & ~(E_NOTICE | E_USER_NOTICE));
+ $data1 = new Smarty_Data($this->smarty);
+ $data2 = new Smarty_Data($data1);
+ $this->smarty->assign('foo', 'bar');
+ $data1->assign('blar', 'buh');
+ $data2->assign('foo2', 'bar2');
+ $this->assertEquals("", $this->smarty->getTemplateVars('foo', $data2, false));
+ $this->assertEquals("bar2", $this->smarty->getTemplateVars('foo2', $data2, false));
+ $this->assertEquals("", $this->smarty->getTemplateVars('blar', $data2, false));
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/RegisterBlock/RegisterBlockTest.php b/tests/UnitTests/SmartyMethodsTests/RegisterBlock/RegisterBlockTest.php
new file mode 100644
index 00000000..3294c22a
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/RegisterBlock/RegisterBlockTest.php
@@ -0,0 +1,310 @@
+block / unregister->block methods
+ *
+ * @package PHPunit
+ * @author Uwe Tews
+ */
+
+/**
+ * class for register->block / unregister->block methods tests
+ *
+ * @backupStaticAttributes enabled
+ */
+class RegisterBlockTest extends PHPUnit_Smarty
+{
+ public $loadSmartyBC = true;
+ public function setUp()
+ {
+ $this->setUpSmarty(__DIR__);
+ $this->smarty->disableSecurity();
+ $this->smartyBC->disableSecurity();
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test registerPlugin method for block function
+ */
+ public function testRegisterBlockFunction()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_BLOCK, 'testblock', 'myblock');
+ $this->smarty->assign('value', 1);
+ $this->assertEquals('function hello world 1 1 function hello world 1 2 function hello world 1 3 ', $this->smarty->fetch('eval:{testblock}hello world {$value}{/testblock}'));
+ }
+
+ public function testRegisterBlockFunctionModifier1()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_BLOCK, 'testblock', 'myblock');
+ $this->smarty->assign('value', 1);
+ $this->assertEquals(strtoupper('function hello world 1 1 function hello world 1 2 function hello world 1 3 '), $this->smarty->fetch('eval:{testblock}hello world {$value}{/testblock|strtoupper}'));
+ }
+
+ public function testRegisterBlockFunctionModifier2()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_BLOCK, 'testblock', 'myblock');
+ $this->smarty->assign('value', 1);
+ $this->assertEquals(strtoupper('function hello world 1 1 function hello world 1 2 function hello world 1 3 '), $this->smarty->fetch('eval:{testblock}hello world {$value}{/testblock|default:""|strtoupper}'));
+ }
+
+ public function testRegisterBlockFunctionWrapper()
+ {
+ $this->smartyBC->register_block('testblock', 'myblock');
+ $this->smartyBC->assign('value', 1);
+ $this->assertEquals('function hello world 1 1 function hello world 1 2 function hello world 1 3 ', $this->smartyBC->fetch('eval:{testblock}hello world {$value}{/testblock}'));
+ }
+
+ /**
+ * test registerPlugin method for block class
+ */
+ public function testRegisterBlockClass()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_BLOCK, 'testblock', array('myblockclass', 'static_method'));
+ $this->smarty->assign('value', 2);
+ $this->assertEquals('static hello world 2 1 static hello world 2 2 static hello world 2 3 ', $this->smarty->fetch('eval:{testblock}hello world {$value}{/testblock}'));
+ }
+
+ public function testRegisterBlockClassWrapper()
+ {
+ $this->smartyBC->register_block('testblock', array('myblockclass', 'static_method'));
+ $this->smartyBC->assign('value', 2);
+ $this->assertEquals('static hello world 2 1 static hello world 2 2 static hello world 2 3 ', $this->smartyBC->fetch('eval:{testblock}hello world {$value}{/testblock}'));
+ }
+
+ /**
+ * test registerPlugin method for block object
+ */
+ public function testRegisterBlockObject()
+ {
+ $myblock_object = new myblockclass;
+ $this->smarty->registerPlugin(Smarty::PLUGIN_BLOCK, 'testblock', array($myblock_object, 'object_method'));
+ $this->smarty->assign('value', 3);
+ $this->assertEquals('object hello world 3 1 object hello world 3 2 object hello world 3 3 ', $this->smarty->fetch('eval:{testblock}hello world {$value}{/testblock}'));
+ }
+
+ public function testRegisterBlockObjectWrapper()
+ {
+ $myblock_object = new myblockclass;
+ $this->smartyBC->register_block('testblock', array($myblock_object, 'object_method'));
+ $this->smartyBC->assign('value', 3);
+ $this->assertEquals('object hello world 3 1 object hello world 3 2 object hello world 3 3 ', $this->smartyBC->fetch('eval:{testblock}hello world {$value}{/testblock}'));
+ }
+
+ /**
+ * test registerPlugin method for block with caching
+ */
+ public function testRegisterBlockCaching1()
+ {
+ $this->smarty->caching = 1;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setForceCompile(true);
+ $this->smarty->assign('x', 1);
+ $this->smarty->assign('y', 10);
+ $this->smarty->assign('z', 100);
+ $this->smarty->registerPlugin(Smarty::PLUGIN_BLOCK, 'testblock', 'myblockcache');
+ $this->assertEquals('1 10 100', $this->smarty->fetch('test_register_block.tpl'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testRegisterBlockCaching2()
+ {
+ $this->smarty->caching = 1;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->assign('x', 2);
+ $this->smarty->assign('y', 20);
+ $this->smarty->assign('z', 200);
+ $this->smarty->registerPlugin(Smarty::PLUGIN_BLOCK, 'testblock', 'myblockcache');
+ $this->assertEquals('1 10 100', $this->smarty->fetch('test_register_block.tpl'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testRegisterBlockCaching3()
+ {
+ $this->smarty->caching = 1;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setForceCompile(true);
+ $this->smarty->assign('x', 3);
+ $this->smarty->assign('y', 30);
+ $this->smarty->assign('z', 300);
+ $this->smarty->registerPlugin(Smarty::PLUGIN_BLOCK, 'testblock', 'myblockcache', false);
+ $this->assertEquals('3 30 300', $this->smarty->fetch('test_register_block.tpl'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testRegisterBlockCaching4()
+ {
+ $this->smarty->caching = 1;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->assign('x', 4);
+ $this->smarty->assign('y', 40);
+ $this->smarty->assign('z', 400);
+ $this->smarty->registerPlugin(Smarty::PLUGIN_BLOCK, 'testblock', 'myblockcache', false);
+ $this->assertEquals('3 40 300', $this->smarty->fetch('test_register_block.tpl'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testRegisterBlockCaching1Wrapper()
+ {
+ $this->smartyBC->caching = 1;
+ $this->smartyBC->cache_lifetime = 1000;
+ $this->smartyBC->setForceCompile(true);
+ $this->smartyBC->assign('x', 1);
+ $this->smartyBC->assign('y', 10);
+ $this->smartyBC->assign('z', 100);
+ $this->smartyBC->register_block('testblock', 'myblockcache');
+ $this->assertEquals('1 10 100', $this->smartyBC->fetch('test_register_block.tpl'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testRegisterBlockCaching2Wrapper()
+ {
+ $this->smartyBC->caching = 1;
+ $this->smartyBC->cache_lifetime = 1000;
+ $this->smartyBC->assign('x', 2);
+ $this->smartyBC->assign('y', 20);
+ $this->smartyBC->assign('z', 200);
+ $this->smartyBC->register_block('testblock', 'myblockcache');
+ $this->assertEquals('1 10 100', $this->smartyBC->fetch('test_register_block.tpl'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testRegisterBlockCaching3Wrapper()
+ {
+ $this->smartyBC->caching = 1;
+ $this->smartyBC->cache_lifetime = 1000;
+ $this->smartyBC->setForceCompile(true);
+ $this->smartyBC->assign('x', 3);
+ $this->smartyBC->assign('y', 30);
+ $this->smartyBC->assign('z', 300);
+ $this->smartyBC->register_block('testblock', 'myblockcache', false);
+ $this->assertEquals('3 30 300', $this->smartyBC->fetch('test_register_block.tpl'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testRegisterBlockCaching4Wrapper()
+ {
+ $this->smartyBC->caching = 1;
+ $this->smartyBC->cache_lifetime = 1000;
+ $this->smartyBC->assign('x', 4);
+ $this->smartyBC->assign('y', 40);
+ $this->smartyBC->assign('z', 400);
+ $this->smartyBC->register_block('testblock', 'myblockcache', false);
+ $this->assertEquals('3 40 300', $this->smartyBC->fetch('test_register_block.tpl'));
+ }
+
+ /**
+ * test unregister->block method
+ */
+ public function testUnregisterBlock()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_BLOCK, 'testblock', 'myblock');
+ $this->smarty->unregisterPlugin(Smarty::PLUGIN_BLOCK, 'testblock');
+ $this->assertFalse(isset($this->smarty->registered_plugins[Smarty::PLUGIN_BLOCK]['testblock']));
+ }
+
+ public function testUnregisterBlockWrapper()
+ {
+ $this->smartyBC->register_block('testblock', 'myblock');
+ $this->smartyBC->unregister_block('testblock');
+ $this->assertFalse(isset($this->smartyBC->registered_plugins[Smarty::PLUGIN_BLOCK]['testblock']));
+ }
+
+ /**
+ * test unregister->block method not registered
+ */
+ public function testUnregisterBlockNotRegistered()
+ {
+ $this->smarty->unregisterPlugin(Smarty::PLUGIN_BLOCK, 'testblock');
+ $this->assertFalse(isset($this->smarty->registered_plugins[Smarty::PLUGIN_BLOCK]['testblock']));
+ }
+}
+
+function myblock($params, $content, &$smarty_tpl, &$repeat)
+{
+ static $loop = 0;
+
+ if ($content == null) {
+ $loop = 0;
+
+ return;
+ }
+ $loop ++;
+ if ($loop < 3) {
+ $repeat = true;
+ }
+
+ return "function $content $loop ";
+}
+
+function myblockcache($params, $content, &$smarty_tpl, &$repeat)
+{
+ return $content;
+}
+
+class myblockclass
+{
+ static function static_method($params, $content, &$smarty_tpl, &$repeat)
+ {
+ static $loop = 0;
+
+ if ($content == null) {
+ $loop = 0;
+
+ return;
+ }
+ $loop ++;
+ if ($loop < 3) {
+ $repeat = true;
+ }
+
+ return "static $content $loop ";
+ }
+
+ public function object_method($params, $content, &$smarty_tpl, &$repeat)
+ {
+ static $loop = 0;
+
+ if ($content == null) {
+ $loop = 0;
+
+ return;
+ }
+ $loop ++;
+ if ($loop < 3) {
+ $repeat = true;
+ }
+
+ return "object $content $loop ";
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/RegisterBlock/templates/test_register_block.tpl b/tests/UnitTests/SmartyMethodsTests/RegisterBlock/templates/test_register_block.tpl
new file mode 100644
index 00000000..858eab15
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/RegisterBlock/templates/test_register_block.tpl
@@ -0,0 +1 @@
+{$x} {testblock}{$y}{/testblock} {$z}
\ No newline at end of file
diff --git a/tests/UnitTests/SmartyMethodsTests/RegisterCompiler/RegisterCompilerFunctionTest.php b/tests/UnitTests/SmartyMethodsTests/RegisterCompiler/RegisterCompilerFunctionTest.php
new file mode 100644
index 00000000..33f8aa8d
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/RegisterCompiler/RegisterCompilerFunctionTest.php
@@ -0,0 +1,122 @@
+compilerFunction / unregister->compilerFunction methods
+ *
+ * @package PHPunit
+ * @author Uwe Tews
+ */
+
+/**
+ * class for register->compilerFunction / unregister->compilerFunction methods tests
+ *
+ * @backupStaticAttributes enabled
+ */
+class RegisterCompilerFunctionTest extends PHPUnit_Smarty
+{
+ public function setUp()
+ {
+ $this->setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test register->compilerFunction method for function
+ */
+ public function testRegisterCompilerFunction()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_COMPILER, 'testcompilerfunction', 'mycompilerfunction');
+ $this->assertEquals('mycompilerfunction', $this->smarty->registered_plugins['compiler']['testcompilerfunction'][0]);
+ $this->assertEquals('hello world 1', $this->smarty->fetch('eval:{testcompilerfunction var=1}'));
+ }
+
+ /**
+ * test register->compilerFunction method for blocks
+ */
+ public function testRegisterCompilerFunctionBlock()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_COMPILER, 'foo', 'mycompilerfunctionopen');
+ $this->smarty->registerPlugin(Smarty::PLUGIN_COMPILER, 'fooclose', 'mycompilerfunctionclose');
+ $result = $this->smarty->fetch('eval:{foo} hallo {/foo}');
+ $this->assertEquals('open tag hallo close tag', $result);
+ }
+
+ /**
+ * test register->compilerFunction method for static class
+ */
+ public function testRegisterCompilerFunctionClass()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_COMPILER, 'testcompilerfunction', array('mycompilerfunctionclass', 'execute'));
+ $this->assertEquals('hello world 2', $this->smarty->fetch('eval:{testcompilerfunction var1=2}'));
+ }
+
+ /**
+ * test register->compilerFunction method for objects
+ */
+ public function testRegisterCompilerFunctionObject()
+ {
+ $obj = new mycompilerfunctionclass;
+ $this->smarty->registerPlugin(Smarty::PLUGIN_COMPILER, 'testcompilerfunction', array($obj, 'compile'));
+ $this->assertEquals('hello world 3', $this->smarty->fetch('eval:{testcompilerfunction var2=3}'));
+ }
+
+ /**
+ * test unregister->compilerFunction method
+ */
+ public function testUnregisterCompilerFunction()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_COMPILER, 'testcompilerfunction', 'mycompilerfunction');
+ $this->smarty->unregisterPlugin(Smarty::PLUGIN_COMPILER, 'testcompilerfunction');
+ $this->assertFalse(isset($this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER]['testcompilerfunction']));
+ }
+
+ /**
+ * test unregister->compilerFunction method not registered
+ */
+ public function testUnregisterCompilerFunctionNotRegistered()
+ {
+ $this->smarty->unregisterPlugin(Smarty::PLUGIN_COMPILER, 'testcompilerfunction');
+ $this->assertFalse(isset($this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER]['testcompilerfunction']));
+ }
+
+ /**
+ * test unregister->compilerFunction method other registered
+ */
+ public function testUnregisterCompilerFunctionOtherRegistered()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_BLOCK, 'testcompilerfunction', 'mycompilerfunction');
+ $this->smarty->unregisterPlugin(Smarty::PLUGIN_COMPILER, 'testcompilerfunction');
+ $this->assertTrue(isset($this->smarty->registered_plugins[Smarty::PLUGIN_BLOCK]['testcompilerfunction']));
+ }
+}
+
+function mycompilerfunction($params, $smarty)
+{
+ return "";
+}
+
+function mycompilerfunctionopen($params, $smarty)
+{
+ return "";
+}
+
+function mycompilerfunctionclose($params, $smarty)
+{
+ return "";
+}
+
+class mycompilerfunctionclass
+{
+ static function execute($params, $smarty)
+ {
+ return "";
+ }
+
+ public function compile($params, $smarty)
+ {
+ return "";
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/RegisterFunction/RegisterFunctionTest.php b/tests/UnitTests/SmartyMethodsTests/RegisterFunction/RegisterFunctionTest.php
new file mode 100644
index 00000000..a54b296c
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/RegisterFunction/RegisterFunctionTest.php
@@ -0,0 +1,164 @@
+templateFunction / unregister->templateFunction methods
+ *
+ * @package PHPunit
+ * @author Uwe Tews
+ */
+
+/**
+ * class for register->templateFunction / unregister->templateFunction methods tests
+ *
+ * @backupStaticAttributes enabled
+ *
+ */
+class RegisterFunctionTest extends PHPUnit_Smarty
+{
+ public function setUp()
+ {
+ $this->setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test register->templateFunction method for function
+ */
+ public function testRegisterFunction()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_FUNCTION, 'testfunction', 'myfunction');
+ $this->assertEquals('myfunction', $this->smarty->registered_plugins[Smarty::PLUGIN_FUNCTION]['testfunction'][0]);
+ $this->assertEquals('hello world 1', $this->smarty->fetch('eval:{testfunction value=1}'));
+ }
+
+ /**
+ * test wrapper rfor egister_function method for function
+ */
+ public function testRegisterFunctionWrapper()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_FUNCTION, 'testfunction', 'myfunction');
+ $this->assertEquals('myfunction', $this->smarty->registered_plugins[Smarty::PLUGIN_FUNCTION]['testfunction'][0]);
+ $this->assertEquals('hello world 1', $this->smarty->fetch('eval:{testfunction value=1}'));
+ }
+
+ /**
+ * test register->templateFunction method for class
+ */
+ public function testRegisterFunctionClass()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_FUNCTION, 'testfunction', array('myfunctionclass', 'execute'));
+ $this->assertEquals('hello world 2', $this->smarty->fetch('eval:{testfunction value=2}'));
+ }
+
+ /**
+ * test register->templateFunction method for object
+ */
+ public function testRegisterFunctionObject()
+ {
+ $myfunction_object = new myfunctionclass;
+ $this->smarty->registerPlugin(Smarty::PLUGIN_FUNCTION, 'testfunction', array($myfunction_object, 'execute'));
+ $this->assertEquals('hello world 3', $this->smarty->fetch('eval:{testfunction value=3}'));
+ }
+
+ public function testRegisterFunctionCaching1()
+ {
+ $this->smarty->caching = 1;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setForceCompile(true);
+ $this->smarty->assign('x', 0);
+ $this->smarty->assign('y', 10);
+ $this->smarty->registerPlugin(Smarty::PLUGIN_FUNCTION, 'testfunction', 'myfunction');
+ $this->assertEquals('hello world 0 10', $this->smarty->fetch('test_register_function.tpl'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testRegisterFunctionCaching2()
+ {
+ $this->smarty->caching = 1;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->assign('x', 1);
+ $this->smarty->assign('y', 20);
+ $this->smarty->registerPlugin(Smarty::PLUGIN_FUNCTION, 'testfunction', 'myfunction');
+ $this->assertEquals('hello world 0 10', $this->smarty->fetch('test_register_function.tpl'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testRegisterFunctionCaching3()
+ {
+ $this->smarty->caching = 1;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->setForceCompile(true);
+ $this->smarty->assign('x', 2);
+ $this->smarty->assign('y', 30);
+ $this->smarty->registerPlugin(Smarty::PLUGIN_FUNCTION, 'testfunction', 'myfunction', false);
+ $this->assertEquals('hello world 2 30', $this->smarty->fetch('test_register_function.tpl'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testRegisterFunctionCaching4()
+ {
+ $this->smarty->caching = 1;
+ $this->smarty->cache_lifetime = 1000;
+ $this->smarty->assign('x', 3);
+ $this->smarty->assign('y', 40);
+ $this->smarty->registerPlugin(Smarty::PLUGIN_FUNCTION, 'testfunction', 'myfunction', false);
+ $this->assertEquals('hello world 3 30', $this->smarty->fetch('test_register_function.tpl'));
+ }
+
+ /**
+ * test unregister->templateFunction method
+ */
+ public function testUnregisterFunction()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_FUNCTION, 'testfunction', 'myfunction');
+ $this->smarty->unregisterPlugin(Smarty::PLUGIN_FUNCTION, 'testfunction');
+ $this->assertFalse(isset($this->smarty->registered_plugins[Smarty::PLUGIN_FUNCTION]['testfunction']));
+ }
+
+ /**
+ * test unregister->templateFunction method not registered
+ */
+ public function testUnregisterFunctionNotRegistered()
+ {
+ $this->smarty->unregisterPlugin(Smarty::PLUGIN_FUNCTION, 'testfunction');
+ $this->assertFalse(isset($this->smarty->registered_plugins[Smarty::PLUGIN_FUNCTION]['testfunction']));
+ }
+
+ /**
+ * test unregister->templateFunction method other registered
+ */
+ public function testUnregisterFunctionOtherRegistered()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_BLOCK, 'testfunction', 'myfunction');
+ $this->smarty->unregisterPlugin(Smarty::PLUGIN_FUNCTION, 'testfunction');
+ $this->assertTrue(isset($this->smarty->registered_plugins[Smarty::PLUGIN_BLOCK]['testfunction']));
+ }
+}
+
+function myfunction($params, &$smarty)
+{
+ return "hello world $params[value]";
+}
+
+class myfunctionclass
+{
+ static function execute($params, &$smarty)
+ {
+ return "hello world $params[value]";
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/RegisterFunction/templates/test_register_function.tpl b/tests/UnitTests/SmartyMethodsTests/RegisterFunction/templates/test_register_function.tpl
new file mode 100644
index 00000000..58453b77
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/RegisterFunction/templates/test_register_function.tpl
@@ -0,0 +1 @@
+{testfunction value=$x} {$y}
\ No newline at end of file
diff --git a/tests/UnitTests/SmartyMethodsTests/RegisterModifier/RegisterModifierTest.php b/tests/UnitTests/SmartyMethodsTests/RegisterModifier/RegisterModifierTest.php
new file mode 100644
index 00000000..509721db
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/RegisterModifier/RegisterModifierTest.php
@@ -0,0 +1,107 @@
+modifier / unregister->modifier methods
+ *
+ * @package PHPunit
+ * @author Uwe Tews
+ */
+
+/**
+ * class for register->modifier / unregister->modifier methods tests
+ *
+ * @backupStaticAttributes enabled
+ */
+class RegisterModifierTest extends PHPUnit_Smarty
+{
+ public function setUp()
+ {
+ $this->setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test register->modifier method for function
+ */
+ public function testRegisterModifier()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_MODIFIER, 'testmodifier', 'mymodifier');
+ $this->assertEquals('mymodifier', $this->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER]['testmodifier'][0]);
+ $this->smarty->assign('foo', 'foo');
+ $this->smarty->assign('bar', 'bar');
+ $this->assertEquals('foo function blar bar', $this->smarty->fetch('eval:{$foo|testmodifier:blar:$bar}'));
+ }
+
+ /**
+ * test register->modifier method for classes
+ */
+ public function testRegisterModifierClass()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_MODIFIER, 'testmodifier', array('mymodifierclass', 'static_method'));
+ $this->smarty->assign('foo', 'foo');
+ $this->smarty->assign('bar', 'bar');
+ $this->assertEquals('foo static blar bar', $this->smarty->fetch('eval:{$foo|testmodifier:blar:$bar}'));
+ }
+
+ /**
+ * test register->modifier method for objects
+ */
+ public function testRegisterModifierObject()
+ {
+ $obj = new mymodifierclass;
+ $this->smarty->registerPlugin(Smarty::PLUGIN_MODIFIER, 'testmodifier', array($obj, 'object_method'));
+ $this->smarty->assign('foo', 'foo');
+ $this->smarty->assign('bar', 'bar');
+ $this->assertEquals('foo object blar bar', $this->smarty->fetch('eval:{$foo|testmodifier:blar:$bar}'));
+ }
+
+ /**
+ * test unregister->modifier method
+ */
+ public function testUnregisterModifier()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_MODIFIER, 'testmodifier', 'mymodifier');
+ $this->smarty->unregisterPlugin(Smarty::PLUGIN_MODIFIER, 'testmodifier');
+ $this->assertFalse(isset($this->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER]['testmodifier']));
+ }
+
+ /**
+ * test unregister->modifier method not registered
+ */
+ public function testUnregisterModifierNotRegistered()
+ {
+ $this->smarty->unregisterPlugin(Smarty::PLUGIN_MODIFIER, 'testmodifier');
+ $this->assertFalse(isset($this->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER]['testmodifier']));
+ }
+
+ /**
+ * test unregister->modifier method other registered
+ */
+ public function testUnregisterModifierOtherRegistered()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_BLOCK, 'testmodifier', 'mymodifier');
+ $this->smarty->unregisterPlugin(Smarty::PLUGIN_MODIFIER, 'testmodifier');
+ $this->assertTrue(isset($this->smarty->registered_plugins[Smarty::PLUGIN_BLOCK]['testmodifier']));
+ }
+}
+
+function mymodifier($a, $b, $c)
+{
+ return "$a function $b $c";
+}
+
+class mymodifierclass
+{
+ static function static_method($a, $b, $c)
+ {
+ return "$a static $b $c";
+ }
+
+ public function object_method($a, $b, $c)
+ {
+ return "$a object $b $c";
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/RegisterObject/CompileRegisteredObjectFunctionTest.php b/tests/UnitTests/SmartyMethodsTests/RegisterObject/CompileRegisteredObjectFunctionTest.php
new file mode 100644
index 00000000..5e88029f
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/RegisterObject/CompileRegisteredObjectFunctionTest.php
@@ -0,0 +1,104 @@
+setUpSmarty(__DIR__);
+
+ $this->smarty->setForceCompile(true);
+ $this->smarty->disableSecurity();
+ $this->object = new RegObject;
+ $this->smarty->registerObject('objecttest', $this->object, 'myhello', true, 'myblock');
+ $this->smarty->registerObject('objectprop', $this->object);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test resgistered object as function
+ */
+ public function testRegisteredObjectFunction()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{objecttest->myhello}');
+ $this->assertEquals('hello world', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test resgistered object as function with modifier
+ */
+ public function testRegisteredObjectFunctionModifier()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{objecttest->myhello|truncate:6}');
+ $this->assertEquals('hel...', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test resgistered object as block function
+ */
+ public function testRegisteredObjectBlockFunction()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{objecttest->myblock}hello world{/objecttest->myblock}');
+ $this->assertEquals('block test', $this->smarty->fetch($tpl));
+ }
+
+ public function testRegisteredObjectBlockFunctionModifier1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{objecttest->myblock}hello world{/objecttest->myblock|strtoupper}');
+ $this->assertEquals(strtoupper('block test'), $this->smarty->fetch($tpl));
+ }
+
+ public function testRegisteredObjectBlockFunctionModifier2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{objecttest->myblock}hello world{/objecttest->myblock|default:""|strtoupper}');
+ $this->assertEquals(strtoupper('block test'), $this->smarty->fetch($tpl));
+ }
+ // TODO
+
+ /**
+ public function testRegisteredObjectProperty()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{objectprop->prop}');
+ $this->assertEquals('hello world', $this->smarty->fetch($tpl));
+ }
+
+ public function testRegisteredObjectPropertyAssign()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{objectprop->prop assign="foo"}{$foo}');
+ $this->assertEquals('hello world', $this->smarty->fetch($tpl));
+ }
+ */
+}
+
+Class RegObject
+{
+ public $prop = 'hello world';
+
+ public function myhello($params)
+ {
+ return 'hello world';
+ }
+
+ public function myblock($params, $content, &$smarty_tpl, &$repeat)
+ {
+ if (isset($content)) {
+ $output = str_replace('hello world', 'block test', $content);
+
+ return $output;
+ }
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/TemplateExist/TemplateExistsTest.php b/tests/UnitTests/SmartyMethodsTests/TemplateExist/TemplateExistsTest.php
new file mode 100644
index 00000000..611b5434
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/TemplateExist/TemplateExistsTest.php
@@ -0,0 +1,41 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test $smarty->templateExists true
+ */
+ public function testSmartyTemplateExists()
+ {
+ $this->assertTrue($this->smarty->templateExists('helloworld.tpl'));
+ }
+
+ /**
+ * test $smarty->templateExists false
+ */
+ public function testSmartyTemplateNotExists()
+ {
+ $this->assertFalse($this->smarty->templateExists('notthere.tpl'));
+ }
+}
diff --git a/tests/UnitTests/SmartyMethodsTests/TemplateExist/templates/helloworld.tpl b/tests/UnitTests/SmartyMethodsTests/TemplateExist/templates/helloworld.tpl
new file mode 100644
index 00000000..95d09f2b
--- /dev/null
+++ b/tests/UnitTests/SmartyMethodsTests/TemplateExist/templates/helloworld.tpl
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/Comments/CommentsTest.php b/tests/UnitTests/TemplateSource/Comments/CommentsTest.php
new file mode 100644
index 00000000..b26b9d7d
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/Comments/CommentsTest.php
@@ -0,0 +1,85 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test simple comments
+ */
+ public function testSimpleComment1()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{* this is a comment *}");
+ $this->assertEquals("", $this->smarty->fetch($tpl));
+ }
+
+ public function testSimpleComment2()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{* another \$foo comment *}");
+ $this->assertEquals("", $this->smarty->fetch($tpl));
+ }
+
+ public function testSimpleComment3()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{* another comment *}some in between{* another comment *}");
+ $this->assertEquals("some in between", $this->smarty->fetch($tpl));
+ }
+
+ public function testSimpleComment4()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{* multi line \n comment *}");
+ $this->assertEquals("", $this->smarty->fetch($tpl));
+ }
+
+ public function testSimpleComment5()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{* /* foo * / *}");
+ $this->assertEquals("", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test comment text combinations
+ */
+ public function testTextComment1()
+ {
+ $tpl = $this->smarty->createTemplate("eval:A{* comment *}B\nC");
+ $this->assertEquals("AB\nC", $this->smarty->fetch($tpl));
+ }
+
+ public function testTextComment2()
+ {
+ $tpl = $this->smarty->createTemplate("eval:D{* comment *}\n{* comment *}E\nF");
+ $this->assertEquals("D\nE\nF", $this->smarty->fetch($tpl));
+ }
+
+ public function testTextComment3()
+ {
+ $tpl = $this->smarty->createTemplate("eval:G{* multi \nline *}H");
+ $this->assertEquals("GH", $this->smarty->fetch($tpl));
+ }
+
+ public function testTextComment4()
+ {
+ $tpl = $this->smarty->createTemplate("eval:I{* multi \nline *}\nJ");
+ $this->assertEquals("I\nJ", $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/Spacing/SpacingTest.php b/tests/UnitTests/TemplateSource/Spacing/SpacingTest.php
new file mode 100644
index 00000000..c81cafc4
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/Spacing/SpacingTest.php
@@ -0,0 +1,107 @@
+setUpSmarty(__DIR__);
+ $this->smarty->assign('foo', 'bar');
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test variable output
+ */
+ public function testVariableSpacing1()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{\$foo}", null, null, $this->smarty);
+ $this->assertEquals("bar", $this->smarty->fetch($tpl));
+ }
+
+ public function testVariableSpacing2()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{\$foo}{\$foo}", null, null, $this->smarty);
+ $this->assertEquals("barbar", $this->smarty->fetch($tpl));
+ }
+
+ public function testVariableSpacing3()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{\$foo} {\$foo}", null, null, $this->smarty);
+ $this->assertEquals("bar bar", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test variable text combinations
+ */
+ public function testVariableText1()
+ {
+ $tpl = $this->smarty->createTemplate("eval:A{\$foo}B", null, null, $this->smarty);
+ $this->assertEquals("AbarB", $this->smarty->fetch($tpl));
+ }
+
+ public function testVariableText2()
+ {
+ $tpl = $this->smarty->createTemplate("eval:A {\$foo}B", null, null, $this->smarty);
+ $this->assertEquals("A barB", $this->smarty->fetch($tpl));
+ }
+
+ public function testVariableText3()
+ {
+ $tpl = $this->smarty->createTemplate("eval:A{\$foo} B", null, null, $this->smarty);
+ $this->assertEquals("Abar B", $this->smarty->fetch($tpl));
+ }
+
+ public function testVariableText4()
+ {
+ $tpl = $this->smarty->createTemplate("eval:A{\$foo}\nB", null, null, $this->smarty);
+ $this->assertEquals("Abar\nB", $this->smarty->fetch($tpl));
+ }
+
+ public function testVariableText5()
+ {
+ $tpl = $this->smarty->createTemplate("eval:A{\$foo}B\nC", null, null, $this->smarty);
+ $this->assertEquals("AbarB\nC", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test tag text combinations
+ */
+ public function testTagText1()
+ {
+ $tpl = $this->smarty->createTemplate("eval:A{assign var=zoo value='blah'}B");
+ $this->assertEquals("AB", $this->smarty->fetch($tpl));
+ }
+
+ public function testTagText2()
+ {
+ $tpl = $this->smarty->createTemplate("string:A\n{assign var=zoo value='blah'}\nB");
+ $this->assertEquals("A\nB", $this->smarty->fetch($tpl));
+ }
+
+ public function testTagText3()
+ {
+ $tpl = $this->smarty->createTemplate("eval:E{assign var=zoo value='blah'}\nF");
+ $this->assertEquals("EF", $this->smarty->fetch($tpl));
+ }
+
+ public function testTagText4()
+ {
+ $tpl = $this->smarty->createTemplate("eval:G\n{assign var=zoo value='blah'}H");
+ $this->assertEquals("G\nH", $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/StaticClass/StaticClassAccessTest.php b/tests/UnitTests/TemplateSource/StaticClass/StaticClassAccessTest.php
new file mode 100644
index 00000000..037eca3d
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/StaticClass/StaticClassAccessTest.php
@@ -0,0 +1,134 @@
+setUpSmarty(__DIR__);
+ $this->smarty->disableSecurity();
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test static class variable
+ */
+ public function testStaticClassVariable()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{mystaticclass::$static_var}');
+ $this->assertEquals('5', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test registered static class variable
+ */
+ public function testStaticRegisteredClassVariable()
+ {
+ $this->smarty->registerClass('registeredclass', 'mystaticclass');
+ $tpl = $this->smarty->createTemplate('eval:{registeredclass::$static_var}');
+ $this->assertEquals('5', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test static class constant
+ */
+ public function testStaticClassConstant()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{mystaticclass::STATIC_CONSTANT_VALUE}');
+ $this->assertEquals('3', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test static class constant
+ */
+ public function testRegisteredStaticClassConstant()
+ {
+ $this->smarty->registerClass('registeredclass', 'mystaticclass');
+ $tpl = $this->smarty->createTemplate('eval:{registeredclass::STATIC_CONSTANT_VALUE}');
+ $this->assertEquals('3', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test static class method
+ */
+ public function testStaticClassmethod()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{mystaticclass::square(5)}');
+ $this->assertEquals('25', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test static class method
+ */
+ public function testRegisteredStaticClassmethod()
+ {
+ $this->smarty->registerClass('registeredclass', 'mystaticclass');
+ $tpl = $this->smarty->createTemplate('eval:{registeredclass::square(5)}');
+ $this->assertEquals('25', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test static class variable method
+ */
+ public function testStaticClassVariablemethod()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=\'square\'}{mystaticclass::$foo(5)}');
+ $this->assertEquals('25', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test registered static class variable method
+ */
+ public function testRegisteredStaticClassVariablemethod()
+ {
+ $this->smarty->registerClass('registeredclass', 'mystaticclass');
+ $tpl = $this->smarty->createTemplate('eval:{$foo=\'square\'}{registeredclass::$foo(5)}');
+ $this->assertEquals('25', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test static class variable method
+ */
+ public function testStaticClassVariablemethod2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{mystaticclass::$foo(5)}');
+ $tpl->assign('foo', 'square');
+ $this->assertEquals('25', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test registered static class variable method
+ */
+ public function testRegisteredStaticClassVariablemethod2()
+ {
+ $this->smarty->registerClass('registeredclass', 'mystaticclass');
+ $tpl = $this->smarty->createTemplate('eval:{registeredclass::$foo(5)}');
+ $tpl->assign('foo', 'square');
+ $this->assertEquals('25', $this->smarty->fetch($tpl));
+ }
+}
+
+class mystaticclass
+{
+ const STATIC_CONSTANT_VALUE = 3;
+ static $static_var = 5;
+
+ static function square($i)
+ {
+ return $i * $i;
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/Append/CompileAppendTest.php b/tests/UnitTests/TemplateSource/TagTests/Append/CompileAppendTest.php
new file mode 100644
index 00000000..86019700
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Append/CompileAppendTest.php
@@ -0,0 +1,39 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test aappand tag
+ */
+ public function testAppend1()
+ {
+ $this->assertEquals("12", $this->smarty->fetch('eval:{$foo=1}{append var=foo value=2}{foreach $foo as $bar}{$bar}{/foreach}'));
+ }
+
+ public function testAppend2()
+ {
+ $this->smarty->assign('foo', 1);
+ $this->assertEquals("12", $this->smarty->fetch('eval:{append var=foo value=2}{foreach $foo as $bar}{$bar}{/foreach}'));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/Assign/CompileAssignTest.php b/tests/UnitTests/TemplateSource/TagTests/Assign/CompileAssignTest.php
new file mode 100644
index 00000000..a76b8d83
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Assign/CompileAssignTest.php
@@ -0,0 +1,172 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test old style of assign tag
+ */
+ public function testAssignOld1()
+ {
+ $this->assertEquals("1", $this->smarty->fetch('eval:{assign var=foo value=1}{$foo}'));
+ $this->assertEquals("1", $this->smarty->fetch('eval:{assign var = foo value= 1}{$foo}'));
+ }
+
+ public function testAssignOld2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=\'foo\' value=1}{$foo}');
+ $this->assertEquals("1", $this->smarty->fetch($tpl));
+ }
+
+ public function testAssignOld3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var="foo" value=1}{$foo}');
+ $this->assertEquals("1", $this->smarty->fetch($tpl));
+ }
+
+ public function testAssignOld4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=bar}{$foo}');
+ $this->assertEquals("bar", $this->smarty->fetch($tpl));
+ }
+
+ public function testAssignOld5()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=1+2}{$foo}');
+ $this->assertEquals("3", $this->smarty->fetch($tpl));
+ }
+
+ public function testAssignOld6()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=strlen(\'bar\')}{$foo}');
+ $this->assertEquals("3", $this->smarty->fetch($tpl));
+ }
+
+ public function testAssignOld7()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=\'bar\'|strlen}{$foo}');
+ $this->assertEquals("3", $this->smarty->fetch($tpl));
+ }
+
+ public function testAssignOld8()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=[9,8,7,6]}{foreach $foo as $x}{$x}{/foreach}');
+ $this->assertEquals("9876", $this->smarty->fetch($tpl));
+ }
+
+ public function testAssignOld9()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=[\'a\'=>9,\'b\'=>8,\'c\'=>7,\'d\'=>6]}{foreach $foo as $x}{$x@key}{$x}{/foreach}');
+ $this->assertEquals("a9b8c7d6", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test assign tag shorthands
+ */
+ public function testAssignShort1()
+ {
+ $this->assertEquals("1", $this->smarty->fetch('string:{assign foo value=1}{$foo}'));
+ }
+
+ public function testAssignShort2()
+ {
+ $this->assertEquals("1", $this->smarty->fetch('string:{assign foo 1}{$foo}'));
+ }
+
+ /**
+ * test new style of assign tag
+ */
+ public function testAssignNew1()
+ {
+ $this->assertEquals("1", $this->smarty->fetch('eval:{$foo=1}{$foo}'));
+ $this->assertEquals("1", $this->smarty->fetch('eval:{$foo =1}{$foo}'));
+ $this->assertEquals("1", $this->smarty->fetch('eval:{$foo = 1}{$foo}'));
+ }
+
+ public function testAssignNew2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=bar}{$foo}');
+ $this->assertEquals("bar", $this->smarty->fetch($tpl));
+ }
+
+ public function testAssignNew3()
+ {
+ $this->assertEquals("3", $this->smarty->fetch('eval:{$foo=1+2}{$foo}'));
+ $this->assertEquals("3", $this->smarty->fetch('eval:{$foo = 1+2}{$foo}'));
+ $this->assertEquals("3", $this->smarty->fetch('eval:{$foo = 1 + 2}{$foo}'));
+ }
+
+ public function testAssignNew4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=strlen(\'bar\')}{$foo}');
+ $this->assertEquals("3", $this->smarty->fetch($tpl));
+ }
+
+ public function testAssignNew5()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{\$foo='bar'|strlen}{\$foo}");
+ $this->assertEquals("3", $this->smarty->fetch($tpl));
+ }
+
+ public function testAssignNew6()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{\$foo=[9,8,7,6]}{foreach \$foo as \$x}{\$x}{/foreach}");
+ $this->assertEquals("9876", $this->smarty->fetch($tpl));
+ }
+
+ public function testAssignNew7()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{\$foo=['a'=>9,'b'=>8,'c'=>7,'d'=>6]}{foreach \$foo as \$x}{\$x@key}{\$x}{/foreach}");
+ $this->assertEquals("a9b8c7d6", $this->smarty->fetch($tpl));
+ }
+
+ public function testAssignArrayAppend()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{\$foo =1}{\$foo[] = 2}{foreach \$foo as \$x}{\$x@key}{\$x}{/foreach}");
+ $this->assertEquals("0112", $this->smarty->fetch($tpl));
+ }
+
+ public function testAssignArrayAppend2()
+ {
+ $this->smarty->assign('foo', 1);
+ $tpl = $this->smarty->createTemplate("eval:{\$foo[]=2}{foreach \$foo as \$x}{\$x@key}{\$x}{/foreach}", null, null, $this->smarty);
+ $this->assertEquals("0112", $this->smarty->fetch($tpl));
+ $tpl2 = $this->smarty->createTemplate("eval:{\$foo}", null, null, $this->smarty);
+ $this->assertEquals("1", $this->smarty->fetch($tpl2));
+ }
+
+ public function testAssignArrayAppend3()
+ {
+ $this->smarty->assign('foo', 1);
+ $tpl = $this->smarty->createTemplate("eval:{\$foo[]=2 scope=root}{foreach \$foo as \$x}{\$x@key}{\$x}{/foreach}", null, null, $this->smarty);
+ $this->assertEquals("0112", $this->smarty->fetch($tpl));
+ $tpl2 = $this->smarty->createTemplate("eval:{foreach \$foo as \$x}{\$x@key}{\$x}{/foreach}", null, null, $this->smarty);
+ $this->assertEquals("0112", $this->smarty->fetch($tpl2));
+ }
+
+ public function testAssignNestedArray()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{\$foo['a'][4]=1}{\$foo['a'][4]}");
+ $this->assertEquals("1", $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BlockPlugin/CompileBlockPluginTest.php b/tests/UnitTests/TemplateSource/TagTests/BlockPlugin/CompileBlockPluginTest.php
new file mode 100644
index 00000000..c59bd88c
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BlockPlugin/CompileBlockPluginTest.php
@@ -0,0 +1,144 @@
+setUpSmarty(__DIR__);
+ $this->smarty->addPluginsDir("./PHPunitplugins/");
+ $this->smarty->setForceCompile(true);
+ $this->smarty->disableSecurity();
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test block plugin tag
+ *
+ */
+ public function testBlockPluginNoAssign()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{textformat}hello world{/textformat}");
+ $this->assertEquals("hello world", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test block plugin tag with assign attribute
+ *
+ */
+ public function testBlockPluginAssign()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{textformat assign=foo}hello world{/textformat}{\$foo}");
+ $this->assertEquals("hello world", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test block plugin tag in template file
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testBlockPluginFromTemplateFile()
+ {
+ $tpl = $this->smarty->createTemplate('blockplugintest.tpl');
+ $this->assertEquals("abc", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test block plugin tag in compiled template file
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testBlockPluginFromCompiledTemplateFile()
+ {
+ $this->smarty->setForceCompile(false);
+ $tpl = $this->smarty->createTemplate('blockplugintest.tpl');
+ $this->assertEquals("abc", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test block plugin tag in template file
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testBlockPluginFromTemplateFileCache()
+ {
+ $this->smarty->setForceCompile(false);
+ $this->smarty->caching = 1;
+ $this->smarty->cache_lifetime = 10;
+ $tpl = $this->smarty->createTemplate('blockplugintest.tpl');
+ $this->assertEquals("abc", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test block plugin function definition in script
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testBlockPluginRegisteredFunction()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_BLOCK, 'blockplugintest', 'myblockplugintest');
+ $tpl = $this->smarty->createTemplate('eval:{blockplugintest}hello world{/blockplugintest}');
+ $this->assertEquals('block test', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test block plugin repeat function
+ *
+ */
+ public function testBlockPluginRepeat()
+ {
+ $this->smarty->addPluginsDir(dirname(__FILE__) . "/PHPunitplugins/");
+ $this->assertEquals('12345', $this->smarty->fetch('eval:{testblock}{/testblock}'));
+ }
+
+ /**
+ *
+ *
+ */
+ public function testBlockPluginRepeatModidier1()
+ {
+ $this->smarty->addPluginsDir(dirname(__FILE__) . "/PHPunitplugins/");
+ $this->assertEquals('11111', $this->smarty->fetch('eval:{testblock}{/testblock|strlen}'));
+ }
+
+ /**
+ *
+ *
+ */
+ public function testBlockPluginRepeatModidier2()
+ {
+ $this->smarty->addPluginsDir(dirname(__FILE__) . "/PHPunitplugins/");
+ $this->assertEquals('11111', $this->smarty->fetch('eval:{testblock}{/testblock|strlen|default:""}'));
+ }
+}
+
+function myblockplugintest($params, $content, &$smarty_tpl, &$repeat)
+{
+ if (!$repeat) {
+ $output = str_replace('hello world', 'block test', $content);
+
+ return $output;
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BlockPlugin/PHPunitplugins/block.testblock.php b/tests/UnitTests/TemplateSource/TagTests/BlockPlugin/PHPunitplugins/block.testblock.php
new file mode 100644
index 00000000..8a0aac2a
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BlockPlugin/PHPunitplugins/block.testblock.php
@@ -0,0 +1,34 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test block default outout
+ */
+ public function testBlockDefault_000_1()
+ {
+ $result = $this->smarty->fetch('string:{block name=test}-- block default --{/block}');
+ $this->assertEquals('-- block default --', $result);
+ }
+
+ public function testBlockDefault_000_2()
+ {
+ $this->smarty->assign('foo', 'another');
+ $result = $this->smarty->fetch('string:{block name=test}-- {$foo} block default --{/block}');
+ $this->assertEquals('-- another block default --', $result);
+ }
+
+ /**
+ * test just call of parent template, no blocks predefined
+ */
+ public function testCompileBlockParent_001()
+ {
+ $result = $this->smarty->fetch('001_parent.tpl');
+ $this->assertContains('Default Title', $result);
+ }
+
+ /**
+ * test child/parent template chain
+ */
+ public function testCompileBlockChild_002()
+ {
+ $result = $this->smarty->fetch('002_child.tpl');
+ $this->assertContains('Page Title', $result);
+ }
+
+ /**
+ * test child/parent template chain with prepend
+ */
+ public function testCompileBlockChildPrepend_003()
+ {
+ $result = $this->smarty->fetch('003_child_prepend.tpl');
+ $this->assertContains("prepend - Default Title", $result);
+ }
+
+ /**
+ * test child/parent template chain with apppend
+ */
+ public function testCompileBlockChildAppend_004()
+ {
+ $result = $this->smarty->fetch('004_child_append.tpl');
+ $this->assertContains("Default Title - append", $result);
+ }
+
+ /**
+ * test child/parent template chain with apppend and shorttags
+ */
+ public function testCompileBlockChildAppendShortag_005()
+ {
+ $result = $this->smarty->fetch('005_child_append_shorttag.tpl');
+ $this->assertContains("Default Title - append", $result);
+ }
+
+ /**
+ * test child/parent template chain with {$this->smarty.block.child)
+ */
+ public function testCompileBlockChildSmartyChild_006()
+ {
+ $result = $this->smarty->fetch('006_child_smartychild.tpl');
+ $this->assertContains('here is >child text< included', $result);
+ }
+
+ /**
+ * test child/parent template chain with {$this->smarty.block.parent)
+ */
+ public function testCompileBlockChildSmartyParent_007()
+ {
+ $result = $this->smarty->fetch('007_child_smartyparent.tpl');
+ $this->assertContains('parent block Default Title is here', $result);
+ }
+
+ /**
+ * test child/parent template chain loading plugin
+ */
+ public function testCompileBlockChildPlugin_008()
+ {
+ $result = $this->smarty->fetch('008_child_plugin.tpl');
+ $this->assertContains('escaped <text>', $result);
+ }
+
+ /**
+ * test parent template with nested blocks
+ */
+ public function testCompileBlockParentNested_009()
+ {
+ $result = $this->smarty->fetch('009_parent_nested.tpl');
+ $this->assertContains('Title with -default- here', $result);
+ }
+
+ /**
+ * test child/parent template chain with nested block
+ */
+ public function testCompileBlockChildNested_010()
+ {
+ $result = $this->smarty->fetch('010_child_nested.tpl');
+ $this->assertContains('Title with -content from child- here', $result);
+ }
+
+ /**
+ * test child/parent template chain with nested block and include
+ */
+ public function testCompileBlockChildNestedInclude_011()
+ {
+ $result = $this->smarty->fetch('011_grandchild_nested_include.tpl');
+ $this->assertContains('hello world', $result);
+ }
+
+ /**
+ * test grandchild/child/parent template chain
+ */
+ public function testCompileBlockGrandChild_012()
+ {
+ $result = $this->smarty->fetch('012_grandchild.tpl');
+ $this->assertContains('Grandchild Page Title', $result);
+ }
+
+ /**
+ * test grandchild/child/parent template chain prepend
+ */
+ public function testCompileBlockGrandChildPrepend_013()
+ {
+ $result = $this->smarty->fetch('013_grandchild_prepend.tpl');
+ $this->assertContains('grandchild prepend - Page Title', $result);
+ }
+
+ /**
+ * test grandchild/child/parent template chain with {$this->smarty.block.child}
+ */
+ public function testCompileBlockGrandChildSmartyChild_014()
+ {
+ $result = $this->smarty->fetch('014_grandchild_smartychild.tpl');
+ $this->assertContains('child title with - grandchild content - here', $result);
+ }
+
+ /**
+ * test grandchild/child/parent template chain append
+ */
+ public function testCompileBlockGrandChildAppend_015()
+ {
+ $result = $this->smarty->fetch('015_grandchild_append.tpl');
+ $this->assertContains('Page Title - grandchild append', $result);
+ }
+
+ /**
+ * test grandchild/child/parent template chain with nested block
+ */
+ public function testCompileBlockGrandChildNested_016()
+ {
+ $result = $this->smarty->fetch('016_grandchild_nested.tpl');
+ $this->assertContains('child title with -grandchild content- here', $result);
+ }
+
+ /**
+ * test grandchild/child/parent template chain with nested {$this->smarty.block.child}
+ */
+ public function testCompileBlockGrandChildNested_017()
+ {
+ $result = $this->smarty->fetch('017_grandchild_nested.tpl');
+ $this->assertContains('child pre -grandchild content- child post', $result);
+ }
+
+ /**
+ * test nested child block with hide
+ */
+ public function testCompileBlockChildNestedHide_018()
+ {
+ $result = $this->smarty->fetch('018_child_nested_hide.tpl');
+ $this->assertContains('nested block', $result);
+ $this->assertNotContains('should be hidden', $result);
+ }
+
+ /**
+ * test child/parent template chain starting in subtempates
+ */
+ public function testCompileBlockStartSubTemplates_020()
+ {
+ $result = $this->smarty->fetch('020_include_root.tpl');
+ $this->assertContains('page 1', $result);
+ $this->assertContains('page 2', $result);
+ $this->assertContains('page 3', $result);
+ $this->assertContains('block 1', $result);
+ $this->assertContains('block 2', $result);
+ $this->assertContains('block 3', $result);
+ }
+
+ /**
+ * test grandchild/child/parent dependency test1
+ */
+ public function testCompileBlockGrandChildMustCompile_021_1()
+ {
+ $this->cleanDirs();
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('021_grandchild.tpl');
+ $this->assertFalse($tpl->isCached());
+ $result = $this->smarty->fetch($tpl);
+ $this->assertContains('Grandchild Page Title', $result);
+ $this->smarty->template_objects = null;
+ $tpl2 = $this->smarty->createTemplate('021_grandchild.tpl');
+ $this->assertTrue($tpl2->isCached());
+ $result = $this->smarty->fetch($tpl2);
+ $this->assertContains('Grandchild Page Title', $result);
+ }
+
+ /**
+ * test grandchild/child/parent dependency test2
+ *
+ */
+ public function testCompileBlockGrandChildMustCompile_021_2()
+ {
+ sleep(2);
+ touch($this->smarty->getTemplateDir(0) . '021_grandchild.tpl');
+ clearstatcache();
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('021_grandchild.tpl');
+ $this->assertFalse($tpl->isCached());
+ $result = $this->smarty->fetch($tpl);
+ $this->assertContains('Grandchild Page Title', $result);
+ $this->smarty->template_objects = null;
+ $tpl2 = $this->smarty->createTemplate('021_grandchild.tpl');
+ $this->assertTrue($tpl2->isCached());
+ $result = $this->smarty->fetch($tpl2);
+ $this->assertContains('Grandchild Page Title', $result);
+ }
+
+ /**
+ * test grandchild/child/parent dependency test3
+ *
+ */
+ public function testCompileBlockGrandChildMustCompile_021_3()
+ {
+ sleep(2);
+ touch($this->smarty->getTemplateDir(0) . '021_child.tpl');
+ clearstatcache();
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('021_grandchild.tpl');
+ $this->assertFalse($tpl->isCached());
+ $result = $this->smarty->fetch($tpl);
+ $this->assertContains('Grandchild Page Title', $result);
+ $this->smarty->template_objects = null;
+ $tpl2 = $this->smarty->createTemplate('021_grandchild.tpl');
+ $this->assertTrue($tpl2->isCached());
+ $result = $this->smarty->fetch($tpl2);
+ $this->assertContains('Grandchild Page Title', $result);
+ }
+
+ /**
+ * test grandchild/child/parent dependency test4
+ *
+ */
+ public function testCompileBlockGrandChildMustCompile_021_4()
+ {
+ sleep(2);
+ touch($this->smarty->getTemplateDir(0) . '021_parent.tpl');
+ clearstatcache();
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('021_grandchild.tpl');
+ $this->assertFalse($tpl->isCached());
+ $result = $this->smarty->fetch($tpl);
+ $this->assertContains('Grandchild Page Title', $result);
+ $this->smarty->template_objects = null;
+ $tpl2 = $this->smarty->createTemplate('021_grandchild.tpl');
+ $this->assertTrue($tpl2->isCached());
+ $result = $this->smarty->fetch($tpl2);
+ $this->assertContains('Grandchild Page Title', $result);
+ }
+
+ /**
+ * test dirt in child templates
+ */
+ public function testDirt_022()
+ {
+ $result = $this->smarty->fetch('022_child.tpl');
+ $this->assertEquals('Page Title', $result);
+ }
+
+ /**
+ * test {$this->smarty.block.child} for not existing child {block]
+ */
+ public function testNotExistingChildBlock_024()
+ {
+ $result = $this->smarty->fetch('024_parent.tpl');
+ $this->assertContains('no >< child', $result);
+ }
+
+ /**
+ * @expectedException SmartyCompilerException
+ * @expectedExceptionMessage Syntax Error in template ".\templates\025_parent.tpl"
+ * @expectedExceptionMessage {$smarty.block.child} used out of context
+ * test {$this->smarty.block.child} outside {block]
+ */
+ public function testSmartyBlockChildOutsideBlock_025()
+ {
+ $this->smarty->fetch('025_parent.tpl');
+ }
+
+ /**
+ * @expectedException SmartyCompilerException
+ * @expectedExceptionMessage Syntax Error in template ".\templates\026_parent.tpl"
+ * @expectedExceptionMessage $smarty.block is invalid
+ * test {$this->smarty.block.parent} outside {block]
+ */
+ public function testSmartyBlockParentOutsideBlock_026()
+ {
+ $this->smarty->fetch('026_parent.tpl');
+ }
+
+ /**
+ * @expectedException SmartyCompilerException
+ * @expectedExceptionMessage Syntax Error in template ".\templates\027_parent.tpl"
+ * @expectedExceptionMessage $smarty.block is invalid
+ * test {$this->smarty.block.parent} in parent template
+ */
+ public function testSmartyBlockParentInParent_027()
+ {
+ $result = $this->smarty->fetch('027_parent.tpl');
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/001_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/001_parent.tpl
new file mode 100644
index 00000000..e007864b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/001_parent.tpl
@@ -0,0 +1 @@
+{block name='title'}Default Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/002_child.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/002_child.tpl
new file mode 100644
index 00000000..bac2cf93
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/002_child.tpl
@@ -0,0 +1,2 @@
+{extends file='002_parent.tpl'}
+{block name='title'}Page Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/002_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/002_parent.tpl
new file mode 100644
index 00000000..e007864b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/002_parent.tpl
@@ -0,0 +1 @@
+{block name='title'}Default Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/003_child_prepend.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/003_child_prepend.tpl
new file mode 100644
index 00000000..81acb6d7
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/003_child_prepend.tpl
@@ -0,0 +1,2 @@
+{extends file='003_parent.tpl'}
+{block name='title' prepend}prepend - {/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/003_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/003_parent.tpl
new file mode 100644
index 00000000..e007864b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/003_parent.tpl
@@ -0,0 +1 @@
+{block name='title'}Default Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/004_child_append.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/004_child_append.tpl
new file mode 100644
index 00000000..d6dd84c0
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/004_child_append.tpl
@@ -0,0 +1,2 @@
+{extends file='004_parent.tpl'}
+{block name='title' append} - append{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/004_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/004_parent.tpl
new file mode 100644
index 00000000..e007864b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/004_parent.tpl
@@ -0,0 +1 @@
+{block name='title'}Default Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/005_child_append_shorttag.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/005_child_append_shorttag.tpl
new file mode 100644
index 00000000..3aac9add
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/005_child_append_shorttag.tpl
@@ -0,0 +1,2 @@
+{extends file='005_parent_shorttag.tpl'}
+{block 'title' append} - append{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/005_parent_shorttag.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/005_parent_shorttag.tpl
new file mode 100644
index 00000000..46b6eef0
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/005_parent_shorttag.tpl
@@ -0,0 +1 @@
+
{block 'title'}Default Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/006_child_smartychild.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/006_child_smartychild.tpl
new file mode 100644
index 00000000..ba550f03
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/006_child_smartychild.tpl
@@ -0,0 +1,3 @@
+{extends file='006_parent_smartychild.tpl'}
+{block name='title'}child text{/block}
+
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/006_parent_smartychild.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/006_parent_smartychild.tpl
new file mode 100644
index 00000000..674a693b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/006_parent_smartychild.tpl
@@ -0,0 +1 @@
+{block name='title'}here is >{$smarty.block.child}< included{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/007_child_smartyparent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/007_child_smartyparent.tpl
new file mode 100644
index 00000000..41b6e27f
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/007_child_smartyparent.tpl
@@ -0,0 +1,2 @@
+{extends file='007_parent.tpl'}
+{block name='title'}parent block {$smarty.block.parent} is here{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/007_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/007_parent.tpl
new file mode 100644
index 00000000..e007864b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/007_parent.tpl
@@ -0,0 +1 @@
+{block name='title'}Default Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/008_child_plugin.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/008_child_plugin.tpl
new file mode 100644
index 00000000..c846670a
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/008_child_plugin.tpl
@@ -0,0 +1,2 @@
+{extends file='008_parent.tpl'}
+{block name='title'}{'escaped '|escape}{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/008_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/008_parent.tpl
new file mode 100644
index 00000000..e007864b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/008_parent.tpl
@@ -0,0 +1 @@
+{block name='title'}Default Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/009_parent_nested.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/009_parent_nested.tpl
new file mode 100644
index 00000000..cf08ca02
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/009_parent_nested.tpl
@@ -0,0 +1 @@
+{block name='title'}Title with {block name='title_content'}-default-{/block} here{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/010_child_nested.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/010_child_nested.tpl
new file mode 100644
index 00000000..5055bd51
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/010_child_nested.tpl
@@ -0,0 +1,2 @@
+{extends file='010_parent_nested.tpl'}
+{block name='title_content'}-content from child-{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/010_parent_nested.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/010_parent_nested.tpl
new file mode 100644
index 00000000..cf08ca02
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/010_parent_nested.tpl
@@ -0,0 +1 @@
+{block name='title'}Title with {block name='title_content'}-default-{/block} here{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/011_child_nested_include.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/011_child_nested_include.tpl
new file mode 100644
index 00000000..148887bb
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/011_child_nested_include.tpl
@@ -0,0 +1,4 @@
+{extends file='011_parent_nested_include.tpl'}
+{block name='body'}
+ {block name='title_content'}{block name='nested'}{include file='helloworld.tpl'}{/block}{/block}
+{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/011_grandchild_nested_include.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/011_grandchild_nested_include.tpl
new file mode 100644
index 00000000..1935b241
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/011_grandchild_nested_include.tpl
@@ -0,0 +1,2 @@
+{extends file='011_child_nested_include.tpl'}
+{block name='title_content' append} some content {/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/011_parent_nested_include.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/011_parent_nested_include.tpl
new file mode 100644
index 00000000..98f212e2
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/011_parent_nested_include.tpl
@@ -0,0 +1 @@
+{block name='body'}-default-{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/012_child.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/012_child.tpl
new file mode 100644
index 00000000..bac2cf93
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/012_child.tpl
@@ -0,0 +1,2 @@
+{extends file='002_parent.tpl'}
+{block name='title'}Page Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/012_grandchild.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/012_grandchild.tpl
new file mode 100644
index 00000000..c485967a
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/012_grandchild.tpl
@@ -0,0 +1,2 @@
+{extends file='012_child.tpl'}
+{block name='title'}Grandchild Page Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/012_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/012_parent.tpl
new file mode 100644
index 00000000..e007864b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/012_parent.tpl
@@ -0,0 +1 @@
+{block name='title'}Default Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/013_child.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/013_child.tpl
new file mode 100644
index 00000000..bac2cf93
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/013_child.tpl
@@ -0,0 +1,2 @@
+{extends file='002_parent.tpl'}
+{block name='title'}Page Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/013_grandchild_prepend.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/013_grandchild_prepend.tpl
new file mode 100644
index 00000000..b78367fd
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/013_grandchild_prepend.tpl
@@ -0,0 +1,2 @@
+{extends file='013_child.tpl'}
+{block name='title' prepend}grandchild prepend - {/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/013_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/013_parent.tpl
new file mode 100644
index 00000000..e007864b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/013_parent.tpl
@@ -0,0 +1 @@
+{block name='title'}Default Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/014_child_smartychild.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/014_child_smartychild.tpl
new file mode 100644
index 00000000..521b0f67
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/014_child_smartychild.tpl
@@ -0,0 +1,2 @@
+{extends file='014_parent.tpl'}
+{block name='title'}child title with - {$smarty.block.child} - here{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/014_grandchild_smartychild.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/014_grandchild_smartychild.tpl
new file mode 100644
index 00000000..d617aaa5
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/014_grandchild_smartychild.tpl
@@ -0,0 +1,2 @@
+{extends file='014_child_smartychild.tpl'}
+{block name='title'}grandchild content{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/014_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/014_parent.tpl
new file mode 100644
index 00000000..e007864b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/014_parent.tpl
@@ -0,0 +1 @@
+{block name='title'}Default Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/015_child.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/015_child.tpl
new file mode 100644
index 00000000..7bd02fa9
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/015_child.tpl
@@ -0,0 +1,2 @@
+{extends file='015_parent.tpl'}
+{block name='title'}Page Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/015_grandchild_append.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/015_grandchild_append.tpl
new file mode 100644
index 00000000..46e912ff
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/015_grandchild_append.tpl
@@ -0,0 +1,2 @@
+{extends file='015_child.tpl'}
+{block name='title' append} - grandchild append{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/015_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/015_parent.tpl
new file mode 100644
index 00000000..e007864b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/015_parent.tpl
@@ -0,0 +1 @@
+{block name='title'}Default Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/016_child_nested.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/016_child_nested.tpl
new file mode 100644
index 00000000..14ffb077
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/016_child_nested.tpl
@@ -0,0 +1,2 @@
+{extends file='016_parent.tpl'}
+{block name='title'}child title with {block name='title_content'}-default-{/block} here{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/016_grandchild_nested.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/016_grandchild_nested.tpl
new file mode 100644
index 00000000..3f4970a5
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/016_grandchild_nested.tpl
@@ -0,0 +1,2 @@
+{extends file='016_child_nested.tpl'}
+{block name='title_content'}-grandchild content-{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/016_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/016_parent.tpl
new file mode 100644
index 00000000..03ddb708
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/016_parent.tpl
@@ -0,0 +1 @@
+{block name='title'}Default Title{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/017_child_nested.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/017_child_nested.tpl
new file mode 100644
index 00000000..d8af5c6d
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/017_child_nested.tpl
@@ -0,0 +1,6 @@
+{extends file='017_parent.tpl'}
+{block name='content1'}
+ {block name='content2'}
+ child pre {$smarty.block.child} child post
+ {/block}
+{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/017_grandchild_nested.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/017_grandchild_nested.tpl
new file mode 100644
index 00000000..9d63a077
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/017_grandchild_nested.tpl
@@ -0,0 +1,2 @@
+{extends file='017_child_nested.tpl'}
+{block name='content2'}-grandchild content-{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/017_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/017_parent.tpl
new file mode 100644
index 00000000..34d9deda
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/017_parent.tpl
@@ -0,0 +1 @@
+{block name='content1'}Default content{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/018_child_nested_hide.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/018_child_nested_hide.tpl
new file mode 100644
index 00000000..bf662b74
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/018_child_nested_hide.tpl
@@ -0,0 +1,12 @@
+{extends file="018_parent_nested.tpl"}
+
+{block name="index"}
+ {block name="test2"}
+ nested block.
+ {$smarty.block.child}
+ {/block}
+ {block name="test" hide}
+ I should be hidden.
+ {$smarty.block.child}
+ {/block}
+{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/018_parent_nested.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/018_parent_nested.tpl
new file mode 100644
index 00000000..b778c3a1
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/018_parent_nested.tpl
@@ -0,0 +1 @@
+{block name='index'}{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/019_child_nested_hide_autoliteral.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/019_child_nested_hide_autoliteral.tpl
new file mode 100644
index 00000000..94a29a52
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/019_child_nested_hide_autoliteral.tpl
@@ -0,0 +1,12 @@
+{ extends file="019_parent.tpl" }
+
+{ block name="index" }
+{ block name="test2" }
+nested block.
+{ $smarty.block.child }
+{ /block }
+{ block name="test" hide }
+I should be hidden.
+{ $smarty.block.child }
+{ /block }
+{ /block }
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/019_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/019_parent.tpl
new file mode 100644
index 00000000..b778c3a1
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/019_parent.tpl
@@ -0,0 +1 @@
+{block name='index'}{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_1.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_1.tpl
new file mode 100644
index 00000000..96cb96ca
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_1.tpl
@@ -0,0 +1,5 @@
+{extends file='020_include_parent.tpl'}
+
+{block name="p"}page 1
{/block}
+
+{block name="b"}block 1
{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_2.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_2.tpl
new file mode 100644
index 00000000..4a0115f8
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_2.tpl
@@ -0,0 +1,5 @@
+{extends file='020_include_parent.tpl'}
+
+{block name="p"}page 2
{/block}
+
+{block name="b"}block 2
{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_3.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_3.tpl
new file mode 100644
index 00000000..fbf6a5ad
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_3.tpl
@@ -0,0 +1,5 @@
+{extends file='020_include_parent.tpl'}
+
+{block name="p"}page 3
{/block}
+
+{block name="b"}block 3
{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_parent.tpl
new file mode 100644
index 00000000..eedca930
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_parent.tpl
@@ -0,0 +1,4 @@
+{block name="p"} {/block}
+{block name='dummy'}
+ {include file='020_include_subtemplate.tpl'}
+{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_root.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_root.tpl
new file mode 100644
index 00000000..bc0c3119
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_root.tpl
@@ -0,0 +1,4 @@
+{include file='020_include_1.tpl'}
+{include file='020_include_2.tpl'}
+{include file='020_include_3.tpl'}
+
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_subtemplate.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_subtemplate.tpl
new file mode 100644
index 00000000..21a4d317
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/020_include_subtemplate.tpl
@@ -0,0 +1 @@
+{block name="b"}-dummy-{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/021_child.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/021_child.tpl
new file mode 100644
index 00000000..0bb2dd56
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/021_child.tpl
@@ -0,0 +1,2 @@
+{extends file='021_parent.tpl'}
+{block name='title'}Page Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/021_grandchild.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/021_grandchild.tpl
new file mode 100644
index 00000000..a700a046
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/021_grandchild.tpl
@@ -0,0 +1,2 @@
+{extends file='021_child.tpl'}
+{block name='title'}Grandchild Page Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/021_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/021_parent.tpl
new file mode 100644
index 00000000..e007864b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/021_parent.tpl
@@ -0,0 +1 @@
+{block name='title'}Default Title{/block}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/022_child.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/022_child.tpl
new file mode 100644
index 00000000..305d805b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/022_child.tpl
@@ -0,0 +1,4 @@
+{extends file='022_parent.tpl'}
+{block name='title'}Page Title{/block}
+
+
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/022_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/022_parent.tpl
new file mode 100644
index 00000000..b5ba7602
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/022_parent.tpl
@@ -0,0 +1 @@
+{block name='title'}{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/023_child.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/023_child.tpl
new file mode 100644
index 00000000..69f554f9
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/023_child.tpl
@@ -0,0 +1,8 @@
+{extends file="023_parent.tpl"}
+{strip}
+ {block name="strip"}
+
+ Demo
+
+ {/block}
+{/strip}
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/023_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/023_parent.tpl
new file mode 100644
index 00000000..028e456f
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/023_parent.tpl
@@ -0,0 +1,9 @@
+{strip}
+
+{/strip}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/024_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/024_parent.tpl
new file mode 100644
index 00000000..ba6d010b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/024_parent.tpl
@@ -0,0 +1 @@
+{block 'b1'}no >{$smarty.block.child}< child{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/025_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/025_parent.tpl
new file mode 100644
index 00000000..345cff01
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/025_parent.tpl
@@ -0,0 +1 @@
+{$smarty.block.child}{block 'b1'}{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/026_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/026_parent.tpl
new file mode 100644
index 00000000..d046a177
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/026_parent.tpl
@@ -0,0 +1 @@
+{$smarty.block.parent}{block 'b1'}{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/027_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/027_parent.tpl
new file mode 100644
index 00000000..580bc737
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/027_parent.tpl
@@ -0,0 +1 @@
+{block 'b1'}this {$smarty.block.parent} is illegal{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/028_child.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/028_child.tpl
new file mode 100644
index 00000000..ccfca614
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/028_child.tpl
@@ -0,0 +1,4 @@
+{extends '028_parent.tpl'}
+{block 'i2'}-i2-{/block}
+{block 'n1'}-1-{/block}
+{block 'n2'}-2-{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/028_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/028_parent.tpl
new file mode 100644
index 00000000..ab2e31ff
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/028_parent.tpl
@@ -0,0 +1 @@
+{block 'b1'}b1-{include $foo}-b1{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/028_parent_include1.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/028_parent_include1.tpl
new file mode 100644
index 00000000..0e21a57d
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/028_parent_include1.tpl
@@ -0,0 +1 @@
+{block 'i1'}include{block 'n1'}{/block}{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/028_parent_include2.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/028_parent_include2.tpl
new file mode 100644
index 00000000..27ce8563
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/028_parent_include2.tpl
@@ -0,0 +1 @@
+{block 'i2'}child{$smarty.block.child}include{block 'n2'}{/block}{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/029_child.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/029_child.tpl
new file mode 100644
index 00000000..671c92cc
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/029_child.tpl
@@ -0,0 +1,4 @@
+{extends $foo}
+
+{block 'p2'}2{/block}
+{block 'p1'}1{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/029_parent.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/029_parent.tpl
new file mode 100644
index 00000000..cd6579dc
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/029_parent.tpl
@@ -0,0 +1 @@
+{block 'b1'}parent{block 'p1'}{/block}{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/029_parent2.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/029_parent2.tpl
new file mode 100644
index 00000000..4ec5d97f
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/029_parent2.tpl
@@ -0,0 +1 @@
+{block 'b1'}parent{block 'p2'}{/block}{/block}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/helloworld.tpl b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/helloworld.tpl
new file mode 100644
index 00000000..95d09f2b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/BockExtend/templates/helloworld.tpl
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Capture/CompileCaptureTest.php b/tests/UnitTests/TemplateSource/TagTests/Capture/CompileCaptureTest.php
new file mode 100644
index 00000000..da1f5b47
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Capture/CompileCaptureTest.php
@@ -0,0 +1,100 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test capture tag
+ */
+ public function testCapture1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{capture assign=foo}hello world{/capture}');
+ $this->assertEquals("", $this->smarty->fetch($tpl));
+ }
+
+ public function testCapture2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=bar}{capture assign=foo}hello world{/capture}{$foo}');
+ $this->assertEquals("hello world", $this->smarty->fetch($tpl));
+ }
+
+ public function testCapture3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{capture name=foo}hello world{/capture}{$smarty.capture.foo}');
+ $this->assertEquals("hello world", $this->smarty->fetch($tpl));
+ }
+
+ public function testCapture4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{capture name=foo assign=bar}hello world{/capture}{$smarty.capture.foo} {$bar}');
+ $this->assertEquals("hello world hello world", $this->smarty->fetch($tpl));
+ }
+
+ public function testCapture5()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{capture}hello world{/capture}{$smarty.capture.default}');
+ $this->assertEquals("hello world", $this->smarty->fetch($tpl));
+ }
+
+ public function testCapture6()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{capture short}hello shorttag{/capture}{$smarty.capture.short}');
+ $this->assertEquals("hello shorttag", $this->smarty->fetch($tpl));
+ }
+
+ public function testCapture7()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{capture append=foo}hello{/capture}bar{capture append=foo}world{/capture}{foreach $foo item} {$item@key} {$item}{/foreach}');
+ $this->assertEquals("bar 0 hello 1 world", $this->smarty->fetch($tpl));
+ }
+
+ /*
+ * The following test has been disabled. It fails only in PHPunit
+ */
+ public function testCapture8()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{capture assign=foo}hello {capture assign=bar}this is my {/capture}world{/capture}{$foo} {$bar}');
+ $this->assertEquals("hello world this is my ", $this->smarty->fetch($tpl), 'This failure pops up only during PHPunit test ?????');
+ }
+
+ public function testCompileCaptureNocache1()
+ {
+ $this->smarty->assign('foo', 1);
+ $this->smarty->caching = 1;
+ $this->assertContains('foo 1', $this->smarty->fetch('test_capture_nocache.tpl'));
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testCompileCaptureNocache2()
+ {
+ $this->smarty->assign('foo', 2);
+ $this->smarty->caching = 1;
+ $this->assertTrue($this->smarty->isCached('test_capture_nocache.tpl'));
+ $this->assertContains('foo 2', $this->smarty->fetch('test_capture_nocache.tpl'));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/Capture/templates/test_capture_nocache.tpl b/tests/UnitTests/TemplateSource/TagTests/Capture/templates/test_capture_nocache.tpl
new file mode 100644
index 00000000..f34f731a
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Capture/templates/test_capture_nocache.tpl
@@ -0,0 +1,2 @@
+{capture assign=bar nocache}foo {$foo}{/capture}
+{$bar nocache}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/CompilerPlugin/CompilerPluginTest.php b/tests/UnitTests/TemplateSource/TagTests/CompilerPlugin/CompilerPluginTest.php
new file mode 100644
index 00000000..3b3541dd
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/CompilerPlugin/CompilerPluginTest.php
@@ -0,0 +1,34 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test compiler plugin
+ */
+ public function testCompilerPlugin()
+ {
+ $this->smarty->addPluginsDir(dirname(__FILE__) . "/PHPunitplugins/");
+ $this->assertEquals('test output', $this->smarty->fetch('eval:{test data="test output"}{/test}'));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/CompilerPlugin/PHPunitplugins/compiler.test.php b/tests/UnitTests/TemplateSource/TagTests/CompilerPlugin/PHPunitplugins/compiler.test.php
new file mode 100644
index 00000000..615e0413
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/CompilerPlugin/PHPunitplugins/compiler.test.php
@@ -0,0 +1,28 @@
+required_attributes = array('data');
+
+ $_attr = $this->getAttributes($compiler, $args);
+
+ $this->openTag($compiler, 'test');
+
+ return "";
+ }
+}
+
+// compiler.testclose.php
+class smarty_compiler_testclose extends Smarty_Internal_CompileBase
+{
+ public function compile($args, $compiler)
+ {
+
+ $this->closeTag($compiler, 'test');
+
+ return '';
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/CompilerPlugin/PHPunitplugins/compiler.testclose.php b/tests/UnitTests/TemplateSource/TagTests/CompilerPlugin/PHPunitplugins/compiler.testclose.php
new file mode 100644
index 00000000..bd751f06
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/CompilerPlugin/PHPunitplugins/compiler.testclose.php
@@ -0,0 +1,13 @@
+closeTag($compiler, 'test');
+
+ return '';
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/ConfigLoad/CompileConfigLoadTest.php b/tests/UnitTests/TemplateSource/TagTests/ConfigLoad/CompileConfigLoadTest.php
new file mode 100644
index 00000000..7883645f
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/ConfigLoad/CompileConfigLoadTest.php
@@ -0,0 +1,170 @@
+setUpSmarty(__DIR__);
+ }
+
+ /**
+ * empty templat_c and cache folders
+ */
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test {load_config} loading section2
+ */
+ public function testConfigVariableSection2Template()
+ {
+ $this->assertEquals("Welcome to Smarty! Global Section1 Hello Section2", $this->smarty->fetch('eval:{config_load file=\'test.conf\' section=\'section2\'}{#title#} {#sec1#} {#sec2#}'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ * test {load_config} loading section2 shorttags
+ */
+ public function testConfigVariableSection2TemplateShorttags()
+ {
+ $this->assertEquals("Welcome to Smarty! Global Section1 Hello Section2", $this->smarty->fetch('eval:{config_load \'test.conf\' \'section2\'}{#title#} {#sec1#} {#sec2#}'));
+ }
+
+ /**
+ * test config varibales loading local
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigVariableLocal()
+ {
+ $this->assertEquals("Welcome to Smarty!", $this->smarty->fetch('eval:{config_load file=\'test.conf\' scope=\'local\'}{#title#}'));
+ // global must be empty
+ $this->assertEquals("", $this->smarty->getConfigVars('title'));
+ }
+
+ /**
+ * test config varibales loading parent
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigVariableParent()
+ {
+ $this->assertEquals("Welcome to Smarty!", $this->smarty->fetch('eval:{config_load file=\'test.conf\' scope=\'parent\'}{#title#}'));
+ // global is parent must not be empty
+ $this->assertEquals("Welcome to Smarty!", $this->smarty->getConfigVars('title'));
+ }
+
+ /**
+ * test config varibales loading global
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigVariableGlobal()
+ {
+ $this->assertEquals("Welcome to Smarty!", $this->smarty->fetch('eval:{config_load file=\'test.conf\' scope=\'global\'}{#title#}'));
+ // global is parent must not be empty
+ $this->assertEquals("Welcome to Smarty!", $this->smarty->getConfigVars('title'));
+ }
+
+
+ /**
+ * test config varibales loading all sections from template
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigVariableAllSectionsTemplate()
+ {
+ $this->smarty->setConfigOverwrite(true);
+ $this->assertEquals("Welcome to Smarty! Global Section1 Global Section2", $this->smarty->fetch('eval:{config_load file=\'test.conf\'}{#title#} {#sec1#} {#sec2#}'));
+ }
+
+ /**
+ * test config varibales overwrite
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigVariableOverwrite()
+ {
+ $this->assertEquals("Overwrite2", $this->smarty->fetch('eval:{config_load file=\'test.conf\'}{#overwrite#}'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigVariableOverwrite2()
+ {
+ $this->assertEquals("Overwrite3", $this->smarty->fetch('eval:{config_load file=\'test.conf\'}{config_load file=\'test2.conf\'}{#overwrite#}'));
+ }
+
+ /**
+ * test config varibales overwrite false
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigVariableOverwriteFalse()
+ {
+ $this->smarty->setConfigOverwrite(false);
+ $this->assertEquals("Overwrite1Overwrite2Overwrite3Welcome to Smarty! Global Section1 Global Section2", $this->smarty->fetch('eval:{config_load file=\'test.conf\'}{config_load file=\'test2.conf\'}{foreach #overwrite# as $over}{$over}{/foreach}{#title#} {#sec1#} {#sec2#}'));
+ }
+
+ /**
+ * test config varibales booleanize on
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigVariableBooleanizeOn()
+ {
+ $this->smarty->setConfigBooleanize(true);
+ $this->assertEquals("passed", $this->smarty->fetch('eval:{config_load file=\'test.conf\'}{if #booleanon# === true}passed{/if}'));
+ }
+
+ /**
+ * test config varibales booleanize off
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testConfigVariableBooleanizeOff()
+ {
+ $this->smarty->setConfigBooleanize(false);
+ $this->assertEquals("passed", $this->smarty->fetch('eval:{config_load file=\'test.conf\'}{if #booleanon# == \'on\'}passed{/if}'));
+ }
+
+ /**
+ * @expectedException SmartyCompilerException
+ * @expectedExceptionMessage Syntax error in config file
+ * test config file syntax error
+ */
+ public function testConfigSyntaxError()
+ {
+ $this->smarty->fetch('eval:{config_load file=\'test_error.conf\'}');
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/ConfigLoad/configs/test.conf b/tests/UnitTests/TemplateSource/TagTests/ConfigLoad/configs/test.conf
new file mode 100644
index 00000000..9bd1731c
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/ConfigLoad/configs/test.conf
@@ -0,0 +1,49 @@
+title = Welcome to Smarty!
+
+overwrite = Overwrite1
+overwrite = Overwrite2
+
+booleanon = on
+
+Intro = """This is a value that spans more
+ than one line. you must enclose
+ it in triple quotes."""
+
+Number = 123.4
+
+text = 123bvc
+
+line = 123 This is a line
+
+sec1 = Global Section1
+
+sec2 = Global Section2
+
+sec = Global char
+[/]
+sec = special char
+
+[foo/bar]
+sec = section foo/bar
+
+[section1]
+sec1 = Hello Section1
+
+[section2]
+sec2 = 'Hello Section2'
+
+[.hidden]
+hiddentext = Hidden Section
+
+#Comment
+# Comment with a space first line first
+ #Comment line starting with space
+ # Space before and after #
+#The line below only contains a #
+#
+#
+# title = This is not the correct title
+
+#[section1]
+#sec1 = Wrong text
+
diff --git a/tests/UnitTests/TemplateSource/TagTests/ConfigLoad/configs/test2.conf b/tests/UnitTests/TemplateSource/TagTests/ConfigLoad/configs/test2.conf
new file mode 100644
index 00000000..26578eee
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/ConfigLoad/configs/test2.conf
@@ -0,0 +1,2 @@
+
+overwrite = Overwrite3
diff --git a/tests/UnitTests/TemplateSource/TagTests/ConfigLoad/configs/test_error.conf b/tests/UnitTests/TemplateSource/TagTests/ConfigLoad/configs/test_error.conf
new file mode 100644
index 00000000..586e0c75
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/ConfigLoad/configs/test_error.conf
@@ -0,0 +1,15 @@
+title = Welcome to Smarty!
+
+overwrite = Overwrite1
+overwrite = Overwrite2
+
+[section1=]]
+# Here is an error
+sec1 = "Hello Section1"
+
+[section2]
+sec2 = 'Hello Section2'
+
+[.hidden]
+hiddentext = Hidden Section
+
diff --git a/tests/UnitTests/TemplateSource/TagTests/Delimiter/CompileDelimiterTest.php b/tests/UnitTests/TemplateSource/TagTests/Delimiter/CompileDelimiterTest.php
new file mode 100644
index 00000000..5341cce8
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Delimiter/CompileDelimiterTest.php
@@ -0,0 +1,40 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test delimiter tag test
+ */
+ public function testLeftDelimiter()
+ {
+ $tpl = $this->smarty->createTemplate('eval:x{ldelim}x');
+ $this->assertEquals('x{x', $this->smarty->fetch($tpl));
+ }
+
+ public function testRightDelimiter()
+ {
+ $tpl = $this->smarty->createTemplate('eval:x{rdelim}x');
+ $this->assertEquals('x}x', $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/Eval/CompileEvalTest.php b/tests/UnitTests/TemplateSource/TagTests/Eval/CompileEvalTest.php
new file mode 100644
index 00000000..b553a5cf
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Eval/CompileEvalTest.php
@@ -0,0 +1,46 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test eval tag
+ */
+ public function testEval1()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{eval var='hello world'}");
+ $this->assertEquals("hello world", $this->smarty->fetch($tpl));
+ }
+
+ public function testEval2()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{eval var='hello world' assign=foo}{\$foo}");
+ $this->assertEquals("hello world", $this->smarty->fetch($tpl));
+ }
+
+ public function testEval3()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{eval var='hello world' assign=foo}");
+ $this->assertEquals("", $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/For/CompileForTest.php b/tests/UnitTests/TemplateSource/TagTests/For/CompileForTest.php
new file mode 100644
index 00000000..47a2b777
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/For/CompileForTest.php
@@ -0,0 +1,188 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test {for $x=0;$x<10;$x++} tag
+ */
+ public function testFor1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{for $x=0;$x<10;$x++}{$x}{/for}');
+ $this->assertEquals("0123456789", $this->smarty->fetch($tpl));
+ }
+
+ public function testFor2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{for $x=0; $x<10; $x++}{$x}{forelse}else{/for}');
+ $this->assertEquals("0123456789", $this->smarty->fetch($tpl));
+ }
+
+ public function testFor3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{for $x=10;$x<10;$x++}{$x}{forelse}else{/for}');
+ $this->assertEquals("else", $this->smarty->fetch($tpl));
+ }
+
+ public function testFor4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{for $x=9;$x>=0;$x--}{$x}{forelse}else{/for}');
+ $this->assertEquals("9876543210", $this->smarty->fetch($tpl));
+ }
+
+ public function testFor5()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{for $x=-1;$x>=0;$x--}{$x}{forelse}else{/for}');
+ $this->assertEquals("else", $this->smarty->fetch($tpl));
+ }
+
+ public function testFor6()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{for $x=0,$y=10;$x<$y;$x++}{$x}{forelse}else{/for}');
+ $this->assertEquals("0123456789", $this->smarty->fetch($tpl));
+ }
+
+ public function testFor7()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{for $x=0;$x<10;$x=$x+2}{$x}{/for}');
+ $this->assertEquals("02468", $this->smarty->fetch($tpl));
+ }
+
+ public function testFor8()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{for $x=0 to 8}{$x}{/for}');
+ $this->assertEquals("012345678", $this->smarty->fetch($tpl));
+ }
+
+ public function testFor9()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{for $x=0 to 8 step=2}{$x}{/for}');
+ $this->assertEquals("02468", $this->smarty->fetch($tpl));
+ }
+
+ public function testFor10()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{for $x=0 to 8 step=2}{if $x@first}{$x} {$x@total}{/if}{/for}');
+ $this->assertEquals("0 5", $this->smarty->fetch($tpl));
+ }
+
+ public function testFor11()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{for $x=0 to 8 step=2}{if $x@last}{$x} {$x@iteration}{/if}{/for}');
+ $this->assertEquals("8 5", $this->smarty->fetch($tpl));
+ }
+
+ public function testFor12()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{for $x=8 to 0 step=-2}{$x}{/for}');
+ $this->assertEquals("86420", $this->smarty->fetch($tpl));
+ }
+
+ public function testFor13()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{for $x=8 to 0 step=2}{$x}{forelse}step error{/for}');
+ $this->assertEquals("step error", $this->smarty->fetch($tpl));
+ }
+
+ public function testFor14()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{for $x=8 to 0 step -1 max=3}{$x}{/for}');
+ $this->assertEquals("876", $this->smarty->fetch($tpl));
+ }
+
+ /*
+ * test for and nocache
+ */
+ public function testForNocacheVar1()
+ {
+ $this->smarty->caching = true;
+ $tpl = $this->smarty->createTemplate('string:{for $x=$foo to 5}{$x} {/for}');
+ $tpl->assign('foo', 1, true);
+ $this->assertFalse($this->smarty->isCached($tpl));
+ $this->assertEquals("1 2 3 4 5 ", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testForNocacheVar2()
+ {
+ $this->smarty->caching = true;
+ $tpl = $this->smarty->createTemplate('string:{for $x=$foo to 5}{$x} {/for}');
+ $tpl->assign('foo', 4, true);
+ $this->assertTrue($this->smarty->isCached($tpl));
+ $this->assertEquals("4 5 ", $this->smarty->fetch($tpl));
+ }
+
+ public function testForNocacheTag1()
+ {
+ $this->smarty->caching = true;
+ $tpl = $this->smarty->createTemplate('string:{for $x=$foo to 5 nocache}{$x} {/for}');
+ $tpl->assign('foo', 1);
+ $this->assertFalse($this->smarty->isCached($tpl));
+ $this->assertEquals("1 2 3 4 5 ", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testForNocacheTag2()
+ {
+ $this->smarty->caching = true;
+ $tpl = $this->smarty->createTemplate('string:{for $x=$foo to 5 nocache}{$x} {/for}');
+ $tpl->assign('foo', 4);
+ $this->assertTrue($this->smarty->isCached($tpl));
+ $this->assertEquals("4 5 ", $this->smarty->fetch($tpl));
+ }
+
+ public function testForCache1()
+ {
+ $this->smarty->caching = true;
+ $tpl = $this->smarty->createTemplate('string:{for $x=$foo to 2}{$x} {/for}');
+ $tpl->assign('foo', 1);
+ $this->assertFalse($this->smarty->isCached($tpl));
+ $this->assertEquals("1 2 ", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testForCache2()
+ {
+ $this->smarty->caching = true;
+ $tpl = $this->smarty->createTemplate('string:{for $x=$foo to 2}{$x} {/for}');
+ $tpl->assign('foo', 6);
+ $this->assertTrue($this->smarty->isCached($tpl));
+ $this->assertEquals("1 2 ", $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/Foreach/CompileForeachTest.php b/tests/UnitTests/TemplateSource/TagTests/Foreach/CompileForeachTest.php
new file mode 100644
index 00000000..0e754a54
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Foreach/CompileForeachTest.php
@@ -0,0 +1,246 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test {foreach} tag
+ */
+ public function testForeach()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=[0,1,2,3,4,5,6,7,8,9]}{foreach item=x from=$foo}{$x}{/foreach}');
+ $this->assertEquals("0123456789", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachBreak()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=[0,1,2,3,4,5,6,7,8,9]}{foreach item=x from=$foo}{if $x == 2}{break}{/if}{$x}{/foreach}');
+ $this->assertEquals("01", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachContinue()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=[0,1,2,3,4,5,6,7,8,9]}{foreach item=x from=$foo}{if $x == 2}{continue}{/if}{$x}{/foreach}');
+ $this->assertEquals("013456789", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachNotElse()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=[0,1,2,3,4,5,6,7,8,9]}{foreach item=x from=$foo}{$x}{foreachelse}else{/foreach}');
+ $this->assertEquals("0123456789", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachElse()
+ {
+ $this->smarty->setErrorReporting(error_reporting() & ~(E_NOTICE | E_USER_NOTICE));
+ $tpl = $this->smarty->createTemplate('eval:{foreach item=x from=$foo}{$x}{foreachelse}else{/foreach}');
+ $this->assertEquals("else", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachKey()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{foreach item=x key=y from=[9,8,7,6,5,4,3,2,1,0]}{$y}{$x}{foreachelse}else{/foreach}');
+ $this->assertEquals("09182736455463728190", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachKeyProperty()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{foreach item=x from=[9,8,7,6,5,4,3,2,1,0]}{$x@key}{$x}{foreachelse}else{/foreach}');
+ $this->assertEquals("09182736455463728190", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachTotal()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{foreach item=x name=foo from=[0,1,2,3,4,5,6,7,8,9]}{$x}{foreachelse}else{/foreach}total{$smarty.foreach.foo.total}');
+ $this->assertEquals("0123456789total10", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachTotalProperty()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{foreach item=x from=[0,1,2,3,4,5,6,7,8,9]}{$x}{foreachelse}else{/foreach}total{$x@total}');
+ $this->assertEquals("0123456789total10", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachIndexIteration()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{foreach item=x name=foo from=[0,1,2,3,4,5,6,7,8,9]}{$smarty.foreach.foo.index}{$smarty.foreach.foo.iteration}{foreachelse}else{/foreach}');
+ $this->assertEquals("011223344556677889910", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachIndexIterationProperty()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{foreach item=x from=[0,1,2,3,4,5,6,7,8,9]}{$x@index}{$x@iteration}{foreachelse}else{/foreach}');
+ $this->assertEquals("011223344556677889910", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachFirstLast()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{foreach item=x name=foo from=[0,1,2,3,4,5,6,7,8,9]}{if $smarty.foreach.foo.first}first{/if}{if $smarty.foreach.foo.last}last{/if}{$x}{foreachelse}else{/foreach}');
+ $this->assertEquals("first012345678last9", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachFirstLastProperty()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{foreach item=x name=foo from=[0,1,2,3,4,5,6,7,8,9]}{if $x@first}first{/if}{if $x@last}last{/if}{$x}{foreachelse}else{/foreach}');
+ $this->assertEquals("first012345678last9", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachShowTrue()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{foreach item=x name=foo from=[0,1]}{$x}{foreachelse}else{/foreach}{if $smarty.foreach.foo.show}show{else}noshow{/if}');
+ $this->assertEquals("01show", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachShowTrueProperty()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{foreach item=x name=foo from=[0,1]}{$x}{foreachelse}else{/foreach}{if $x@show}show{else}noshow{/if}');
+ $this->assertEquals("01show", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachShowFalse()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{foreach item=x name=foo from=[]}{$x}{foreachelse}else{/foreach}{if $smarty.foreach.foo.show}show{else} noshow{/if}');
+ $this->assertEquals("else noshow", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachShowFalseProperty()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{foreach item=x name=foo from=[]}{$x}{foreachelse}else{/foreach}{if $x@show}show{else} noshow{/if}');
+ $this->assertEquals("else noshow", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachShorttags()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{foreach [9,8,7,6,5,4,3,2,1,0] x y foo}{$y}{$x}{foreachelse}else{/foreach}total{$smarty.foreach.foo.total}');
+ $this->assertEquals("09182736455463728190total10", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test {foreach $foo as $x} tag
+ */
+ public function testNewForeach()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=[0,1,2,3,4,5,6,7,8,9]}{foreach $foo as $x}{$x}{/foreach}');
+ $this->assertEquals("0123456789", $this->smarty->fetch($tpl));
+ }
+
+ public function testNewForeachNotElse()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=[0,1,2,3,4,5,6,7,8,9]}{foreach $foo as $x}{$x}{foreachelse}else{/foreach}');
+ $this->assertEquals("0123456789", $this->smarty->fetch($tpl));
+ }
+
+ public function testNewForeachElse()
+ {
+ $this->smarty->setErrorReporting(error_reporting() & ~(E_NOTICE | E_USER_NOTICE));
+ $tpl = $this->smarty->createTemplate('eval:{foreach $foo as $x}{$x}{foreachelse}else{/foreach}');
+ $this->assertEquals("else", $this->smarty->fetch($tpl));
+ }
+
+ public function testNewForeachKey()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=[9,8,7,6,5,4,3,2,1,0]}{foreach $foo as $y=>$x}{$y}{$x}{foreachelse}else{/foreach}');
+ $this->assertEquals("09182736455463728190", $this->smarty->fetch($tpl));
+ }
+
+ public function testNewForeachKeyProperty()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=[9,8,7,6,5,4,3,2,1,0]}{foreach $foo as $x}{$x@key}{$x}{foreachelse}else{/foreach}');
+ $this->assertEquals("09182736455463728190", $this->smarty->fetch($tpl));
+ }
+
+ /*
+ * test foreach and nocache
+ */
+ public function testForeachNocacheVar1()
+ {
+ $this->smarty->caching = true;
+ $tpl = $this->smarty->createTemplate('string:{foreach $foo as $x}{$x} {/foreach}');
+ $tpl->assign('foo', array(1, 2), true);
+ $this->assertFalse($this->smarty->isCached($tpl));
+ $this->assertEquals("1 2 ", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testForeachNocacheVar2()
+ {
+ $this->smarty->caching = true;
+ $tpl = $this->smarty->createTemplate('string:{foreach $foo as $x}{$x} {/foreach}');
+ $tpl->assign('foo', array(9, 8), true);
+ $this->assertTrue($this->smarty->isCached($tpl));
+ $this->assertEquals("9 8 ", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachNocacheTag1()
+ {
+ $this->smarty->caching = true;
+ $tpl = $this->smarty->createTemplate('string:{foreach $foo as $x nocache}{$x} {/foreach}');
+ $tpl->assign('foo', array(1, 2));
+ $this->assertFalse($this->smarty->isCached($tpl));
+ $this->assertEquals("1 2 ", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testForeachNocacheTag2()
+ {
+ $this->smarty->caching = true;
+ $tpl = $this->smarty->createTemplate('string:{foreach $foo as $x nocache}{$x} {/foreach}');
+ $tpl->assign('foo', array(9, 8));
+ $this->assertTrue($this->smarty->isCached($tpl));
+ $this->assertEquals("9 8 ", $this->smarty->fetch($tpl));
+ }
+
+ public function testForeachCache1()
+ {
+ $this->smarty->caching = true;
+ $tpl = $this->smarty->createTemplate('string:{foreach $foo as $x name=bar}{$x} {/foreach}');
+ $tpl->assign('foo', array(1, 2));
+ $this->assertFalse($this->smarty->isCached($tpl));
+ $this->assertEquals("1 2 ", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testForeachCache2()
+ {
+ $this->smarty->caching = true;
+ $tpl = $this->smarty->createTemplate('string:{foreach $foo as $x name=bar}{$x} {/foreach}');
+ $tpl->assign('foo', array(9, 8));
+ $this->assertTrue($this->smarty->isCached($tpl));
+ $this->assertEquals("1 2 ", $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/FunctionPlugin/CompileFunctionPluginTest.php b/tests/UnitTests/TemplateSource/TagTests/FunctionPlugin/CompileFunctionPluginTest.php
new file mode 100644
index 00000000..c5bec31d
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/FunctionPlugin/CompileFunctionPluginTest.php
@@ -0,0 +1,67 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test function plugin tag in template file
+ */
+ public function testFunctionPluginFromTemplateFile()
+ {
+ $tpl = $this->smarty->createTemplate('functionplugintest.tpl', $this->smarty);
+ $this->assertEquals("10", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test function plugin tag in compiled template file
+ */
+ public function testFunctionPluginFromCompiledTemplateFile()
+ {
+ $this->smarty->setForceCompile(false);
+ $tpl = $this->smarty->createTemplate('functionplugintest.tpl', $this->smarty);
+ $this->assertEquals("10", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test function plugin function definition in script
+ */
+ public function testFunctionPluginRegisteredFunction()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_FUNCTION, 'plugintest', 'myplugintest');
+ $tpl = $this->smarty->createTemplate('eval:{plugintest foo=bar}', $this->smarty);
+ $this->assertEquals("plugin test called bar", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test muiltiline tags
+ */
+ public function testMultiLineTags()
+ {
+ $this->assertEquals("10", $this->smarty->fetch("eval:{counter\n\tstart=10}"));
+ }
+}
+
+function myplugintest($params, &$smarty)
+{
+ return "plugin test called $params[foo]";
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/FunctionPlugin/templates/functionplugintest.tpl b/tests/UnitTests/TemplateSource/TagTests/FunctionPlugin/templates/functionplugintest.tpl
new file mode 100644
index 00000000..8faa5d5f
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/FunctionPlugin/templates/functionplugintest.tpl
@@ -0,0 +1 @@
+{counter start=10 name=tpl}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/If/CompileIfTest.php b/tests/UnitTests/TemplateSource/TagTests/If/CompileIfTest.php
new file mode 100644
index 00000000..0e6e5c23
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/If/CompileIfTest.php
@@ -0,0 +1,430 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test {if} tag
+ */
+ public function testIf1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 0<1}yes{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testElseif1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if false}false{elseif 0<1}yes{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIf2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 2<1}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIf3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 2<1}yes{elseif 4<5}yes1{else}no{/if}');
+ $this->assertEquals("yes1", $this->smarty->fetch($tpl));
+ }
+
+ public function testIf4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 2<1}yes{elseif 6<5}yes1{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfTrue()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if true}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfFalse()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if false}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfNot1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if !(1<2)}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfNot2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if not (true)}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfEQ1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 == 1}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfEQ2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1==1}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfEQ3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 EQ 1}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfEQ4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 eq 1}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfIdentity1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=true}{if $foo===true}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfIdentity2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=true}{if $foo === true}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfNotIdentity1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=true}{if $foo!==true}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfNotIdentity2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=true}{if $foo !== true}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfGT1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 > 0}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfGT2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 0>1}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfGT3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 GT 0}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfGT4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 0 gt 1}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfGE1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 >= 0}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfGE2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1>=1}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfGE3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 GE 1}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfGE4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 0 ge 1}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfLT1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 0 < 0}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfLT2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 0<1}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfLT3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 0 LT 1}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfLT4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 0 lt 1}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfLE1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 0 <= 0}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfLE2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 0<=1}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfLE3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 LE 0}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfLE4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 0 le 1}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfNE1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 != 1}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfNE2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1!=2}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfNE3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 NE 1}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfNE4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 ne 2}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfIdent1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 === "1"}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfIdent2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if "1" === "1"}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfAnd1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 > 0 && 5 < 6}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfAnd2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 > 0&&5 < 6}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfAnd3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 > 0 AND 5 > 6}}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfAnd4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if (1 > 0) and (5 < 6)}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfOr1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 > 0 || 7 < 6}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfOr2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 > 0||5 < 6}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfOr3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 1 > 0 OR 5 > 6}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfOr4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if (0 > 0) or (9 < 6)}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfAndOR4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if ((7>8)||(1 > 0)) and (5 < 6)}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfIsDivBy()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 6 is div by 3}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfIsNotDivBy()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 6 is not div by 3}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfIsEven()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 6 is even}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfIsNotEven()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 6 is not even}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfIsOdd()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 3 is odd}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfIsNotOdd()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 3 is not odd}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfIsOddBy()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 3 is odd by 3}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfIsNotOddBy()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 6 is odd by 3}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfIsEvenBy()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 6 is even by 3}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfIsNotEvenBy()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 6 is not even by 3}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfFunc1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if strlen("hello world") == 11}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfFunc2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if 3 ge strlen("foo")}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfFunc3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if isset($foo)}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfFunc4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=1}{if isset($foo)}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfStatement1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if $x=true}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfStatement2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if $x=false}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfVariable1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$x=1}{if $x}yes{else}no{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfVariable2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$x=0}{if $x}yes{else}no{/if}');
+ $this->assertEquals("no", $this->smarty->fetch($tpl));
+ }
+
+ public function testIfVariableInc1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$x=0}{if $x++}yes{else}no{/if} {$x}');
+ $this->assertEquals("no 1", $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/CompileIncludeTest.php b/tests/UnitTests/TemplateSource/TagTests/Include/CompileIncludeTest.php
new file mode 100644
index 00000000..857cc311
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/CompileIncludeTest.php
@@ -0,0 +1,290 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test spacing
+ *
+ * @rrunInSeparateProcess
+ * @dataProvider includeProviderCaching
+ */
+ public function testSpacing_001($merge, $caching, $text)
+ {
+ $this->smarty->setCaching($caching);
+ if ($merge) {
+ $this->smarty->setCacheId('1');
+ }
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $content = $this->smarty->fetch('test_include_001.tpl');
+ $this->assertEquals('I1I2I3', $content, $text);
+ }
+
+ /**
+ * test spacing
+ *
+ * @rrunInSeparateProcess
+ * @dataProvider includeProviderCaching
+ */
+ public function testSpacing_001V2($merge, $caching, $text)
+ {
+ $this->smarty->setCaching($caching);
+ if ($merge) {
+ $this->smarty->setCacheId('1');
+ }
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $content = $this->smarty->fetch('test_include_001V2.tpl');
+ $this->assertEquals('I1I2I3', $content, $text);
+ }
+
+ /**
+ * test spacing
+ *
+ * @rrunInSeparateProcess
+ * @dataProvider includeProviderCaching
+ */
+ public function testSpacing_001V3($merge, $caching, $text)
+ {
+ $this->smarty->setCaching($caching);
+ if ($merge) {
+ $this->smarty->setCacheId('1');
+ }
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $content = $this->smarty->fetch('test_include_001V3.tpl');
+ $this->assertEquals('I1I2I3', $content, $text);
+ }
+
+ /**
+ * test standard output
+ *
+ * @dataProvider includeProvider
+ */
+ public function testIncludeStandard_001($merge, $text)
+ {
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $tpl = $this->smarty->createTemplate('test_include_standard.tpl');
+ $content = $this->smarty->fetch($tpl);
+ $this->assertEquals("hello world", $content, $text);
+ }
+
+ /**
+ * test standard output nocache var
+ *
+ * @dataProvider includeProvider
+ */
+ public function testIncludeStandardNocacheVar($merge, $text)
+ {
+ $this->smarty->setMergeCompiledIncludes(false);
+ $this->smarty->caching = true;
+ $this->smarty->assign('foo', 'foo', true);
+ $tpl = $this->smarty->createTemplate('test_include_standard_nocache_var.tpl', $this->smarty);
+ $content = $this->smarty->fetch($tpl);
+ $this->assertEquals("foo\n\nhello world", $content, $text);
+ }
+
+ /**
+ * Test that assign attribute does not create standard output
+ *
+ * @dataProvider includeProvider
+ */
+ public function testIncludeAssign1($merge, $text)
+ {
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $tpl = $this->smarty->createTemplate('test_include_assign1.tpl');
+ $this->assertEquals("", $this->smarty->fetch($tpl), $text);
+ }
+
+ /**
+ * Test that assign attribute does load variable
+ *
+ * @dataProvider includeProvider
+ */
+ public function testIncludeAssign2($merge, $text)
+ {
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $tpl = $this->smarty->createTemplate('test_include_assign2.tpl');
+ $this->assertEquals("hello world", $this->smarty->fetch($tpl), $text);
+ }
+
+ /**
+ * Test passing local vars eval
+ *
+ * @dataProvider includeProvider
+ */
+ public function testIncludePassVars($merge, $text)
+ {
+ //$this->smarty->caching = true;
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $tpl = $this->smarty->createTemplate('test_include_pass_vars.tpl');
+ $this->assertEquals("12", $this->smarty->fetch($tpl), $text);
+ }
+
+ /**
+ * Test passing local vars include
+ *
+ * @dataProvider includeProvider
+ */
+ public function testIncludePassVars2($merge, $text)
+ {
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $tpl = $this->smarty->createTemplate('test_include_pass_vars2.tpl');
+ $this->assertEquals("12", $this->smarty->fetch($tpl), $text);
+ }
+
+ /**
+ * Test local scope
+ *
+ * @dataProvider includeProvider
+ */
+ public function testIncludeLocalScope($merge, $text)
+ {
+ //$this->smarty->caching = true;
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $this->smarty->assign('foo', 1);
+ $tpl = $this->smarty->createTemplate('test_include_local_scope.tpl', null, null, $this->smarty);
+ $content = $this->smarty->fetch($tpl);
+ $this->assertContains('before include 1', $content, 'before include 1 ' . $text);
+ $this->assertContains('in include 2', $content . 'in include 2 ' . $text);
+ $this->assertContains('after include 1', $content, 'after include 1 ' . $text);
+ }
+
+ /**
+ * Test parent scope
+ *
+ * @dataProvider includeProvider
+ */
+ public function testIncludeParentScope($merge, $text)
+ {
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $this->smarty->assign('foo', 1);
+ $tpl = $this->smarty->createTemplate('test_include_parent_scope.tpl', null, null, $this->smarty);
+ $content = $this->smarty->fetch($tpl);
+ $content2 = $this->smarty->fetch('eval: root value {$foo}');
+ $this->assertContains('before include 1', $content, 'before include 1 ' . $text);
+ $this->assertContains('in include 2', $content . 'in include 2 ' . $text);
+ $this->assertContains('after include 2', $content, 'after include 2 ' . $text);
+ $this->assertContains('root value 1', $content2, 'root value 1 ' . $text);
+ }
+
+ /**
+ * Test root scope
+ *
+ * @dataProvider includeProvider
+ */
+ public function testIncludeRootScope($merge, $text)
+ {
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $this->smarty->setErrorReporting(error_reporting() & ~(E_NOTICE | E_USER_NOTICE));
+ $this->smarty->assign('foo', 1);
+ $tpl = $this->smarty->createTemplate('test_include_root_scope.tpl');
+ $content = $this->smarty->fetch($tpl);
+ $content2 = $this->smarty->fetch('eval: smarty value {$foo}');
+ $this->assertNotContains('before include 1', $content, 'before include 1 ' . $text);
+ $this->assertContains('in include 2', $content . 'in include 2 ' . $text);
+ $this->assertContains('after include 2', $content, 'after include 2 ' . $text);
+ $this->assertContains('smarty value 1', $content2, 'smarty value 1 ' . $text);
+ }
+
+ /**
+ * Test root scope
+ *
+ * @dataProvider includeProvider
+ */
+ public function testIncludeRootScope2($merge, $text)
+ {
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $this->smarty->assign('foo', 1);
+ $tpl = $this->smarty->createTemplate('test_include_root_scope.tpl', null, null, $this->smarty);
+ $content = $this->smarty->fetch($tpl);
+ $content2 = $this->smarty->fetch('eval: smarty value {$foo}');
+ $this->assertContains('before include 1', $content, 'before include 1 ' . $text);
+ $this->assertContains('in include 2', $content . 'in include 2 ' . $text);
+ $this->assertContains('after include 1', $content, 'after include 1 ' . $text);
+ $this->assertContains('smarty value 2', $content2, 'smarty value 2 ' . $text);
+ }
+
+ /**
+ * Test recursive includes
+ *
+ * @dataProvider includeProvider
+ */
+ public function testRecursiveIncludes1($merge, $text)
+ {
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $this->smarty->assign('foo', 1);
+ $this->smarty->assign('bar', 'bar');
+ $content = $this->smarty->fetch('test_recursive_includes.tpl');
+ $this->assertContains("before 1 bar
\nbefore 2 bar
\nbefore 3 bar
\nafter 3 bar
\nafter 2 bar
\nafter 1 bar
", $content, $text);
+ }
+
+ /**
+ * Test recursive includes 2
+ *
+ * @dataProvider includeProvider
+ */
+ public function testRecursiveIncludes2($merge, $text)
+ {
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $this->smarty->assign('foo', 1);
+ $this->smarty->assign('bar', 'bar');
+ $content = $this->smarty->fetch('test_recursive_includes2.tpl');
+ $this->assertContains("before 1 bar
\nbefore 3 bar
\nbefore 5 bar
\nafter 5 bar
\nafter 3 bar
\nafter 1 bar
", $content, $text);
+ }
+
+ /**
+ * Include data provider
+ */
+ public function includeProvider()
+ {
+ return array(
+ array(false, 'normal'),
+ array(true, 'merged'),
+ );
+ }
+
+ /**
+ * Include data provider caching
+ *
+ * @dataProvider fileProvider
+ */
+ public function includeProviderCaching($file)
+ {
+ return array(
+ array(false, false, 'normal'),
+ array(true, false, 'merged'),
+ array(false, true, 'normal cached 1'),
+ array(false, true, 'normal cached 2'),
+ array(true, true, 'merged cached 1'),
+ array(true, true, 'merged cached 2'),
+ );
+ }
+
+ public function fileProvider()
+ {
+ return array(
+ array('normal'),
+ array('merged'),
+ );
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/helloworld.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/helloworld.tpl
new file mode 100644
index 00000000..95d09f2b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/helloworld.tpl
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001.tpl
new file mode 100644
index 00000000..8dd11b1e
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001.tpl
@@ -0,0 +1 @@
+I1{include file='test_include_001_2.tpl'}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001V2.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001V2.tpl
new file mode 100644
index 00000000..49d4a5bb
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001V2.tpl
@@ -0,0 +1 @@
+I1{include file='test_include_001_2.tpl' cache_lifetime=30}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001V3.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001V3.tpl
new file mode 100644
index 00000000..a1eee482
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001V3.tpl
@@ -0,0 +1 @@
+I1{include file='test_include_001_2V3.tpl' cache_lifetime=30}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001_2.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001_2.tpl
new file mode 100644
index 00000000..c2a6f309
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001_2.tpl
@@ -0,0 +1 @@
+I2{include file='test_include_001_3.tpl'}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001_2V3.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001_2V3.tpl
new file mode 100644
index 00000000..64bf6c17
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001_2V3.tpl
@@ -0,0 +1 @@
+I2{include file='test_include_001_3.tpl' nocache}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001_3.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001_3.tpl
new file mode 100644
index 00000000..ebf6bc50
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_001_3.tpl
@@ -0,0 +1 @@
+I3
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_assign1.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_assign1.tpl
new file mode 100644
index 00000000..6021362f
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_assign1.tpl
@@ -0,0 +1 @@
+{include file="helloworld.tpl" assign=foo}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_assign2.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_assign2.tpl
new file mode 100644
index 00000000..aee9b8ad
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_assign2.tpl
@@ -0,0 +1 @@
+{assign var=foo value=bar}{include file="helloworld.tpl" assign=foo}{$foo}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_local_scope.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_local_scope.tpl
new file mode 100644
index 00000000..e90ac4e1
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_local_scope.tpl
@@ -0,0 +1 @@
+before include {$foo} {include file='test_include_local_scope_sub.tpl'} after include {$foo}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_local_scope_sub.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_local_scope_sub.tpl
new file mode 100644
index 00000000..0e43de2d
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_local_scope_sub.tpl
@@ -0,0 +1 @@
+{$foo=2} in include {$foo}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_parent_scope.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_parent_scope.tpl
new file mode 100644
index 00000000..e8e39131
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_parent_scope.tpl
@@ -0,0 +1 @@
+before include {$foo} {include file='test_include_local_scope_sub.tpl' scope = parent} after include {$foo}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_pass_vars.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_pass_vars.tpl
new file mode 100644
index 00000000..0cf974d1
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_pass_vars.tpl
@@ -0,0 +1 @@
+{include file='test_include_pass_vars2_sub.tpl' myvar1=1 myvar2=2}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_pass_vars2.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_pass_vars2.tpl
new file mode 100644
index 00000000..0cf974d1
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_pass_vars2.tpl
@@ -0,0 +1 @@
+{include file='test_include_pass_vars2_sub.tpl' myvar1=1 myvar2=2}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_pass_vars2_sub.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_pass_vars2_sub.tpl
new file mode 100644
index 00000000..e2b94437
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_pass_vars2_sub.tpl
@@ -0,0 +1 @@
+{$myvar1}{$myvar2}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_root_scope.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_root_scope.tpl
new file mode 100644
index 00000000..92f68120
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_root_scope.tpl
@@ -0,0 +1 @@
+before include {$foo} {include file='test_include_local_scope_sub.tpl' scope = root} after include {$foo}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_standard.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_standard.tpl
new file mode 100644
index 00000000..9837d596
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_standard.tpl
@@ -0,0 +1 @@
+{include file='helloworld.tpl'}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_standard_nocache_var.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_standard_nocache_var.tpl
new file mode 100644
index 00000000..8a545348
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_include_standard_nocache_var.tpl
@@ -0,0 +1,3 @@
+{$foo}
+
+{include file="helloworld.tpl"}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_recursive_includes.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_recursive_includes.tpl
new file mode 100644
index 00000000..344c0dd6
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_recursive_includes.tpl
@@ -0,0 +1,2 @@
+before {$foo} {$bar}
+{if $foo < 3}{include 'test_recursive_includes.tpl' foo=$foo+1}{/if}after {$foo} {$bar}
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_recursive_includes2.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_recursive_includes2.tpl
new file mode 100644
index 00000000..f550809e
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_recursive_includes2.tpl
@@ -0,0 +1,2 @@
+before {$foo} {$bar}
+{if $foo < 4}{include 'test_recursive_includes_pass.tpl' foo=$foo+1}{/if}after {$foo} {$bar}
diff --git a/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_recursive_includes_pass.tpl b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_recursive_includes_pass.tpl
new file mode 100644
index 00000000..eb31fc18
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Include/templates/test_recursive_includes_pass.tpl
@@ -0,0 +1 @@
+{include 'test_recursive_includes2.tpl' foo=$foo+1}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/IncludePhp/CompileIncludePhpTest.php b/tests/UnitTests/TemplateSource/TagTests/IncludePhp/CompileIncludePhpTest.php
new file mode 100644
index 00000000..0bda94c6
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/IncludePhp/CompileIncludePhpTest.php
@@ -0,0 +1,60 @@
+setUpSmarty(__DIR__);
+ $this->smartyBC->setForceCompile(true);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test include_php string file_name function
+ */
+ public function testIncludePhpStringFileName()
+ {
+ $this->smartyBC->disableSecurity();
+ $tpl = $this->smartyBC->createTemplate("eval:start {include_php file='scripts/test_include_php.php'} end");
+ $result = $this->smartyBC->fetch($tpl);
+ $this->assertContains("test include php", $result);
+ }
+
+ /**
+ * test include_php string file_name function
+ */
+ public function testIncludePhpVariableFileName()
+ {
+ $this->smartyBC->disableSecurity();
+ $tpl = $this->smartyBC->createTemplate('eval:start {include_php file=$filename once=false} end');
+ $tpl->assign('filename', 'scripts/test_include_php.php');
+ $result = $this->smartyBC->fetch($tpl);
+ $this->assertContains("test include php", $result);
+ }
+
+ public function testIncludePhpVariableFileNameShortag()
+ {
+ $this->smartyBC->disableSecurity();
+ $tpl = $this->smartyBC->createTemplate('eval:start {include_php $filename once=false} end');
+ $tpl->assign('filename', 'scripts/test_include_php.php');
+ $result = $this->smartyBC->fetch($tpl);
+ $this->assertContains("test include php", $result);
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/IncludePhp/scripts/test_include_php.php b/tests/UnitTests/TemplateSource/TagTests/IncludePhp/scripts/test_include_php.php
new file mode 100644
index 00000000..2bb96d8a
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/IncludePhp/scripts/test_include_php.php
@@ -0,0 +1,2 @@
+setUpSmarty(__DIR__);
+ $this->smarty->addPluginsDir(__DIR__ . "/PHPunitplugins/");
+ $this->smarty->enableSecurity();
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test inserted function
+ */
+ public function testInsertFunctionSingle()
+ {
+ $tpl = $this->smarty->createTemplate("eval:start {insert name='test' foo='bar'} end");
+ $this->assertEquals("start insert function parameter value bar end", $this->smarty->fetch($tpl));
+ }
+
+ public function testInsertFunctionDouble()
+ {
+ $tpl = $this->smarty->createTemplate("eval:start {insert name=\"test\" foo='bar'} end");
+ $this->assertEquals("start insert function parameter value bar end", $this->smarty->fetch($tpl));
+ }
+
+ public function testInsertFunctionVariableName()
+ {
+ $tpl = $this->smarty->createTemplate("eval:start {insert name=\$variable foo='bar'} end");
+ $tpl->assign('variable', 'test');
+ $this->assertEquals("start insert function parameter value bar end", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test insert plugin
+ */
+ public function testInsertPlugin1()
+ {
+ global $insertglobal;
+ $insertglobal = 'global';
+ $tpl = $this->smarty->createTemplate('insertplugintest.tpl');
+ $tpl->assign('foo', 'bar');
+ $this->assertEquals('param foo bar globalvar global', $this->smarty->fetch($tpl));
+ }
+ /**
+ * @runInSeparateProcess
+ * @preserveGlobalState disabled
+ * test insert plugin
+ */
+ public function testInsertPlugin2()
+ {
+ global $insertglobal;
+ $insertglobal = 'global 2';
+ $tpl = $this->smarty->createTemplate('insertplugintest.tpl');
+ $tpl->assign('foo', 'buh');
+ $this->assertEquals('param foo buh globalvar global 2', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test insert plugin caching
+ */
+ public function testInsertPluginCaching1_1()
+ {
+ global $insertglobal;
+ $insertglobal = 'global';
+ $this->smarty->caching = true;
+ $tpl = $this->smarty->createTemplate('insertplugintest.tpl');
+ $tpl->assign('foo', 'bar', true);
+ $this->assertEquals('param foo bar globalvar global', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ *
+ * @runInSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testInsertPluginCaching1_3()
+ {
+ $this->smarty->addPluginsDir(__DIR__ . "/PHPunitplugins/");
+ global $insertglobal;
+ $insertglobal = 'changed global';
+ $this->smarty->caching = 1;
+// $this->smarty->setForceCompile(true);
+ $this->smarty->assign('foo', 'bar', true);
+ $this->assertEquals('param foo bar globalvar changed global', $this->smarty->fetch('insertplugintest.tpl'));
+ }
+
+ /**
+ * test insert plugin caching 2
+ */
+ public function testInsertPluginCaching2_1()
+ {
+ global $insertglobal;
+ $insertglobal = 'global';
+ $this->smarty->caching = true;
+ $this->smarty->compile_id = 1;
+ $tpl = $this->smarty->createTemplate('insertplugintest.tpl');
+ $tpl->assign('foo', 'bar');
+ $this->assertEquals('param foo bar globalvar global', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test insert plugin caching 2
+ * @runInSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testInsertPluginCaching2_2()
+ {
+ global $insertglobal;
+ $insertglobal = 'global 2';
+ $this->smarty->caching = true;
+ $this->smarty->compile_id = 1;
+ $tpl = $this->smarty->createTemplate('insertplugintest.tpl');
+ $tpl->assign('foo', 'buh');
+ $this->assertEquals('param foo bar globalvar global 2', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test inserted function with assign
+ */
+ public function testInsertFunctionAssign()
+ {
+ $tpl = $this->smarty->createTemplate("eval:start {insert name='test' foo='bar' assign=blar} end {\$blar}");
+ $this->assertEquals("start end insert function parameter value bar", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test insertfunction with assign no output
+ */
+ public function testInsertFunctionAssignNoOutput()
+ {
+ $tpl = $this->smarty->createTemplate("eval:start {insert name='test' foo='bar' assign=blar} end");
+ $this->assertEquals("start end", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test insert plugin with assign
+ */
+ public function testInsertPluginAssign()
+ {
+ global $insertglobal;
+ $insertglobal = 'global';
+ $tpl = $this->smarty->createTemplate("eval:start {insert name='insertplugintest' foo='bar' assign=blar} end {\$blar}");
+ $tpl->assign('foo', 'bar');
+ $this->assertEquals('start end param foo bar globalvar global', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test inserted function none existing function
+ */
+ public function testInsertFunctionNoneExistingFunction()
+ {
+ $tpl = $this->smarty->createTemplate("eval:start {insert name='mustfail' foo='bar' assign=blar} end {\$blar}");
+ try {
+ $this->smarty->fetch($tpl);
+ }
+ catch (Exception $e) {
+ $this->assertContains("{insert} no function or plugin found for 'mustfail'", $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for "function is not callable" has not been raised.');
+ }
+
+ /**
+ * test inserted function none existing script
+ */
+ public function testInsertFunctionNoneExistingScript()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{insert name='mustfail' foo='bar' script='nofile.php'}");
+ try {
+ $this->smarty->fetch($tpl);
+ }
+ catch (Exception $e) {
+ $this->assertContains('missing script file', $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for "missing file" has not been raised.');
+ }
+}
+
+/**
+ * test function
+ */
+function insert_test($params)
+{
+ return "insert function parameter value $params[foo]";
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/Insert/PHPunitplugins/insert.insertplugintest.php b/tests/UnitTests/TemplateSource/TagTests/Insert/PHPunitplugins/insert.insertplugintest.php
new file mode 100644
index 00000000..cd2e27cd
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Insert/PHPunitplugins/insert.insertplugintest.php
@@ -0,0 +1,7 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /*
+ * Test literal tag
+ */
+ public function testLiteralTag()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{literal} {\$foo} {/literal}");
+ $this->assertEquals(' {$foo} ', $this->smarty->fetch($tpl));
+ }
+
+ /*
+ * Test auto literal space
+ */
+ public function testAutoLiteralSpace()
+ {
+ $tpl = $this->smarty->createTemplate("eval: { \$foo} ");
+ $tpl->assign('foo', 'literal');
+ $this->assertEquals(' { $foo} ', $this->smarty->fetch($tpl));
+ }
+
+ /*
+ * Test auto literal line break
+ */
+ public function testAutoLiteralLineBreak()
+ {
+ $tpl = $this->smarty->createTemplate("eval: {\n\$foo} ");
+ $tpl->assign('foo', 'literal');
+ $this->assertEquals(" {\n\$foo} ", $this->smarty->fetch($tpl));
+ }
+
+ /*
+ * Test auto literal disabled
+ */
+ public function testAutoLiteralDisabled()
+ {
+ $this->smarty->setAutoLiteral(false);
+ $tpl = $this->smarty->createTemplate("eval: { \$foo} ");
+ $tpl->assign('foo', 'literal');
+ $this->assertEquals(' literal ', $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/Nocache/CompileNocacheTest.php b/tests/UnitTests/TemplateSource/TagTests/Nocache/CompileNocacheTest.php
new file mode 100644
index 00000000..5f69ce2f
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Nocache/CompileNocacheTest.php
@@ -0,0 +1,73 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test nocache tag caching disabled
+ */
+ public function testNocacheCachingNo()
+ {
+ $this->smarty->caching = 0;
+ $this->smarty->assign('foo', 0);
+ $this->smarty->assign('bar', 'A');
+ $content = $this->smarty->fetch('test_nocache_tag.tpl');
+ $this->assertContains("root 2A", $content);
+ $this->assertContains("include 4A", $content);
+ $this->smarty->assign('foo', 2);
+ $this->smarty->assign('bar', 'B');
+ $content = $this->smarty->fetch('test_nocache_tag.tpl');
+ $this->assertContains("root 4B", $content);
+ $this->assertContains("include 6B", $content);
+ }
+
+ /**
+ * test nocache tag caching enabled
+ */
+ public function testNocacheCachingYes1()
+ {
+ $this->smarty->caching = 1;
+ $this->smarty->assign('foo', 0);
+ $this->smarty->assign('bar', 'A');
+ $content = $this->smarty->fetch('test_nocache_tag.tpl');
+ $this->assertContains("root 2A", $content);
+ $this->assertContains("include 4A", $content);
+
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testNocacheCachingYes2()
+ {
+ $this->smarty->caching = 1;
+ $this->smarty->assign('foo', 2);
+ $this->smarty->assign('bar', 'B');
+ $content = $this->smarty->fetch('test_nocache_tag.tpl');
+ $this->assertContains("root 4A", $content);
+ $this->assertContains("include 6A", $content);
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/Nocache/templates/test_nocache_tag.tpl b/tests/UnitTests/TemplateSource/TagTests/Nocache/templates/test_nocache_tag.tpl
new file mode 100644
index 00000000..fed2d1fa
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Nocache/templates/test_nocache_tag.tpl
@@ -0,0 +1,2 @@
+
root {nocache}{$foo + 2}{/nocache}{$bar}
+{include file='test_nocache_tag_include.tpl'}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Nocache/templates/test_nocache_tag_include.tpl b/tests/UnitTests/TemplateSource/TagTests/Nocache/templates/test_nocache_tag_include.tpl
new file mode 100644
index 00000000..6ef97be7
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Nocache/templates/test_nocache_tag_include.tpl
@@ -0,0 +1 @@
+
include {nocache}{$foo + 4}{/nocache}{$bar}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/Php/CompilePhp2Test.php b/tests/UnitTests/TemplateSource/TagTests/Php/CompilePhp2Test.php
new file mode 100644
index 00000000..eb8b02b7
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Php/CompilePhp2Test.php
@@ -0,0 +1,393 @@
+ tag
+ *
+ * @package PHPunit
+ * @author Uwe Tews
+ */
+
+/**
+ * class for {php} and tag tests
+ */
+class CompilePhp2Test extends PHPUnit_Smarty
+{
+ public $loadSmartyBC = true;
+ public $loadSmarty = false;
+ public function setUp()
+ {
+ $this->setUpSmarty(__DIR__);
+ $this->smartyBC->disableSecurity();
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ public function testEndTagInStrings1()
+ {
+ $str = <<< STR
+" => 3 );
+\$b = Array("?>" => "?>");
+\$c = Array("a" => Array("b" => 7));
+class d_class
+{
+ public \$d_attr = 8;
+}
+\$d = new d_class();
+\$e = Array("f" => \$d);
+
+// '"
+# '"
+
+echo '{\$a["?>"]}';
+echo "{\$a['?>']}";
+echo '{\$a["{\$b["?>"]}"]}';
+echo "{\$c['a']['b']}";
+echo "a{\$e['f']->d_attr}a";
+?>
+STR;
+
+ $this->smartyBC->left_delimiter = '{{';
+ $this->smartyBC->right_delimiter = '}}';
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals(str_replace("\r", '', $str), str_replace("\r", '', $content));
+
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $this->smartyBC->disableSecurity();
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals('{$a["?>"]}3{$a["{$b["?>"]}"]}7a8a', $content);
+ }
+
+ public function testEndTagInStrings2()
+ {
+ $str = <<< STR
+" => 3 );
+\$b = Array("?>" => "?>");
+
+echo "{\$a["?>"]}";
+echo "{\$a["{\$b["?>"]}"]}";
+?>
+STR;
+
+ $this->smartyBC->left_delimiter = '{{';
+ $this->smartyBC->right_delimiter = '}}';
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals(str_replace("\r", '', $str), str_replace("\r", '', $content));
+
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $this->smartyBC->disableSecurity();
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals('33', $content);
+ }
+
+ public function testEndTagInStrings3()
+ {
+ $str = <<< STR
+a';
+echo '?>\\\\';
+echo '\\\\\\'?>a';
+echo '/*'; // */
+echo 1+1;
+?>
+STR;
+
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals(str_replace("\r", '', $str), str_replace("\r", '', $content));
+
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $this->smartyBC->disableSecurity();
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals('a?>a?>\\\\\'?>a/*2', $content);
+ }
+
+ public function testEndTagInStrings4()
+ {
+ $str = <<< STR
+a";
+echo "?>\\\\";
+echo "\\"?>";
+echo "\\\\\\"?>a";
+echo "/*";
+echo 1+1;
+?>
+STR;
+
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals(str_replace("\r", '', $str), str_replace("\r", '', $content));
+
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $this->smartyBC->disableSecurity();
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals('a?>a?>\\"?>\\"?>a/*2', $content);
+ }
+
+ public function testEndTagInHEREDOC()
+ {
+ $str = <<< STR
+
+
+ "! ?> /*
+ LALA
+LALA ;
+LALA;1+1;
+LALA;
+echo <<
+STR;
+ // " Fix emacs highlighting which chokes on preceding open quote
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals(str_replace("\r", '', $str), str_replace("\r", '', $content));
+
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $this->smartyBC->disableSecurity();
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals(" LALA\n ?>\n\n \"! ?> /*\n LALA\nLALA ;\nLALA;1+1;LALA2;1+1;", str_replace("\r", '', $content));
+ }
+
+ public function testEmbeddingsInHEREDOC1()
+ {
+ $str = <<< STR
+'" => 1);
+
+echo <<< EOT
+{\$a["EOT?>'"]}
+EOT;
+?>
+STR;
+ // ' Fix emacs highlighting which chokes on preceding open quote
+ $this->smartyBC->left_delimiter = '{{';
+ $this->smartyBC->right_delimiter = '}}';
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals(str_replace("\r", '', $str), str_replace("\r", '', $content));
+
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $this->smartyBC->disableSecurity();
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals("1", $content);
+ }
+
+ public function testEmbeddingsInHEREDOC2()
+ {
+ $str = <<< STR
+'" => 1);
+
+echo <<< EOT
+{\$a[<<'
+EOT2
+]}
+EOT
+;
+?>
+STR;
+ // ' Fix emacs highlighting which chokes on preceding open quote
+ $this->smartyBC->left_delimiter = '{{';
+ $this->smartyBC->right_delimiter = '}}';
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals(str_replace("\r", '', $str), str_replace("\r", '', $content));
+ /* Disabled due to bug in PHP easiest illustrated by:
+ http://bugs.php.net/bug.php?id=50654
+
+ 1);
+
+echo <<
+ $this->smartyBC->left_delimiter = '{{';
+ $this->smartyBC->right_delimiter = '}}';
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $this->smartyBC->security = false;
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals("11", $content);
+*/
+ }
+
+ public function testEmbeddedHEREDOC()
+ {
+ $str = <<< STR
+ 3);
+\$b = Array("aa\"?>" => 4);
+
+echo "{\$a[<<"]}"
+EOT
+ ]}";
+?>
+STR;
+ // " Fix emacs highlighting which chokes on preceding open quote
+ $this->smartyBC->left_delimiter = '{{';
+ $this->smartyBC->right_delimiter = '}}';
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals(str_replace("\r", '', $str), str_replace("\r", '', $content));
+
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $this->smartyBC->disableSecurity();
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals("3", $content);
+ }
+
+ public function testEmbeddedNOWDOC()
+ {
+ $str = <<< STR
+" => 3);
+
+echo "{\$a[<<<'EOT'
+aa"?>
+EOT
+ ]}";
+?>
+STR;
+ // " Fix emacs highlighting which chokes on preceding open quote
+ $this->smartyBC->left_delimiter = '{{';
+ $this->smartyBC->right_delimiter = '}}';
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals(str_replace("\r", '', $str), str_replace("\r", '', $content));
+
+ if (version_compare(PHP_VERSION, '5.3.0') < 0) {
+ return;
+ }
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $this->smartyBC->disableSecurity();
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals("3", $content);
+ }
+
+ public function testEndTagInNOWDOC()
+ {
+ $str = <<< STR
+ bb
+LALA;
+echo <<<'LALA2'
+LALA2;1+1;?>
+LALA2
+;
+?>
+STR;
+
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals(str_replace("\r", '', $str), str_replace("\r", '', $content));
+
+ if (version_compare(PHP_VERSION, '5.3.0') < 0) {
+ return;
+ }
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $this->smartyBC->disableSecurity();
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals("aa ?> bbLALA2;1+1;?>", $content);
+ }
+
+ public function testNewlineHEREDOC()
+ {
+ $sprintf_str = "";
+ foreach (Array("\n", "\r\n") as $newline_chars) {
+ $str = sprintf($sprintf_str, $newline_chars);
+
+ $this->smartyBC->php_handling = Smarty::PHP_PASSTHRU;
+ $this->smartyBC->enableSecurity();
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ // For some reason $content doesn't preserve newline format. Not a big problem, I think.
+ $this->assertEquals(preg_replace("/\r\n/", "\n", $str),
+ preg_replace("/\r\n/", "\n", $content)
+ );
+
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $this->smartyBC->disableSecurity();
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals("a", $content);
+ }
+ }
+
+ public function testNewlineNOWDOC()
+ {
+ $sprintf_str = "";
+ foreach (Array("\n", "\r\n") as $newline_chars) {
+ $str = sprintf($sprintf_str, $newline_chars);
+
+ $this->smartyBC->php_handling = Smarty::PHP_PASSTHRU;
+ $this->smartyBC->enableSecurity();
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ // For some reason $content doesn't preserve newline format. Not a big problem, I think.
+ $this->assertEquals(preg_replace("/\r\n/", "\n", $str),
+ preg_replace("/\r\n/", "\n", $content)
+ );
+
+ if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $this->smartyBC->disableSecurity();
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals("a", $content);
+ }
+ }
+ }
+
+ public function testEndTagInComment()
+ {
+ $str = <<< STR
+dd "' <<< EOT
+*/
+echo 1+1;
+?>
+STR;
+
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals(str_replace("\r", '', $str), str_replace("\r", '', $content));
+
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $this->smartyBC->disableSecurity();
+ $tpl = $this->smartyBC->createTemplate("eval:$str");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals('2', $content);
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/Php/CompilePhpTest.php b/tests/UnitTests/TemplateSource/TagTests/Php/CompilePhpTest.php
new file mode 100644
index 00000000..4bed0c8a
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Php/CompilePhpTest.php
@@ -0,0 +1,217 @@
+ tag
+ *
+ * @package PHPunit
+ * @author Uwe Tews
+ */
+
+/**
+ * class for {php} and tag tests
+ *
+ * @backupStaticAt tributes enabled
+ */
+class CompilePhpTest extends PHPUnit_Smarty
+{
+ public $loadSmartyBC = true;
+ public function setUp()
+ {
+ $this->setUpSmarty(__DIR__);
+ $this->smartyBC->disableSecurity();
+ $this->smarty->disableSecurity();
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+/**
+ * test tag
+ * PHP_REMOVE
+ */
+public function testPHP_REMOVEphp()
+{
+ $this->smarty->setPhpHandling(Smarty::PHP_REMOVE);
+ $content = $this->smarty->fetch("string:ae");
+ $this->assertEquals("a echo 'hello world'; e", $content, 'remove ');
+}
+
+ /**
+ * test <%...%> tag
+ * PHP_REMOVE
+ */
+ public function testPHP_REMOVEasp()
+ {
+ if (!ini_get('asp_tags')) {
+ $this->markTestSkipped('asp tags disabled in php.ini');
+ }
+ $this->smarty->setPhpHandling(Smarty::PHP_REMOVE);
+ $content = $this->smarty->fetch("string:a<% echo 'hello world';%>e");
+ $this->assertEquals("a echo 'hello world';e", $content, 'remove <% %>');
+
+
+ }
+ /**
+ * test tag
+ * PHP_PASSTHRU
+ */
+ public function testPHP_PASSTHRUphp()
+ {
+ $this->smarty->setPhpHandling(Smarty::PHP_PASSTHRU);
+ $content = $this->smarty->fetch("string:pape");
+ $this->assertEquals("pape", $content, 'passthru ');
+ }
+ /**
+ * test <%...%> tag
+ * PHP_PASSTHRU
+ */
+ public function testPHP_PASSTHRUasp()
+ {
+ if (!ini_get('asp_tags')) {
+ $this->markTestSkipped('asp tags disabled in php.ini');
+ }
+ $this->smarty->setPhpHandling(Smarty::PHP_PASSTHRU);
+ $content = $this->smarty->fetch("string:pa<% echo 'hello world';%>pe");
+ $this->assertEquals("pa<% echo 'hello world';%>pe", $content, 'passthru <% %>');
+ }
+ /**
+ * test tag
+ * PHP_QUOTE
+ */
+ public function testPHP_QUOTEphp()
+ {
+ $this->smarty->setPhpHandling(Smarty::PHP_QUOTE);
+ $content = $this->smarty->fetch("string:qaqe");
+ $this->assertEquals("qa<?php echo 'hello world'; ?>qe", $content, 'qoute ');
+ }
+ /**
+ * test <%...%> tag
+ * PHP_QUOTE
+ */
+ public function testPHP_QUOTEasp()
+ {
+ if (!ini_get('asp_tags')) {
+ $this->markTestSkipped('asp tags disabled in php.ini');
+ }
+ $this->smarty->setPhpHandling(Smarty::PHP_QUOTE);
+ $content = $this->smarty->fetch("string:qa<% echo 'hello world';%>qe");
+ $this->assertEquals("qa<% echo 'hello world';%>qe", $content, 'qoute <% %>');
+ }
+ /**
+ * test tag
+ * PHP_ALLOW
+ */
+ public function testPHP_ALLOWphp()
+ {
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $content = $this->smartyBC->fetch("string:aa ae");
+ }
+ /**
+ * test <%...%> tag
+ * PHP_ALLOW
+ */
+ public function testPHP_ALLOWasp()
+ {
+ if (!ini_get('asp_tags')) {
+ $this->markTestSkipped('asp tags disabled in php.ini');
+ }
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $content = $this->smartyBC->fetch("string:aa <% echo 'hello world';%> ae");
+ $this->assertEquals('aa hello world ae', $content, 'allow <% %>');
+ }
+ /**
+ * test tag
+ * PHP_ALLOW
+ */
+ public function testPHP_ALLOW2()
+ {
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $content = $this->smartyBC->fetch("string:aa ae");
+ $this->assertEquals('aa tag
+ * PHP_ALLOW
+ */
+ public function testPHP_ALLOW3()
+ {
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $content = $this->smartyBC->fetch("string:aa '; ?> ae");
+ $this->assertEquals('aa ?> ae', $content);
+ }
+
+ /**
+ * test {php}{/php} tag
+ * PHP_ALLOW
+ */
+ public function testPHP_ALLOW5()
+ {
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $content = $this->smartyBC->fetch("string:aa {php} echo 'hallo'; {/php} ae");
+ $this->assertEquals('aa hallo ae', $content);
+ }
+ /**
+ * test {php}{/php} tag
+ * PHP_ALLOW
+ */
+ public function testPHP_ALLOW6()
+ {
+ $this->smartyBC->caching = 1;
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $content = $this->smartyBC->fetch("string:aa {php nocache} echo 'hallo'; {/php} ae");
+ $this->assertEquals('aa hallo ae', $content);
+ }
+
+ /**
+ * @expectedException SmartyCompilerException
+ * @expectedExceptionMessage PHP in template not allowed
+ */
+
+ public function testPHP_ALLOW_error()
+ {
+ $this->smarty->setPhpHandling(Smarty::PHP_ALLOW);
+ $content = $this->smarty->fetch("string:aa ae");
+ }
+ /**
+ * test tag
+ * default is PASSTHRU
+ */
+ public function testPhpTag()
+ {
+ $tpl = $this->smartyBC->createTemplate("eval:");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals("", $content);
+ }
+
+ // ALLOW
+ public function testPhpTagAllow()
+ {
+ $this->smartyBC->setPhpHandling(Smarty::PHP_ALLOW);
+ $this->smartyBC->disableSecurity();
+ $tpl = $this->smartyBC->createTemplate("eval:");
+ $content = $this->smartyBC->fetch($tpl);
+ $this->assertEquals('hello world', $content);
+ }
+
+ /**
+ * test =...\> shorttag
+ * default is PASSTHRU
+ */
+ public function testShortTag()
+ {
+ $this->smartyBC->assign('foo', 'bar');
+ $content = $this->smartyBC->fetch('eval:=$foo?>');
+ $this->assertEquals('=$foo?>', $content);
+ }
+ /**
+ * PHP tag data provider
+ */
+ public function includeProvider()
+ {
+ return array(
+ array(SMARTY::PHP_REMOVE, 'normal'),
+ array(true, 'merged'),
+ );
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginBlock/PluginBlockTextformatTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginBlock/PluginBlockTextformatTest.php
new file mode 100644
index 00000000..6c0cf89c
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginBlock/PluginBlockTextformatTest.php
@@ -0,0 +1,134 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testDefault()
+ {
+ $result = "\n\nThis is foo. This is foo. This is foo.\nThis is foo. This is foo. This is foo.\n\nThis is bar.\n\nbar foo bar foo foo. bar foo bar foo\nfoo. bar foo bar foo foo. bar foo bar\nfoo foo. bar foo bar foo foo. bar foo\nbar foo foo. bar foo bar foo foo.\n\n";
+ $tpl = $this->smarty->createTemplate('eval:{textformat wrap=40}' . $this->string . '{/textformat}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($this->smarty->fetch($tpl)));
+ }
+
+ public function testDefaultWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "\n\nThis is foo. This is foo. This is foo.\nThis is foo. This is foo. This is foo.\n\nThis is bar.\n\nbar foo bar foo foo. bar foo bar foo\nfoo. bar foo bar foo foo. bar foo bar\nfoo foo. bar foo bar foo foo. bar foo\nbar foo foo. bar foo bar foo foo.\n\n";
+ $tpl = $this->smarty->createTemplate('eval:{textformat wrap=40}' . $this->string . '{/textformat}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($this->smarty->fetch($tpl)));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testIndent()
+ {
+ $result = "\n\n This is foo. This is foo. This is\n foo. This is foo. This is foo. This\n is foo.\n\n This is bar.\n\n bar foo bar foo foo. bar foo bar foo\n foo. bar foo bar foo foo. bar foo\n bar foo foo. bar foo bar foo foo.\n bar foo bar foo foo. bar foo bar foo\n foo.\n\n";
+ $tpl = $this->smarty->createTemplate('eval:{textformat wrap=40 indent=4}' . $this->string . '{/textformat}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($this->smarty->fetch($tpl)));
+ }
+
+ public function testIndentWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "\n\n This is foo. This is foo. This is\n foo. This is foo. This is foo. This\n is foo.\n\n This is bar.\n\n bar foo bar foo foo. bar foo bar foo\n foo. bar foo bar foo foo. bar foo\n bar foo foo. bar foo bar foo foo.\n bar foo bar foo foo. bar foo bar foo\n foo.\n\n";
+ $tpl = $this->smarty->createTemplate('eval:{textformat wrap=40 indent=4}' . $this->string . '{/textformat}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($this->smarty->fetch($tpl)));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testIndentFirst()
+ {
+ $result = "\n\n This is foo. This is foo. This\n is foo. This is foo. This is foo.\n This is foo.\n\n This is bar.\n\n bar foo bar foo foo. bar foo bar\n foo foo. bar foo bar foo foo. bar\n foo bar foo foo. bar foo bar foo\n foo. bar foo bar foo foo. bar foo\n bar foo foo.\n\n";
+ $tpl = $this->smarty->createTemplate('eval:{textformat wrap=40 indent=4 indent_first=4}' . $this->string . '{/textformat}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($this->smarty->fetch($tpl)));
+ }
+
+ public function testIndentFirstWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "\n\n This is foo. This is foo. This\n is foo. This is foo. This is foo.\n This is foo.\n\n This is bar.\n\n bar foo bar foo foo. bar foo bar\n foo foo. bar foo bar foo foo. bar\n foo bar foo foo. bar foo bar foo\n foo. bar foo bar foo foo. bar foo\n bar foo foo.\n\n";
+ $tpl = $this->smarty->createTemplate('eval:{textformat wrap=40 indent=4 indent_first=4}' . $this->string . '{/textformat}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($this->smarty->fetch($tpl)));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testIndentchar()
+ {
+ $result = "\n\n####This is foo. This is foo. This is\n####foo. This is foo. This is foo. This\n####is foo.\n\n####This is bar.\n\n####bar foo bar foo foo. bar foo bar foo\n####foo. bar foo bar foo foo. bar foo\n####bar foo foo. bar foo bar foo foo.\n####bar foo bar foo foo. bar foo bar foo\n####foo.\n\n";
+ $tpl = $this->smarty->createTemplate('eval:{textformat wrap=40 indent=4 indent_char="#"}' . $this->string . '{/textformat}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($this->smarty->fetch($tpl)));
+ }
+
+ public function testIndentcharWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "\n\n####This is foo. This is foo. This is\n####foo. This is foo. This is foo. This\n####is foo.\n\n####This is bar.\n\n####bar foo bar foo foo. bar foo bar foo\n####foo. bar foo bar foo foo. bar foo\n####bar foo foo. bar foo bar foo foo.\n####bar foo bar foo foo. bar foo bar foo\n####foo.\n\n";
+ $tpl = $this->smarty->createTemplate('eval:{textformat wrap=40 indent=4 indent_char="#"}' . $this->string . '{/textformat}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($this->smarty->fetch($tpl)));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testIndentcharFirst()
+ {
+ $result = "\n\n########This is foo. This is foo. This\n####is foo. This is foo. This is foo.\n####This is foo.\n\n########This is bar.\n\n########bar foo bar foo foo. bar foo bar\n####foo foo. bar foo bar foo foo. bar\n####foo bar foo foo. bar foo bar foo\n####foo. bar foo bar foo foo. bar foo\n####bar foo foo.\n\n";
+ $tpl = $this->smarty->createTemplate('eval:{textformat wrap=40 indent=4 indent_first=4 indent_char="#"}' . $this->string . '{/textformat}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($this->smarty->fetch($tpl)));
+ }
+
+ public function testIndentcharFirstWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "\n\n########This is foo. This is foo. This\n####is foo. This is foo. This is foo.\n####This is foo.\n\n########This is bar.\n\n########bar foo bar foo foo. bar foo bar\n####foo foo. bar foo bar foo foo. bar\n####foo bar foo foo. bar foo bar foo\n####foo. bar foo bar foo foo. bar foo\n####bar foo foo.\n\n";
+ $tpl = $this->smarty->createTemplate('eval:{textformat wrap=40 indent=4 indent_first=4 indent_char="#"}' . $this->string . '{/textformat}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($this->smarty->fetch($tpl)));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testWrapchar()
+ {
+ $result = "## This is foo. This is foo. This is#foo. This is foo. This is foo. This#is foo.## This is bar.## bar foo bar foo foo. bar foo bar foo#foo. bar foo bar foo foo. bar foo#bar foo foo. bar foo bar foo foo.#bar foo bar foo foo. bar foo bar foo#foo.##";
+ $tpl = $this->smarty->createTemplate('eval:{textformat wrap=40 indent=4 wrap_char="#"}' . $this->string . '{/textformat}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($this->smarty->fetch($tpl)));
+ }
+
+ public function testWrapcharWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "## This is foo. This is foo. This is#foo. This is foo. This is foo. This#is foo.## This is bar.## bar foo bar foo foo. bar foo bar foo#foo. bar foo bar foo foo. bar foo#bar foo foo. bar foo bar foo foo.#bar foo bar foo foo. bar foo bar foo#foo.##";
+ $tpl = $this->smarty->createTemplate('eval:{textformat wrap=40 indent=4 wrap_char="#"}' . $this->string . '{/textformat}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($this->smarty->fetch($tpl)));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testStyleEmail()
+ {
+ $result = "\n\nThis is foo. This is foo. This is foo. This is foo. This is foo. This is\nfoo.\n\nThis is bar.\n\nbar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo\nbar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo\nfoo.\n\n";
+ $tpl = $this->smarty->createTemplate('eval:{textformat style="email"}' . $this->string . '{/textformat}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($this->smarty->fetch($tpl)));
+ }
+
+ public function testStyleEmailWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "\n\nThis is foo. This is foo. This is foo. This is foo. This is foo. This is\nfoo.\n\nThis is bar.\n\nbar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo\nbar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo\nfoo.\n\n";
+ $tpl = $this->smarty->createTemplate('eval:{textformat style="email"}' . $this->string . '{/textformat}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($this->smarty->fetch($tpl)));
+ Smarty::$_MBSTRING = true;
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionFetchTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionFetchTest.php
new file mode 100644
index 00000000..355dc16d
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionFetchTest.php
@@ -0,0 +1,25 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testTodo()
+ {
+ // TODO: UnitTests for {fetch}
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlCheckboxesTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlCheckboxesTest.php
new file mode 100644
index 00000000..22767e57
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlCheckboxesTest.php
@@ -0,0 +1,354 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testAssociativeArray()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_checkboxes name="id" options=$cust_radios selected=$customer_id separator="
"}');
+ $tpl->assign('customer_id', 1001);
+ $tpl->assign('cust_radios', array(
+ 1000 => 'Joe Schmoe',
+ 1001 => 'Jack Smith',
+ 1002 => 'Jane Johnson',
+ 1003 => 'Charlie Brown',
+ ));
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testSeparateArrays()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_checkboxes name="id" values=$cust_ids output=$cust_names selected=$customer_id separator="
"}');
+ $tpl->assign('customer_id', 1001);
+ $tpl->assign('cust_ids', array(1000, 1001, 1002, 1003));
+ $tpl->assign('cust_names', array(
+ 'Joe Schmoe',
+ 'Jack Smith',
+ 'Jane Johnson',
+ 'Charlie Brown',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testIterator()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_checkboxes name="id" values=$cust_ids output=$cust_names selected=$customer_id separator="
"}');
+ $tpl->assign('customer_id', 1001);
+ $tpl->assign('cust_ids', array(1000, 1001, 1002, 1003));
+ $tpl->assign('cust_names', new ArrayIterator(array(
+ 'Joe Schmoe',
+ 'Jack Smith',
+ 'Jane Johnson',
+ 'Charlie Brown',
+ )));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testNoLabels()
+ {
+ $n = "\n";
+ $expected = 'Joe Schmoe
'
+ . $n . 'Jack Smith
'
+ . $n . 'Jane Johnson
'
+ . $n . 'Charlie Brown
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_checkboxes name="id" options=$cust_radios labels=false selected=$customer_id separator="
"}');
+ $tpl->assign('customer_id', 1001);
+ $tpl->assign('cust_radios', array(
+ 1000 => 'Joe Schmoe',
+ 1001 => 'Jack Smith',
+ 1002 => 'Jane Johnson',
+ 1003 => 'Charlie Brown',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testWithId()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_checkboxes name="id" options=$cust_radios selected=$customer_id label_ids=true separator="
"}');
+ $tpl->assign('customer_id', 1001);
+ $tpl->assign('cust_radios', array(
+ 1000 => 'Joe Schmoe',
+ 1001 => 'Jack Smith',
+ 1002 => 'Jane Johnson',
+ 'work s ä' => 'Charlie Brown',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testNullString()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_checkboxes name="id" options=$options selected=$selected separator="
"}');
+ $tpl->assign('selected', "null");
+ $tpl->assign('options', array(
+ "null" => 'null',
+ '' => 'empty string',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testNullValue()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_checkboxes name="id" options=$options selected=$selected separator="
"}');
+ $tpl->assign('selected', null);
+ $tpl->assign('options', array(
+ "null" => 'null',
+ '' => 'empty string',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testZeroValue()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_checkboxes name="id" options=$options selected=$selected separator="
"}');
+ $tpl->assign('selected', 0);
+ $tpl->assign('options', array(
+ "null" => 'null',
+ '' => 'empty string',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testZeroStringValue()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_checkboxes name="id" options=$options selected=$selected separator="
"}');
+ $tpl->assign('selected', "0");
+ $tpl->assign('options', array(
+ "null" => 'null',
+ '' => 'empty string',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testEmptyStringValue()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_checkboxes name="id" options=$options selected=$selected separator="
"}');
+ $tpl->assign('selected', "");
+ $tpl->assign('options', array(
+ "null" => 'null',
+ '' => 'empty string',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testObject()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_checkboxes name="id" options=$cust_radios selected=$customer_id separator="
"}');
+ $tpl->assign('customer_id', new _object_toString(1001));
+ $tpl->assign('cust_radios', array(
+ 1000 => 'Joe Schmoe',
+ 1001 => 'Jack Smith',
+ 1002 => 'Jane Johnson',
+ 1003 => 'Charlie Brown',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testObjectList()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_checkboxes name="id" options=$cust_radios selected=$customer_id separator="
"}');
+ $tpl->assign('customer_id', 1001);
+ $tpl->assign('cust_radios', array(
+ 1000 => new _object_toString('Joe Schmoe'),
+ 1001 => new _object_toString('Jack Smith'),
+ 1002 => new _object_toString('Jane Johnson'),
+ 1003 => new _object_toString('Charlie Brown'),
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ protected $_errors = array();
+
+ public function error_handler($errno, $errstr, $errfile, $errline, $errcontext)
+ {
+ $this->_errors[] = $errstr;
+ }
+
+ public function testObjectNoString()
+ {
+ $this->_errors = array();
+ set_error_handler(array($this, 'error_handler'));
+
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_checkboxes name="id" options=$cust_radios selected=$customer_id separator="
"}');
+ $tpl->assign('customer_id', new _object_noString(1001));
+ $tpl->assign('cust_radios', array(
+ 1000 => 'Joe Schmoe',
+ 1001 => 'Jack Smith',
+ 1002 => 'Jane Johnson',
+ 1003 => 'Charlie Brown',
+ ));
+
+ $tpl->fetch();
+ $this->assertEquals(1, count($this->_errors));
+ $this->assertStringEndsWith("without __toString() method", $this->_errors[0]);
+
+ restore_error_handler();
+ }
+
+ public function testObjectListNoString()
+ {
+ $this->_errors = array();
+ set_error_handler(array($this, 'error_handler'));
+
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_checkboxes name="id" options=$cust_radios selected=$customer_id separator="
"}');
+ $tpl->assign('customer_id', 1001);
+ $tpl->assign('cust_radios', array(
+ 1000 => new _object_toString('Joe Schmoe'),
+ 1001 => new _object_noString('Jack Smith'),
+ 1002 => new _object_toString('Jane Johnson'),
+ 1003 => new _object_toString('Charlie Brown'),
+ ));
+
+ $tpl->fetch();
+ $this->assertEquals(1, count($this->_errors));
+ $this->assertStringEndsWith("without __toString() method", $this->_errors[0]);
+
+ restore_error_handler();
+ }
+
+ public function testDisabled()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_checkboxes name="id" options=$cust_radios selected=$customer_id separator="
" disabled="1"}');
+ $tpl->assign('customer_id', new _object_toString(1001));
+ $tpl->assign('cust_radios', array(
+ 1000 => 'Joe Schmoe',
+ 1001 => 'Jack Smith',
+ 1002 => 'Jane Johnson',
+ 1003 => 'Charlie Brown',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlImageTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlImageTest.php
new file mode 100644
index 00000000..760c094a
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlImageTest.php
@@ -0,0 +1,25 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testFoo()
+ {
+ // TODO: UnitTests for {html_image}
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlOptionsTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlOptionsTest.php
new file mode 100644
index 00000000..7c2e0ac4
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlOptionsTest.php
@@ -0,0 +1,446 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testAssociativeArray()
+ {
+ $n = "\n";
+ $expected = '' . $n;
+
+ $tpl = $this->smarty->createTemplate('eval:{html_options name="foo" options=$myOptions selected=$mySelect}');
+ $tpl->assign('mySelect', 9904);
+ $tpl->assign('myOptions', array(
+ 1800 => 'Joe Schmoe',
+ 9904 => 'Jack Smith',
+ 2003 => 'Charlie Brown',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testSeparateArrays()
+ {
+ $n = "\n";
+ $expected = '' . $n;
+
+ $tpl = $this->smarty->createTemplate('eval:{html_options name="foo" values=$cust_ids output=$cust_names selected=$customer_id}');
+ $tpl->assign('customer_id', 92);
+ $tpl->assign('cust_ids', array(56, 92, 13));
+ $tpl->assign('cust_names', array(
+ 'Joe Schmoe',
+ 'Jane Johnson',
+ 'Charlie Brown',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testIterator()
+ {
+ $n = "\n";
+ $expected = '' . $n;
+
+ $tpl = $this->smarty->createTemplate('eval:{html_options name="foo" options=$myOptions selected=$mySelect}');
+ $tpl->assign('mySelect', 9904);
+ $tpl->assign('myOptions', new ArrayIterator(array(
+ 1800 => 'Joe Schmoe',
+ 9904 => 'Jack Smith',
+ 2003 => 'Charlie Brown',
+ )));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testOptgroup()
+ {
+ $n = "\n";
+ $expected = '' . $n;
+
+ $tpl = $this->smarty->createTemplate('eval:{html_options name=foo options=$lookups selected=$fav}');
+ $tpl->assign('fav', 7);
+ $tpl->assign('lookups', array(
+ 'Sport' => array(
+ 6 => 'Golf',
+ 9 => 'Cricket',
+ 7 => 'Swim'
+ ),
+ 'Rest' => array(
+ 3 => 'Sauna',
+ 1 => 'Massage'
+ ),
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testNullString()
+ {
+ $n = "\n";
+ $expected = '' . $n;
+
+ $tpl = $this->smarty->createTemplate('eval:{html_options name=foo options=$array selected=$selected}');
+ $tpl->assign('selected', "null");
+ $tpl->assign('array', array(
+ 'null' => 'null',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ 'optgroup' => array(
+ 'null' => 'null',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ ),
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testNullValue()
+ {
+ $n = "\n";
+ $expected = '' . $n;
+
+ $tpl = $this->smarty->createTemplate('eval:{html_options name=foo options=$array selected=$selected}');
+ $tpl->assign('selected', null);
+ $tpl->assign('array', array(
+ '' => 'empty string',
+ 'null' => 'null',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ 'optgroup' => array(
+ '' => 'empty string',
+ 'null' => 'null',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ ),
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testZeroValue()
+ {
+ $n = "\n";
+ $expected = '' . $n;
+
+ $tpl = $this->smarty->createTemplate('eval:{html_options name=foo options=$array selected=$selected}');
+ $tpl->assign('selected', 0);
+ $tpl->assign('array', array(
+ 'null' => 'null',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ 'optgroup' => array(
+ 'null' => 'null',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ ),
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testZeroStringValue()
+ {
+ $n = "\n";
+ $expected = '' . $n;
+
+ $tpl = $this->smarty->createTemplate('eval:{html_options name=foo options=$array selected=$selected}');
+ $tpl->assign('selected', "0");
+ $tpl->assign('array', array(
+ 'null' => "null",
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ 'optgroup' => array(
+ 'null' => 'null',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ ),
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testEmptyStringValue()
+ {
+ $n = "\n";
+ $expected = '' . $n;
+
+ $tpl = $this->smarty->createTemplate('eval:{html_options name=foo options=$array selected=$selected}');
+ $tpl->assign('selected', "");
+ $tpl->assign('array', array(
+ 'null' => 'null',
+ '0' => 'zero',
+ '1' => 'one',
+ '2' => 'two',
+ 'optgroup' => array(
+ 'null' => 'null',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ ),
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testEmptyStringValues()
+ {
+ $n = "\n";
+ $expected = '' . $n;
+
+ $tpl = $this->smarty->createTemplate('eval:{html_options name=foo options=$array selected=$selected}');
+ $tpl->assign('selected', "");
+ $tpl->assign('array', array(
+ '' => 'empty string',
+ 'null' => 'null',
+ '0' => 'zero',
+ '1' => 'one',
+ '2' => 'two',
+ 'optgroup' => array(
+ '' => 'empty string',
+ 'null' => 'null',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ ),
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testObject()
+ {
+ $n = "\n";
+ $expected = '' . $n;
+
+ $tpl = $this->smarty->createTemplate('eval:{html_options name="foo" options=$myOptions selected=$mySelect}');
+ $tpl->assign('mySelect', new _object_toString(9904));
+ $tpl->assign('myOptions', array(
+ 1800 => 'Joe Schmoe',
+ 9904 => 'Jack Smith',
+ 2003 => 'Charlie Brown',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testObjectList()
+ {
+ $n = "\n";
+ $expected = '' . $n;
+
+ $tpl = $this->smarty->createTemplate('eval:{html_options name="foo" options=$myOptions selected=$mySelect}');
+ $tpl->assign('mySelect', new _object_toString(9904));
+ $tpl->assign('myOptions', array(
+ 1800 => new _object_toString('Joe Schmoe'),
+ 9904 => new _object_toString('Jack Smith'),
+ 2003 => new _object_toString('Charlie Brown'),
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ protected $_errors = array();
+
+ public function error_handler($errno, $errstr, $errfile, $errline, $errcontext)
+ {
+ $this->_errors[] = $errstr;
+ }
+
+ public function testObjectNoString()
+ {
+ $this->_errors = array();
+ set_error_handler(array($this, 'error_handler'));
+ $n = "\n";
+ $expected = '' . $n;
+
+ $tpl = $this->smarty->createTemplate('eval:{html_options name="foo" options=$myOptions selected=$mySelect}');
+ $tpl->assign('mySelect', new _object_noString(9904));
+ $tpl->assign('myOptions', array(
+ 1800 => 'Joe Schmoe',
+ 9904 => 'Jack Smith',
+ 2003 => 'Charlie Brown',
+ ));
+
+ $tpl->fetch();
+ $this->assertEquals(1, count($this->_errors));
+ $this->assertStringEndsWith("without __toString() method", $this->_errors[0]);
+
+ restore_error_handler();
+ }
+
+ public function testObjectListNoString()
+ {
+ $this->_errors = array();
+ set_error_handler(array($this, 'error_handler'));
+ $n = "\n";
+ $expected = '' . $n;
+
+ $tpl = $this->smarty->createTemplate('eval:{html_options name="foo" options=$myOptions selected=$mySelect}');
+ $tpl->assign('mySelect', new _object_toString(9904));
+ $tpl->assign('myOptions', array(
+ 1800 => new _object_toString('Joe Schmoe'),
+ 9904 => new _object_noString('Jack Smith'),
+ 2003 => new _object_toString('Charlie Brown'),
+ ));
+
+ $tpl->fetch();
+ $this->assertEquals(1, count($this->_errors));
+ $this->assertStringEndsWith("without __toString() method", $this->_errors[0]);
+
+ restore_error_handler();
+ }
+
+ public function testDisabled()
+ {
+ $n = "\n";
+ $expected = '' . $n;
+
+ $tpl = $this->smarty->createTemplate('eval:{html_options name="foo" options=$myOptions selected=$mySelect disabled=1}');
+ $tpl->assign('mySelect', new _object_toString(9904));
+ $tpl->assign('myOptions', array(
+ 1800 => 'Joe Schmoe',
+ 9904 => 'Jack Smith',
+ 2003 => 'Charlie Brown',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlRadiosTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlRadiosTest.php
new file mode 100644
index 00000000..73cf626d
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlRadiosTest.php
@@ -0,0 +1,353 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testAssociativeArray()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_radios name="id" options=$cust_radios selected=$customer_id separator="
"}');
+ $tpl->assign('customer_id', 1001);
+ $tpl->assign('cust_radios', array(
+ 1000 => 'Joe Schmoe',
+ 1001 => 'Jack Smith',
+ 1002 => 'Jane Johnson',
+ 1003 => 'Charlie Brown',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testSeparateArrays()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_radios name="id" values=$cust_ids output=$cust_names selected=$customer_id separator="
"}');
+ $tpl->assign('customer_id', 1001);
+ $tpl->assign('cust_ids', array(1000, 1001, 1002, 1003));
+ $tpl->assign('cust_names', array(
+ 'Joe Schmoe',
+ 'Jack Smith',
+ 'Jane Johnson',
+ 'Charlie Brown',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testIterator()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_radios name="id" values=$cust_ids output=$cust_names selected=$customer_id separator="
"}');
+ $tpl->assign('customer_id', 1001);
+ $tpl->assign('cust_ids', array(1000, 1001, 1002, 1003));
+ $tpl->assign('cust_names', new ArrayIterator(array(
+ 'Joe Schmoe',
+ 'Jack Smith',
+ 'Jane Johnson',
+ 'Charlie Brown',
+ )));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testNoLabels()
+ {
+ $n = "\n";
+ $expected = 'Joe Schmoe
'
+ . $n . 'Jack Smith
'
+ . $n . 'Jane Johnson
'
+ . $n . 'Charlie Brown
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_radios name="id" options=$cust_radios labels=false selected=$customer_id separator="
"}');
+ $tpl->assign('customer_id', 1001);
+ $tpl->assign('cust_radios', array(
+ 1000 => 'Joe Schmoe',
+ 1001 => 'Jack Smith',
+ 1002 => 'Jane Johnson',
+ 1003 => 'Charlie Brown',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testWithId()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_radios name="id" options=$cust_radios selected=$customer_id label_ids=true separator="
"}');
+ $tpl->assign('customer_id', 1001);
+ $tpl->assign('cust_radios', array(
+ 1000 => 'Joe Schmoe',
+ 1001 => 'Jack Smith',
+ 1002 => 'Jane Johnson',
+ 'work s ä' => 'Charlie Brown',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testNullString()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_radios name="id" options=$options selected=$selected separator="
"}');
+ $tpl->assign('selected', "null");
+ $tpl->assign('options', array(
+ "null" => 'null',
+ '' => 'empty string',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testNullValue()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_radios name="id" options=$options selected=$selected separator="
"}');
+ $tpl->assign('selected', null);
+ $tpl->assign('options', array(
+ "null" => 'null',
+ '' => 'empty string',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testZeroValue()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_radios name="id" options=$options selected=$selected separator="
"}');
+ $tpl->assign('selected', 0);
+ $tpl->assign('options', array(
+ "null" => 'null',
+ '' => 'empty string',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testZeroStringValue()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_radios name="id" options=$options selected=$selected separator="
"}');
+ $tpl->assign('selected', "0");
+ $tpl->assign('options', array(
+ "null" => 'null',
+ '' => 'empty string',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testEmptyStringValue()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_radios name="id" options=$options selected=$selected separator="
"}');
+ $tpl->assign('selected', "");
+ $tpl->assign('options', array(
+ "null" => 'null',
+ '' => 'empty string',
+ 0 => 'zero',
+ 1 => 'one',
+ 2 => 'two',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testObject()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_radios name="id" options=$cust_radios selected=$customer_id separator="
"}');
+ $tpl->assign('customer_id', new _object_toString(1001));
+ $tpl->assign('cust_radios', array(
+ 1000 => 'Joe Schmoe',
+ 1001 => 'Jack Smith',
+ 1002 => 'Jane Johnson',
+ 1003 => 'Charlie Brown',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testObjectList()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_radios name="id" options=$cust_radios selected=$customer_id separator="
"}');
+ $tpl->assign('customer_id', 1001);
+ $tpl->assign('cust_radios', array(
+ 1000 => new _object_toString('Joe Schmoe'),
+ 1001 => new _object_toString('Jack Smith'),
+ 1002 => new _object_toString('Jane Johnson'),
+ 1003 => new _object_toString('Charlie Brown'),
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+
+ protected $_errors = array();
+
+ public function error_handler($errno, $errstr, $errfile, $errline, $errcontext)
+ {
+ $this->_errors[] = $errstr;
+ }
+
+ public function testObjectNoString()
+ {
+ $this->_errors = array();
+ set_error_handler(array($this, 'error_handler'));
+
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_radios name="id" options=$cust_radios selected=$customer_id separator="
"}');
+ $tpl->assign('customer_id', new _object_noString(1001));
+ $tpl->assign('cust_radios', array(
+ 1000 => 'Joe Schmoe',
+ 1001 => 'Jack Smith',
+ 1002 => 'Jane Johnson',
+ 1003 => 'Charlie Brown',
+ ));
+
+ $tpl->fetch();
+ $this->assertEquals(1, count($this->_errors));
+ $this->assertStringEndsWith("without __toString() method", $this->_errors[0]);
+
+ restore_error_handler();
+ }
+
+ public function testObjectListNoString()
+ {
+ $this->_errors = array();
+ set_error_handler(array($this, 'error_handler'));
+
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_radios name="id" options=$cust_radios selected=$customer_id separator="
"}');
+ $tpl->assign('customer_id', 1001);
+ $tpl->assign('cust_radios', array(
+ 1000 => new _object_toString('Joe Schmoe'),
+ 1001 => new _object_noString('Jack Smith'),
+ 1002 => new _object_toString('Jane Johnson'),
+ 1003 => new _object_toString('Charlie Brown'),
+ ));
+
+ $tpl->fetch();
+ $this->assertEquals(1, count($this->_errors));
+ $this->assertStringEndsWith("without __toString() method", $this->_errors[0]);
+
+ restore_error_handler();
+ }
+
+ public function testDisabled()
+ {
+ $n = "\n";
+ $expected = '
'
+ . $n . '
'
+ . $n . '
'
+ . $n . '
';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_radios name="id" options=$cust_radios selected=$customer_id separator="
" disabled=1}');
+ $tpl->assign('customer_id', new _object_toString(1001));
+ $tpl->assign('cust_radios', array(
+ 1000 => 'Joe Schmoe',
+ 1001 => 'Jack Smith',
+ 1002 => 'Jane Johnson',
+ 1003 => 'Charlie Brown',
+ ));
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($tpl->fetch()));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlSelectDateTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlSelectDateTest.php
new file mode 100644
index 00000000..6767a726
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlSelectDateTest.php
@@ -0,0 +1,602 @@
+ '
+
+
+
+
+
+
+
+
+
+
+',
+ 'default' => '
+
+
+
+
+
+
+
+
+
+
+',
+ 'format_%b' => '
+
+
+
+
+
+
+
+
+
+
+',
+ 'format_value_%b' => '
+
+
+
+
+
+
+
+
+
+
+',
+ 'names' => '
+
+
+
+
+
+
+
+
+
+
+',
+ );
+
+ protected $days = array(
+ 'none' => '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+ 'default' => '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+ 'format_%03d' => '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+ 'format_value_%03d' => '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+ );
+
+ public function setUp()
+ {
+ $this->setUpSmarty(__DIR__);
+
+ $year = date('Y');
+ $this->now = mktime(15, 0, 0, 2, 20, $year);
+ $o = '';
+ for ($i = 2005; $i < $year; $i ++) {
+ $o .= "\n";
+ }
+ $o .= "";
+ $this->years['start_2005'] = $o;
+ $this->years['end_2005'] = $o;
+
+ $o = "";
+ for ($i = $year + 1; $i < $year + 6; $i ++) {
+ $o .= "\n";
+ }
+ $this->years['start_+5'] = $o;
+ $this->years['end_+5'] = $o;
+
+ $o = '';
+ for ($i = $year - 5; $i < $year; $i ++) {
+ $o .= "\n";
+ }
+ $o .= "";
+ $this->years['start_-5'] = $o;
+ $this->years['end_-5'] = $o;
+
+ $this->years['default'] = "";
+ $this->years['none'] = "";
+ }
+
+ protected function reverse($string)
+ {
+ $t = explode("\n", $string);
+ $t = array_reverse($t);
+
+ return join("\n", $t);
+ }
+
+ public function testDefault()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . '}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testPrefix()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' prefix="foobar_"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testFieldArray()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' field_array="namorized"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' field_array="namorized" prefix="foobar_"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testExtra()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' all_extra="data-foo=\"xy\""}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' day_extra="data-foo=\"day\"" month_extra="data-foo=\"month\"" year_extra="data-foo=\"year\""}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' data_foo="foo"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testFieldOrder()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' field_order="DMY"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' field_order="YMD"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testFieldSeparator()
+ {
+ $n = "\n";
+ $result = ''
+ . ' - '
+ . ' - ';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' field_order="DMY" field_separator=" - "}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+
+ $result = ''
+ . ' / '
+ . ' / ';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' field_order="YMD" field_separator=" / "}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testEmpty()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' all_empty=""}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' all_empty="all"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' year_empty=""}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' year_empty="year" month_empty="month" day_empty="day"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testEmptyUnset()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=null all_empty=""}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=null all_empty="all"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=null year_empty=""}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=null year_empty="year" month_empty="month" day_empty="day"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testId()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' all_id=""}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' all_id="all-"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' year_id="year" month_id="month" day_id="day"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testStartYearAbsolute()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' start_year=2005}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testStartYearRelative()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' start_year="+5"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testStartYearRelativeNegative()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' start_year="-5"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testEndYearAbsolute()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' end_year=2005}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testEndYearRelative()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' end_year="+5"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testEndYearRelativeNegative()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' end_year="-5"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testDisplayDaysMonthYear()
+ {
+ $n = "\n";
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' display_days=false}');
+ $result = ''
+ . $n . '';
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' display_months=false}');
+ $result = ''
+ . $n . '';
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' display_years=false}');
+ $result = ''
+ . $n . '';
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testYearsReversed()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' start_year=2005 reverse_years=true}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' start_year="+5" reverse_years=true}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testYearText()
+ {
+ $year = date('Y');
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . "";
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' year_as_text=true}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+
+ $result = ''
+ . $n . ''
+ . $n . "";
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' year_as_text=true prefix="foo_"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testMonthFormat()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' month_format="%b"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testMonthFormatValue()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' month_value_format="%b"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testMonthNames()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{$names = [1 => "alpha","bravo","charlie","delta","echo","foxtrot","golf","hotel","india","juliet","kilo","lima"]}{html_select_date time=' . $this->now . ' month_names=$names}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testDayFormat()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' day_format="%03d"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testDayFormatValue()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=' . $this->now . ' day_value_format="%03d"}');
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+
+ public function testTimeArray()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+
+ $date_array = array(
+ 'namorized' => array(
+ 'foobar_Month' => '02',
+ 'foobar_Day' => '20',
+ 'foobar_Year' => date('Y'),
+ ),
+ );
+
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=$date_array.namorized field_array="namorized" prefix="foobar_"}');
+ $tpl->assign('date_array', $date_array);
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+
+ $tpl = $this->smarty->createTemplate('eval:{html_select_date time=$date_array field_array="namorized" prefix="foobar_"}');
+ $tpl->assign('date_array', $date_array);
+ $this->assertEquals($this->normalizeString($result), $this->normalizeString($tpl->fetch()));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlSelectTimeTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlSelectTimeTest.php
new file mode 100644
index 00000000..6584d7f4
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionHtmlSelectTimeTest.php
@@ -0,0 +1,1126 @@
+setUpSmarty(__DIR__);
+ $this->now = mktime(16, 15, 11, 2, 20, 2011);
+ }
+
+ protected $now = null;
+ protected $hours = array(
+ 'none' => '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+ 'default' => '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+ '12h' => '
+
+
+
+
+
+
+
+
+
+
+',
+ 'format_%03d' => '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+ 'format_value_%03d' => '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+ );
+ protected $minutes = array(
+ 'none' => '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+ 'default' => '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+ '30' => '
+',
+ '15' => '
+
+
+',
+ '10' => '
+
+
+
+
+',
+ '5' => '
+
+
+
+
+
+
+
+
+
+
+',
+ 'format_%03d' => '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+ 'format_value_%03d' => '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+ );
+ protected $seconds = array(
+ 'none' => '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+ 'default' => '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+ '30' => '
+',
+ '15' => '
+
+
+',
+ '10' => '
+
+
+
+
+',
+ '5' => '
+
+
+
+
+
+
+
+
+
+
+',
+ 'format_%03d' => '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+ 'format_value_%03d' => '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+ );
+ protected $meridians = array(
+ 'default' => '
+',
+ );
+
+ public function testDefault()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . '}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testPrefix()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' prefix="foobar_"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testFieldArray()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' field_array="namorized"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' field_array="namorized" prefix="foobar_"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testExtra()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' all_extra="data-foo=\"xy\""}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' hour_extra="data-foo=\"hour\"" minute_extra="data-foo=\"minute\"" second_extra="data-foo=\"second\""}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' data_foo="foo"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testFieldSeparator()
+ {
+ $n = "\n";
+ $result = ''
+ . ' - '
+ . ' - ';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' field_separator=" - "}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testEmpty()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' all_empty=""}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' all_empty="all"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' second_empty=""}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' hour_empty="hour" minute_empty="minute" second_empty="second"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testEmptyUnset()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=null all_empty=""}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=null all_empty="all"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=null second_empty=""}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=null hour_empty="hour" minute_empty="minute" second_empty="second"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testId()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' all_id=""}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' all_id="all-"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' hour_id="hour" minute_id="minute" second_id="second"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testDisplay()
+ {
+ $n = "\n";
+ $result = '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' display_minutes=false display_seconds=false}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+
+ $result = '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' display_hours=false display_seconds=false}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+
+ $result = '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' display_hours=false display_minutes=false}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testMeridian1()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' use_24_hours=false}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+ public function testMeridian2()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' use_24_hours=false display_meridian=false}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testMeridian4()
+ {
+ $n = "\n";
+
+ $time = mktime(4, 15, 11, 2, 20, 2011);
+ $result = '
+';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $time . ' use_24_hours=false display_minutes=false display_seconds=false}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+ public function testMeridian5()
+ {
+ $n = "\n";
+
+ $time = mktime(12, 15, 11, 2, 20, 2011);
+ $result = '
+';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $time . ' use_24_hours=false display_minutes=false display_seconds=false}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+ public function testMeridian6()
+ {
+ $n = "\n";
+
+ $time = mktime(16, 15, 11, 2, 20, 2011);
+ $result = '
+';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $time . ' use_24_hours=false display_minutes=false display_seconds=false}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testMinuteInterval1()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' minute_interval=30}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+ public function testMinuteInterval2()
+ {
+ $n = "\n";
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' minute_interval=15}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+ public function testMinuteInterval3()
+ {
+ $n = "\n";
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' minute_interval=10}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+ public function testMinuteInterval4()
+ {
+ $n = "\n";
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' minute_interval=5}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testSecondInterval1()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' second_interval=30}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+ public function testSecondInterval2()
+ {
+ $n = "\n";
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' second_interval=15}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+ public function testSecondInterval3()
+ {
+ $n = "\n";
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' second_interval=10}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+ public function testSecondInterval4()
+ {
+ $n = "\n";
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' second_interval=5}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testFormat1()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' hour_format="%03d"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+ public function testFormat2()
+ {
+ $n = "\n";
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' minute_format="%03d"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+ public function testFormat3()
+ {
+ $n = "\n";
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' second_format="%03d"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testValueFormat1()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' hour_value_format="%03d"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+ public function testValueFormat2()
+ {
+ $n = "\n";
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' minute_value_format="%03d"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+ public function testValueFormat3()
+ {
+ $n = "\n";
+
+ $result = ''
+ . $n . ''
+ . $n . '';
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=' . $this->now . ' second_value_format="%03d"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testTimeArray1()
+ {
+ $n = "\n";
+ $time_array = array(
+ 'namorized' => array(
+ 'foobar_Hour' => '16',
+ 'foobar_Minute' => '15',
+ 'foobar_Second' => '11',
+ ),
+ );
+ $result = ''
+ . $n . ''
+ . $n . '';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=$time_array.namorized field_array="namorized" prefix="foobar_"}');
+ $tpl->assign('time_array', $time_array);
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+ public function testTimeArray2()
+ {
+ $n = "\n";
+ $time_array = array(
+ 'namorized' => array(
+ 'foobar_Hour' => '16',
+ 'foobar_Minute' => '15',
+ 'foobar_Second' => '11',
+ ),
+ );
+ $result = ''
+ . $n . ''
+ . $n . '';
+
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=$time_array field_array="namorized" prefix="foobar_"}');
+ $tpl->assign('time_array', $time_array);
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testTimeArrayMerdidian()
+ {
+ $n = "\n";
+ $result = ''
+ . $n . ''
+ . $n . ''
+ . $n . '';
+
+ $time_array = array(
+ 'namorized' => array(
+ 'foobar_Hour' => '04',
+ 'foobar_Minute' => '15',
+ 'foobar_Second' => '11',
+ 'foobar_Meridian' => 'pm',
+ ),
+ );
+
+ $tpl = $this->smarty->createTemplate('eval:{html_select_time time=$time_array use_24_hours=false field_array="namorized" prefix="foobar_"}');
+ $tpl->assign('time_array', $time_array);
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionMailtoTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionMailtoTest.php
new file mode 100644
index 00000000..c7c8f77d
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/PluginFunctionMailtoTest.php
@@ -0,0 +1,164 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testDefault()
+ {
+ $result = 'me@example.com';
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testDefaultWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = 'me@example.com';
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testText()
+ {
+ $result = 'send me some mail';
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" text="send me some mail"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testTextWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = 'send me some mail';
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" text="send me some mail"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testEncodeJavascript()
+ {
+ $result = '';
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" encode="javascript"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testEncodeJavascriptWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = '';
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" encode="javascript"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testEncodeJavascriptCharcode()
+ {
+ $result = "\n";
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" encode="javascript_charcode"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testEncodeJavascriptCharcodeWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "\n";
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" encode="javascript_charcode"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testEncodeHex()
+ {
+ $result = 'me@example.com';
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" encode="hex"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testEncodeHexWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = 'me@example.com';
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" encode="hex"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testSubject()
+ {
+ $result = 'me@example.com';
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" subject="Hello to you!"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testSubjectWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = 'me@example.com';
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" subject="Hello to you!"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testCc()
+ {
+ $result = 'me@example.com';
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" cc="you@example.com,they@example.com"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testCcWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = 'me@example.com';
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" cc="you@example.com,they@example.com"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testExtra()
+ {
+ $result = 'me@example.com';
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" extra=\'class="email"\'}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testExtraWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = 'me@example.com';
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" extra=\'class="email"\'}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testUmlauts()
+ {
+ $result = 'me+smtpext@example.com';
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me+smtpext@example.com" cc="you@example.com,they@example.com" subject="hällo wörld"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testUmlautsWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = 'me+smtpext@example.com';
+ $tpl = $this->smarty->createTemplate('eval:{mailto address="me+smtpext@example.com" cc="you@example.com,they@example.com" subject="hällo wörld"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginFunction/helpers/_object_tostring.php b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/helpers/_object_tostring.php
new file mode 100644
index 00000000..4cb55e7f
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginFunction/helpers/_object_tostring.php
@@ -0,0 +1,26 @@
+string = (string) $string;
+ }
+
+ public function __toString()
+ {
+ return $this->string;
+ }
+}
+
+class _object_noString
+{
+ protected $string = null;
+
+ public function __construct($string)
+ {
+ $this->string = (string) $string;
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCapitalizeTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCapitalizeTest.php
new file mode 100644
index 00000000..b467cc2f
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCapitalizeTest.php
@@ -0,0 +1,135 @@
+setUpSmarty(__DIR__);
+ error_reporting(E_ALL & ~E_DEPRECATED | E_STRICT);
+ }
+
+ public function testDefault()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, delayed. ümlauts äre cööl."|capitalize}');
+ $this->assertEquals("Next X-Men FiLm, x3, Delayed. Ümlauts Äre Cööl.", $this->smarty->fetch($tpl));
+ }
+
+ public function testDigits()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, delayed. ümlauts äre cööl."|capitalize:true}');
+ $this->assertEquals("Next X-Men FiLm, X3, Delayed. Ümlauts Äre Cööl.", $this->smarty->fetch($tpl));
+ }
+
+ public function testTrueCaptials()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, delayed. ümlauts äre cööl."|capitalize:true:true}');
+ $this->assertEquals("Next X-Men Film, X3, Delayed. Ümlauts Äre Cööl.", $this->smarty->fetch($tpl));
+ }
+
+ public function testDefaultWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, delayed."|capitalize}');
+ $this->assertEquals("Next X-Men FiLm, x3, Delayed.", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testDigitsWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, delayed."|capitalize:true}');
+ $this->assertEquals("Next X-Men FiLm, X3, Delayed.", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testTrueCaptialsWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, delayed."|capitalize:true:true}');
+ $this->assertEquals("Next X-Men Film, X3, Delayed.", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testQuotes()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, \"delayed. umlauts\" foo."|capitalize}');
+ $this->assertEquals("Next X-Men FiLm, x3, \"Delayed. Umlauts\" Foo.", $this->smarty->fetch($tpl));
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, \'delayed. umlauts\' foo."|capitalize}');
+ $this->assertEquals("Next X-Men FiLm, x3, 'Delayed. Umlauts' Foo.", $this->smarty->fetch($tpl));
+ }
+
+ public function testQuotesWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, \"delayed. umlauts\" foo."|capitalize}');
+ $this->assertEquals("Next X-Men FiLm, x3, \"Delayed. Umlauts\" Foo.", $this->smarty->fetch($tpl));
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, \'delayed. umlauts\' foo."|capitalize}');
+ $this->assertEquals("Next X-Men FiLm, x3, 'Delayed. Umlauts' Foo.", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testQuotesDigits()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, \"delayed. umlauts\" foo."|capitalize:true}');
+ $this->assertEquals("Next X-Men FiLm, X3, \"Delayed. Umlauts\" Foo.", $this->smarty->fetch($tpl));
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, \'delayed. umlauts\' foo."|capitalize:true}');
+ $this->assertEquals("Next X-Men FiLm, X3, 'Delayed. Umlauts' Foo.", $this->smarty->fetch($tpl));
+ }
+
+ public function testQuotesDigitsWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, \"delayed. umlauts\" foo."|capitalize:true}');
+ $this->assertEquals("Next X-Men FiLm, X3, \"Delayed. Umlauts\" Foo.", $this->smarty->fetch($tpl));
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, \'delayed. umlauts\' foo."|capitalize:true}');
+ $this->assertEquals("Next X-Men FiLm, X3, 'Delayed. Umlauts' Foo.", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testQuotesTrueCapitals()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, \"delayed. umlauts\" foo."|capitalize:true:true}');
+ $this->assertEquals("Next X-Men Film, X3, \"Delayed. Umlauts\" Foo.", $this->smarty->fetch($tpl));
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, \'delayed. umlauts\' foo."|capitalize:true:true}');
+ $this->assertEquals("Next X-Men Film, X3, 'Delayed. Umlauts' Foo.", $this->smarty->fetch($tpl));
+ }
+
+ public function testQuotesTrueCapitalsWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, \"delayed. umlauts\" foo."|capitalize:true:true}');
+ $this->assertEquals("Next X-Men Film, X3, \"Delayed. Umlauts\" Foo.", $this->smarty->fetch($tpl));
+ $tpl = $this->smarty->createTemplate('eval:{"next x-men fiLm, x3, \'delayed. umlauts\' foo."|capitalize:true:true}');
+ $this->assertEquals("Next X-Men Film, X3, 'Delayed. Umlauts' Foo.", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testQuotesBeginning()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"\"delayed. umlauts\" foo."|capitalize}');
+ $this->assertEquals("\"Delayed. Umlauts\" Foo.", $this->smarty->fetch($tpl));
+ $tpl = $this->smarty->createTemplate('eval:{"\'delayed. umlauts\' foo."|capitalize}');
+ $this->assertEquals("'Delayed. Umlauts' Foo.", $this->smarty->fetch($tpl));
+ }
+
+ public function testQuotesBeginningWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"\"delayed. umlauts\" foo."|capitalize}');
+ $this->assertEquals("\"Delayed. Umlauts\" Foo.", $this->smarty->fetch($tpl));
+ $tpl = $this->smarty->createTemplate('eval:{"\'delayed. umlauts\' foo."|capitalize}');
+ $this->assertEquals("'Delayed. Umlauts' Foo.", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCharsetTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCharsetTest.php
new file mode 100644
index 00000000..337fa8fc
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCharsetTest.php
@@ -0,0 +1,92 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testToLatin1()
+ {
+ $encoded = "hällö wörld 1";
+ $result = utf8_decode($encoded);
+ $tpl = $this->smarty->createTemplate('eval:{"' . $encoded . '"|to_charset}');
+ $this->assertEquals(str_replace("\r", '', $result), $tpl->fetch());
+ }
+
+ public function testToLatin1WithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $encoded = "hällö wörld 2";
+ $result = utf8_decode($encoded);
+ $tpl = $this->smarty->createTemplate('eval:{"' . $encoded . '"|to_charset}');
+ $this->assertEquals($encoded, $tpl->fetch());
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testFromLatin1()
+ {
+ $result = "hällö wörld 3";
+ $encoded = utf8_decode($result);
+ $tpl = $this->smarty->createTemplate('eval:{"' . $encoded . '"|from_charset}');
+ $this->assertEquals(str_replace("\r", '', $result), $tpl->fetch());
+ }
+
+ public function testFromLatin1WithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "hällö wörld 4";
+ $encoded = utf8_decode($result);
+ $tpl = $this->smarty->createTemplate('eval:{"' . $encoded . '"|from_charset}');
+ $this->assertEquals($encoded, $tpl->fetch());
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testFromUtf32le()
+ {
+ $result = "hällö wörld 5";
+ $encoded = mb_convert_encoding($result, "UTF-32LE", "UTF-8");
+ $tpl = $this->smarty->createTemplate('eval:{"' . $encoded . '"|from_charset:"UTF-32LE"}');
+ $this->assertEquals(str_replace("\r", '', $result), $tpl->fetch());
+ }
+
+ public function testFromUtf32leWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "hällö wörld 6";
+ $encoded = mb_convert_encoding($result, "UTF-32LE", "UTF-8");
+ $tpl = $this->smarty->createTemplate('eval:{"' . $encoded . '"|from_charset:"UTF-32LE"}');
+ $this->assertEquals($encoded, $tpl->fetch());
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testToUtf32le()
+ {
+ $encoded = "hällö wörld 7";
+ $result = mb_convert_encoding($encoded, "UTF-32LE", "UTF-8");
+ $tpl = $this->smarty->createTemplate('eval:{"' . $encoded . '"|to_charset:"UTF-32LE"}');
+ $this->assertEquals(str_replace("\r", '', $result), $tpl->fetch());
+ }
+
+ public function testToUtf32leWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $encoded = "hällö wörld 8";
+ $result = mb_convert_encoding($encoded, "UTF-32LE", "UTF-8");
+ $tpl = $this->smarty->createTemplate('eval:{"' . $encoded . '"|to_charset:"UTF-32LE"}');
+ $this->assertEquals($encoded, $tpl->fetch());
+ Smarty::$_MBSTRING = true;
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCountCharactersTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCountCharactersTest.php
new file mode 100644
index 00000000..995f41fa
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCountCharactersTest.php
@@ -0,0 +1,84 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testDefault()
+ {
+ $result = "29";
+ $tpl = $this->smarty->createTemplate('eval:{"Cold Wave Linked to Temperatures."|count_characters}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testDefaultWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "29";
+ $tpl = $this->smarty->createTemplate('eval:{"Cold Wave Linked to Temperatures."|count_characters}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testSpaces()
+ {
+ $result = "33";
+ $tpl = $this->smarty->createTemplate('eval:{"Cold Wave Linked to Temperatures."|count_characters:true}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testSpacesWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "33";
+ $tpl = $this->smarty->createTemplate('eval:{"Cold Wave Linked to Temperatures."|count_characters:true}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testUmlauts()
+ {
+ $result = "29";
+ $tpl = $this->smarty->createTemplate('eval:{"Cold Wäve Linked tö Temperatures."|count_characters}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testUmlautsWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "29";
+ $tpl = $this->smarty->createTemplate('eval:{"Cold Wäve Linked tö Temperatures."|count_characters}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testUmlautsSpaces()
+ {
+ $result = "33";
+ $tpl = $this->smarty->createTemplate('eval:{"Cold Wäve Linked tö Temperatures."|count_characters:true}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testUmlautsSpacesWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "33";
+ $tpl = $this->smarty->createTemplate('eval:{"Cold Wäve Linked tö Temperatures."|count_characters:true}');
+ $this->assertNotEquals($result, $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCountSentencesTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCountSentencesTest.php
new file mode 100644
index 00000000..3dfef9c3
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCountSentencesTest.php
@@ -0,0 +1,56 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testDefault()
+ {
+ $tpl = $this->smarty->createTemplate('string:{"hello world."|count_sentences}');
+ $this->assertEquals("1", $this->smarty->fetch($tpl));
+ $tpl = $this->smarty->createTemplate('eval:{"hello world. I\'m another? Sentence!"|count_sentences}');
+ $this->assertEquals("3", $this->smarty->fetch($tpl));
+ $tpl = $this->smarty->createTemplate('string:{"hello world.wrong"|count_sentences}');
+ $this->assertEquals("0", $this->smarty->fetch($tpl));
+ }
+
+ public function testDefaultWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"hello world."|count_sentences}');
+ $this->assertEquals("1", $this->smarty->fetch($tpl));
+ $tpl = $this->smarty->createTemplate('eval:{"hello world. I\'m another? Sentence!"|count_sentences}');
+ $this->assertEquals("3", $this->smarty->fetch($tpl));
+ $tpl = $this->smarty->createTemplate('eval:{"hello world.wrong"|count_sentences}');
+ $this->assertEquals("0", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testUmlauts()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"hello worldä."|count_sentences}');
+ $this->assertEquals("1", $this->smarty->fetch($tpl));
+ $tpl = $this->smarty->createTemplate('eval:{"hello worldü. ä\'m another? Sentence!"|count_sentences}');
+ $this->assertEquals("3", $this->smarty->fetch($tpl));
+ $tpl = $this->smarty->createTemplate('eval:{"hello worlä.ärong"|count_sentences}');
+ $this->assertEquals("0", $this->smarty->fetch($tpl));
+ $tpl = $this->smarty->createTemplate('eval:{"hello worlä.wrong"|count_sentences}');
+ $this->assertEquals("0", $this->smarty->fetch($tpl));
+ $tpl = $this->smarty->createTemplate('eval:{"hello world.ärong"|count_sentences}');
+ $this->assertEquals("0", $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCountWordsTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCountWordsTest.php
new file mode 100644
index 00000000..8169e46d
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCountWordsTest.php
@@ -0,0 +1,68 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testDefault()
+ {
+ $result = "7";
+ $tpl = $this->smarty->createTemplate('eval:{"Dealers Will Hear Car Talk at Noon."|count_words}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testDefaultWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "7";
+ $tpl = $this->smarty->createTemplate('eval:{"Dealers Will Hear Car Talk at Noon."|count_words}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testDashes()
+ {
+ $result = "7";
+ $tpl = $this->smarty->createTemplate('eval:{"Smalltime-Dealers Will Hear Car Talk at Noon."|count_words}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testDashesWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "7";
+ $tpl = $this->smarty->createTemplate('eval:{"Smalltime-Dealers Will Hear Car Talk at Noon."|count_words}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testUmlauts()
+ {
+ $result = "7";
+ $tpl = $this->smarty->createTemplate('eval:{"Dealers Will Hear Cär Talk at Nöön."|count_words}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testUmlautsWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "7";
+ $tpl = $this->smarty->createTemplate('eval:{"Dealers Will Hear Cär Talk at Nöön."|count_words}');
+ $this->assertNotEquals($result, $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierEscapeTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierEscapeTest.php
new file mode 100644
index 00000000..a9d33c39
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierEscapeTest.php
@@ -0,0 +1,208 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testHtml()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"I\'m some to ä be \"escaped\" or ©"|escape:"html"}');
+ $this->assertEquals("I'm some <html> to ä be "escaped" or ©", $this->smarty->fetch($tpl));
+ }
+
+ public function testHtmlWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"I\'m some to ä be \"escaped\" or ©"|escape:"html"}');
+ $this->assertEquals("I'm some <html> to ä be "escaped" or ©", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testHtmlDouble()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"I\'m some to ä be \"escaped\" or ©"|escape:"html":null:false}');
+ $this->assertEquals("I'm some <html> to ä be "escaped" or ©", $this->smarty->fetch($tpl));
+ }
+
+ public function testHtmlDoubleWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"I\'m some to ä be \"escaped\" or ©"|escape:"html":null:false}');
+ $this->assertEquals("I'm some <html> to ä be "escaped" or ©", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testHtmlall()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"I\'m some to ä be \"escaped\" or ©"|escape:"htmlall"}');
+ $this->assertEquals("I'm some <html> to ä be "escaped" or ©", $this->smarty->fetch($tpl));
+ }
+
+ public function testHtmlallWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"I\'m some to ä be \"escaped\" or ©"|escape:"htmlall"}');
+ $this->assertEquals("I'm some <html> to ä be "escaped" or ©", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testHtmlallDouble()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"I\'m some to ä be \"escaped\" or ©"|escape:"htmlall":null:false}');
+ $this->assertEquals("I'm some <html> to ä be "escaped" or ©", $this->smarty->fetch($tpl));
+ }
+
+ public function testHtmlallDoubleWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"I\'m some to ä be \"escaped\" or ©"|escape:"htmlall":null:false}');
+ $this->assertEquals("I'm some <html> to ä be "escaped" or ©", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testUrl()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"http://some.encoded.com/url?parts#foo"|escape:"url"}');
+ $this->assertEquals("http%3A%2F%2Fsome.encoded.com%2Furl%3Fparts%23foo", $this->smarty->fetch($tpl));
+ }
+
+ public function testUrlWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"http://some.encoded.com/url?parts#foo"|escape:"url"}');
+ $this->assertEquals("http%3A%2F%2Fsome.encoded.com%2Furl%3Fparts%23foo", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testUrlpathinfo()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"http://some.encoded.com/url?parts#foo"|escape:"urlpathinfo"}');
+ $this->assertEquals("http%3A//some.encoded.com/url%3Fparts%23foo", $this->smarty->fetch($tpl));
+ }
+
+ public function testUrlpathinfoWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"http://some.encoded.com/url?parts#foo"|escape:"urlpathinfo"}');
+ $this->assertEquals("http%3A//some.encoded.com/url%3Fparts%23foo", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testHex()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"a/cäa"|escape:"hex"}');
+ $this->assertEquals("%61%2f%63%c3%a4%61", $this->smarty->fetch($tpl));
+ }
+
+ public function testHexWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"a/cäa"|escape:"hex"}');
+ $this->assertEquals("%61%2f%63%c3%a4%61", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testHexentity()
+ {
+ $q = "aäЗдравсствуйте";
+ $r = html_entity_decode($q, ENT_NOQUOTES, 'UTF-8');
+ $tpl = $this->smarty->createTemplate('eval:{"' . $r . '"|escape:"hexentity"}');
+ $this->assertEquals("aäЗдравсствуйте", $this->smarty->fetch($tpl));
+
+ $tpl = $this->smarty->createTemplate('eval:{"abc"|escape:"hexentity"}');
+ $this->assertEquals("abc", $this->smarty->fetch($tpl));
+ }
+
+ public function testHexentityWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $q = "aäЗдравсствуйте";
+ $r = html_entity_decode($q, ENT_NOQUOTES, 'UTF-8');
+ $tpl = $this->smarty->createTemplate('eval:{"' . $r . '"|escape:"hexentity"}');
+ $this->assertNotEquals("aäЗдравсствуйте", $this->smarty->fetch($tpl));
+
+ $tpl = $this->smarty->createTemplate('eval:{"abc"|escape:"hexentity"}');
+ $this->assertEquals("abc", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testDecentity()
+ {
+ $q = "aäЗдравсствуйте";
+ $r = html_entity_decode($q, ENT_NOQUOTES, 'UTF-8');
+ $tpl = $this->smarty->createTemplate('eval:{"' . $r . '"|escape:"decentity"}');
+ $this->assertEquals("aäЗдравсствуйте", $this->smarty->fetch($tpl));
+
+ $tpl = $this->smarty->createTemplate('eval:{"abc"|escape:"decentity"}');
+ $this->assertEquals("abc", $this->smarty->fetch($tpl));
+ }
+
+ public function testDecentityWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $q = "aäЗдравсствуйте";
+ $r = html_entity_decode($q, ENT_NOQUOTES, 'UTF-8');
+ $tpl = $this->smarty->createTemplate('eval:{"' . $r . '"|escape:"decentity"}');
+ $this->assertNotEquals("aäЗдравсствуйте", $this->smarty->fetch($tpl));
+
+ $tpl = $this->smarty->createTemplate('eval:{"abc"|escape:"decentity"}');
+ $this->assertEquals("abc", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testJavascript()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"var x = { foo : \"bar\n\" };"|escape:"javascript"}');
+ $this->assertEquals("var x = { foo : \\\"bar\\n\\\" };", $this->smarty->fetch($tpl));
+ }
+
+ public function testJavascriptWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"var x = { foo : \"bar\n\" };"|escape:"javascript"}');
+ $this->assertEquals("var x = { foo : \\\"bar\\n\\\" };", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testMail()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"smarty@example.com"|escape:"mail"}');
+ $this->assertEquals("smarty [AT] example [DOT] com", $this->smarty->fetch($tpl));
+ }
+
+ public function testMailWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"smarty@example.com"|escape:"mail"}');
+ $this->assertEquals("smarty [AT] example [DOT] com", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testNonstd()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"sma\'rty|»example«.com"|escape:"nonstd"}');
+ $this->assertEquals("sma'rty|»example«.com", $this->smarty->fetch($tpl));
+ }
+
+ public function testNonstdWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"' . utf8_decode('sma\'rty@»example«.com') . '"|escape:"nonstd"}');
+ $this->assertEquals("sma'rty@»example«.com", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierLowerTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierLowerTest.php
new file mode 100644
index 00000000..77934ea6
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierLowerTest.php
@@ -0,0 +1,50 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testDefault()
+ {
+ $result = "two convicts evade noose, jury hung.";
+ $tpl = $this->smarty->createTemplate('eval:{"Two Convicts Evade Noose, Jury Hung."|lower}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testDefaultWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "two convicts evade noose, jury hung.";
+ $tpl = $this->smarty->createTemplate('eval:{"Two Convicts Evade Noose, Jury Hung."|lower}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testUmlauts()
+ {
+ $result = "two convicts eväde nööse, jury hung.";
+ $tpl = $this->smarty->createTemplate('eval:{"Two Convicts Eväde NöÖse, Jury Hung."|lower}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testUmlautsWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "two convicts eväde nööse, jury hung.";
+ $tpl = $this->smarty->createTemplate('eval:{"Two Convicts Eväde NöÖse, Jury Hung."|lower}');
+ $this->assertNotEquals($result, $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierRegexReplaceTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierRegexReplaceTest.php
new file mode 100644
index 00000000..6da6edb0
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierRegexReplaceTest.php
@@ -0,0 +1,43 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testDefault()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"Infertility unlikely to\nbe passed on, experts say."|regex_replace:"/[\r\t\n]/":" "}');
+ $this->assertEquals("Infertility unlikely to be passed on, experts say.", $this->smarty->fetch($tpl));
+ }
+
+ public function testDefaultWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"Infertility unlikely to\nbe passed on, experts say."|regex_replace:"/[\r\t\n]/":" "}');
+ $this->assertEquals("Infertility unlikely to be passed on, experts say.", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testUmlauts()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"Infertility unlikely tö\näe passed on, experts say."|regex_replace:"/[\r\t\n]/u":" "}');
+ $this->assertEquals("Infertility unlikely tö äe passed on, experts say.", $this->smarty->fetch($tpl));
+
+ $tpl = $this->smarty->createTemplate('eval:{"Infertility unlikely tä be passed on, experts say."|regex_replace:"/[ä]/ue":"ae"}');
+ $this->assertEquals("Infertility unlikely tae be passed on, experts say.", $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierSpacifyTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierSpacifyTest.php
new file mode 100644
index 00000000..275904b5
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierSpacifyTest.php
@@ -0,0 +1,34 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testDefault()
+ {
+ $result = 'h e l l o w ö r l d';
+ $tpl = $this->smarty->createTemplate('eval:{"hello wörld"|spacify}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testCharacter()
+ {
+ $result = 'h##e##l##l##o## ##w##ö##r##l##d';
+ $tpl = $this->smarty->createTemplate('eval:{"hello wörld"|spacify:"##"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierStripTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierStripTest.php
new file mode 100644
index 00000000..b6d45df8
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierStripTest.php
@@ -0,0 +1,42 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testDefault()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{" hello spaced words "|strip}');
+ $this->assertEquals(" hello spaced words ", $this->smarty->fetch($tpl));
+ }
+
+ public function testUnicodeSpaces()
+ {
+ // Some Unicode Spaces
+ $string = " hello spaced words ";
+ $string = mb_convert_encoding($string, 'UTF-8', "HTML-ENTITIES");
+ $tpl = $this->smarty->createTemplate('eval:{"' . $string . '"|strip}');
+ $this->assertEquals(" hello spaced words ", $this->smarty->fetch($tpl));
+ }
+
+ public function testLinebreak()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{" hello
+ spaced words "|strip}');
+ $this->assertEquals(" hello spaced words ", $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierTruncateTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierTruncateTest.php
new file mode 100644
index 00000000..1bdd8513
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierTruncateTest.php
@@ -0,0 +1,132 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testDefault()
+ {
+ $result = 'Two Sisters Reunite after Eighteen Years at Checkout Counter.';
+ $tpl = $this->smarty->createTemplate('eval:{"Two Sisters Reunite after Eighteen Years at Checkout Counter."|truncate}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testDefaultWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = 'Two Sisters Reunite after Eighteen Years at Checkout Counter.';
+ $tpl = $this->smarty->createTemplate('eval:{"Two Sisters Reunite after Eighteen Years at Checkout Counter."|truncate}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testLength()
+ {
+ $result = 'Two Sisters Reunite after...';
+ $tpl = $this->smarty->createTemplate('eval:{"Two Sisters Reunite after Eighteen Years at Checkout Counter."|truncate:30}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testLengthWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = 'Two Sisters Reunite after...';
+ $tpl = $this->smarty->createTemplate('eval:{"Two Sisters Reunite after Eighteen Years at Checkout Counter."|truncate:30}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testEtc()
+ {
+ $result = 'Two Sisters Reunite after';
+ $tpl = $this->smarty->createTemplate('eval:{"Two Sisters Reunite after Eighteen Years at Checkout Counter."|truncate:30:""}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testEtcWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = 'Two Sisters Reunite after';
+ $tpl = $this->smarty->createTemplate('eval:{"Two Sisters Reunite after Eighteen Years at Checkout Counter."|truncate:30:""}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testEtc2()
+ {
+ $result = 'Two Sisters Reunite after---';
+ $tpl = $this->smarty->createTemplate('eval:{"Two Sisters Reunite after Eighteen Years at Checkout Counter."|truncate:30:"---"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testEtc2WithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = 'Two Sisters Reunite after---';
+ $tpl = $this->smarty->createTemplate('eval:{"Two Sisters Reunite after Eighteen Years at Checkout Counter."|truncate:30:"---"}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testBreak()
+ {
+ $result = 'Two Sisters Reunite after Eigh';
+ $tpl = $this->smarty->createTemplate('eval:{"Two Sisters Reunite after Eighteen Years at Checkout Counter."|truncate:30:"":true}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testBreakWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = 'Two Sisters Reunite after Eigh';
+ $tpl = $this->smarty->createTemplate('eval:{"Two Sisters Reunite after Eighteen Years at Checkout Counter."|truncate:30:"":true}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testBreak2()
+ {
+ $result = 'Two Sisters Reunite after E...';
+ $tpl = $this->smarty->createTemplate('eval:{"Two Sisters Reunite after Eighteen Years at Checkout Counter."|truncate:30:"...":true}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testBreak2WithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = 'Two Sisters Reunite after E...';
+ $tpl = $this->smarty->createTemplate('eval:{"Two Sisters Reunite after Eighteen Years at Checkout Counter."|truncate:30:"...":true}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testMiddle()
+ {
+ $result = 'Two Sisters Re..ckout Counter.';
+ $tpl = $this->smarty->createTemplate('eval:{"Two Sisters Reunite after Eighteen Years at Checkout Counter."|truncate:30:"..":true:true}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testMiddleWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = 'Two Sisters Re..ckout Counter.';
+ $tpl = $this->smarty->createTemplate('eval:{"Two Sisters Reunite after Eighteen Years at Checkout Counter."|truncate:30:"..":true:true}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierUnescapeTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierUnescapeTest.php
new file mode 100644
index 00000000..9b8c5fea
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierUnescapeTest.php
@@ -0,0 +1,66 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testHtml()
+ {
+ $encoded = "aäЗдра><&ääвсствуйте";
+ $result = "aäЗдра><&ääвсствуйте";
+ $tpl = $this->smarty->createTemplate('eval:{"' . $encoded . '"|unescape:"html"}');
+ $this->assertEquals($result, $this->smarty->fetch($tpl));
+ }
+
+ public function testHtmlWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $encoded = "aäЗдра><&ääвсствуйте";
+ $result = "aäЗдра><&ääвсствуйте";
+ $tpl = $this->smarty->createTemplate('eval:{"' . $encoded . '"|unescape:"html"}');
+ $this->assertEquals($result, $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testHtmlall()
+ {
+ $encoded = "aäЗдра><&ääвсствуйте";
+ $result = "aäЗдра><&ääвсствуйте";
+ $tpl = $this->smarty->createTemplate('eval:{"' . $encoded . '"|unescape:"htmlall"}');
+ $this->assertEquals($result, $this->smarty->fetch($tpl));
+ }
+
+ public function testHtmlallWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $encoded = "aäЗдра><&ääвсствуйте";
+ $result = "aäЗдра><&ääвсствуйте";
+ $tpl = $this->smarty->createTemplate('eval:{"' . $encoded . '"|unescape:"htmlall"}');
+ $this->assertEquals($result, $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testUrl()
+ {
+ $encoded = "a%C3%A4%D0%97%D0%B4%D1%80%D0%B0%3E%3C%26amp%3B%C3%A4%C3%A4%D0%B2%D1%81%D1%81%D1%82%D0%B2%3F%3D%2B%D1%83%D0%B9%D1%82%D0%B5";
+ $result = "aäЗдра><&ääвсств?=+уйте";
+ $tpl = $this->smarty->createTemplate('eval:{"' . $encoded . '"|unescape:"url"}');
+ $this->assertEquals($result, $this->smarty->fetch($tpl));
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierUpperTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierUpperTest.php
new file mode 100644
index 00000000..2556936b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierUpperTest.php
@@ -0,0 +1,52 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testDefault()
+ {
+ $result = "IF STRIKE ISN'T SETTLED QUICKLY IT MAY LAST A WHILE.";
+ $tpl = $this->smarty->createTemplate('eval:{"If Strike isn\'t Settled Quickly it may Last a While."|upper}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testDefaultWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "IF STRIKE ISN'T SETTLED QUICKLY IT MAY LAST A WHILE.";
+ $tpl = $this->smarty->createTemplate('eval:{"If Strike isn\'t Settled Quickly it may Last a While."|upper}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testUmlauts()
+ {
+ $result = "IF STRIKE ISN'T SÄTTLED ÜQUICKLY IT MAY LAST A WHILE.";
+ $tpl = $this->smarty->createTemplate('eval:{"If Strike isn\'t Sättled ÜQuickly it may Last a While."|upper}');
+ $this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
+ }
+
+ public function testUmlautsWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $result = "IF STRIKE ISN'T SÄTTLED ÜQUICKLY IT MAY LAST A WHILE.";
+ $tpl = $this->smarty->createTemplate('eval:{"If Strike isn\'t Sättled ÜQuickly it may Last a While."|upper}');
+ $this->assertNotEquals($result, $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierWordwrapTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierWordwrapTest.php
new file mode 100644
index 00000000..76e4cee8
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierWordwrapTest.php
@@ -0,0 +1,154 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testDefault()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"Blind woman gets new kidney from dad she hasn\'t seen in years."|wordwrap}');
+ $this->assertEquals("Blind woman gets new kidney from dad she hasn't seen in years.", $this->smarty->fetch($tpl));
+ }
+
+ public function testDefaultWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"Blind woman gets new kidney from dad she hasn\'t seen in years."|wordwrap}');
+ $this->assertEquals("Blind woman gets new kidney from dad she hasn't seen in years.", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testDefaultUmlauts()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"äöüßñ woman ñsä new kidney from dad she hasn\'t seen in years."|wordwrap:30}');
+ $this->assertEquals("äöüßñ woman ñsä new kidney\nfrom dad she hasn't seen in\nyears.", $this->smarty->fetch($tpl));
+ }
+
+ public function testLength()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"Blind woman gets new kidney from dad she hasn\'t seen in years."|wordwrap:30}');
+ $this->assertEquals("Blind woman gets new kidney\nfrom dad she hasn't seen in\nyears.", $this->smarty->fetch($tpl));
+ }
+
+ public function testLengthWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"Blind woman gets new kidney from dad she hasn\'t seen in years."|wordwrap:30}');
+ $this->assertEquals("Blind woman gets new kidney\nfrom dad she hasn't seen in\nyears.", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testBreak()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"Blind woman gets new kidney from dad she hasn\'t seen in years."|wordwrap:30:"
\n"}');
+ $this->assertEquals("Blind woman gets new kidney
\nfrom dad she hasn't seen in
\nyears.", $this->smarty->fetch($tpl));
+ }
+
+ public function testBreakWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"Blind woman gets new kidney from dad she hasn\'t seen in years."|wordwrap:30:"
\n"}');
+ $this->assertEquals("Blind woman gets new kidney
\nfrom dad she hasn't seen in
\nyears.", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testLong()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"Blind woman withaverylongandunpronoucablenameorso gets new kidney from dad she hasn\'t seen in years."|wordwrap:26:"\n"}');
+ $this->assertEquals("Blind woman\nwithaverylongandunpronoucablenameorso\ngets new kidney from dad\nshe hasn't seen in years.", $this->smarty->fetch($tpl));
+ }
+
+ public function testLongWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"Blind woman withaverylongandunpronoucablenameorso gets new kidney from dad she hasn\'t seen in years."|wordwrap:26:"\n"}');
+ $this->assertEquals("Blind woman\nwithaverylongandunpronoucablenameorso\ngets new kidney from dad\nshe hasn't seen in years.", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testLongUmlauts()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"äöüßñ woman ñsääöüßñameorsoäöüßñäöüßñäöüßñäöüßñßñ gets new kidney from dad she hasn\'t seen in years."|wordwrap:26}');
+ $this->assertEquals("äöüßñ woman\nñsääöüßñameorsoäöüßñäöüßñäöüßñäöüßñßñ\ngets new kidney from dad\nshe hasn't seen in years.", $this->smarty->fetch($tpl));
+ }
+
+ public function testLongCut()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"Blind woman withaverylongandunpronoucablenameorso gets new kidney from dad she hasn\'t seen in years."|wordwrap:26:"\n":true}');
+ $this->assertEquals("Blind woman\nwithaverylongandunpronouca\nblenameorso gets new\nkidney from dad she hasn't\nseen in years.", $this->smarty->fetch($tpl));
+ }
+
+ public function testLongCutWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"Blind woman withaverylongandunpronoucablenameorso gets new kidney from dad she hasn\'t seen in years."|wordwrap:26:"\n":true}');
+ $this->assertEquals("Blind woman\nwithaverylongandunpronouca\nblenameorso gets new\nkidney from dad she hasn't\nseen in years.", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testLongCutUmlauts()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"äöüßñ woman ñsääöüßñameorsoäöüßñäöüßñäöüßñäöüßñßñ gets new kidney from dad she hasn\'t seen in years."|wordwrap:26:"\n":true}');
+ $this->assertEquals("äöüßñ woman\nñsääöüßñameorsoäöüßñäöüßñä\nöüßñäöüßñßñ gets new\nkidney from dad she hasn't\nseen in years.", $this->smarty->fetch($tpl));
+ }
+
+ public function testLinebreaks()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"Blind woman\ngets new kidney from dad she hasn\'t seen in years."|wordwrap:30}');
+ $this->assertEquals("Blind woman\ngets new kidney from dad she\nhasn't seen in years.", $this->smarty->fetch($tpl));
+ }
+
+ public function testLinebreaksWithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"Blind woman\ngets new kidney from dad she hasn\'t seen in years."|wordwrap:30}');
+ $this->assertEquals("Blind woman\ngets new kidney from dad she\nhasn't seen in years.", $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+
+ public function testLinebreaks2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"Blind woman
+ gets
+ new kidney from dad she hasn\'t seen in years."|wordwrap:30}');
+ $this->assertEquals($this->normalizeString("Blind woman
+ gets
+ new kidney from\ndad she hasn't seen in years."), $this->smarty->fetch($tpl));
+ }
+
+ public function testLinebreaks2WithoutMbstring()
+ {
+ Smarty::$_MBSTRING = false;
+ $tpl = $this->smarty->createTemplate('eval:{"Blind woman
+ gets
+ new kidney from dad she hasn\'t seen in years."|wordwrap:30}');
+ $this->assertEquals($this->normalizeString("Blind woman
+ gets
+ new kidney from\ndad she hasn't seen in years."), $this->smarty->fetch($tpl));
+ Smarty::$_MBSTRING = true;
+ }
+ /*
+ public function testUnicodeSpaces()
+ {
+ // Some Unicode Spaces
+ $string = " hello spaced words ";
+ $string = mb_convert_encoding($string, 'UTF-8', "HTML-ENTITIES");
+ $tpl = $this->smarty->createTemplate('eval:{"' . $string . '"|strip}');
+ $this->assertEquals(" hello spaced words ", $this->smarty->fetch($tpl));
+ }
+ */
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/Section/CompileSectionTest.php b/tests/UnitTests/TemplateSource/TagTests/Section/CompileSectionTest.php
new file mode 100644
index 00000000..6d9fc6ad
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Section/CompileSectionTest.php
@@ -0,0 +1,65 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test {section} tag
+ */
+ public function testSection1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=[0,1,2,3,4,5,6,7,8,9]}{section name=bar loop=$foo}{$foo[bar]}{/section}');
+ $this->assertEquals("0123456789", $this->smarty->fetch($tpl));
+ }
+
+ public function testSection2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=[0,1,2,3,4,5,6,7,8,9]}{section name=bar loop=$foo}{$foo[bar]}{sectionelse} else {/section}');
+ $this->assertEquals("0123456789", $this->smarty->fetch($tpl));
+ }
+
+ public function testSection3()
+ {
+ $this->smarty->setErrorReporting(error_reporting() & ~(E_NOTICE | E_USER_NOTICE));
+ $tpl = $this->smarty->createTemplate('eval:{section name=bar loop=$foo}{$foo[bar]}{sectionelse}else{/section}');
+ $this->assertEquals("else", $this->smarty->fetch($tpl));
+ }
+
+ public function testSection4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=[0,1,2,3,4,5,6,7,8,9]}{section name=bar loop=$foo}{$foo[bar]}{sectionelse} else {/section}');
+ $this->assertEquals("0123456789", $this->smarty->fetch($tpl));
+ }
+
+ public function testSection6()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=[0,1,2,3,4,5,6,7,8,9]}{section name=bar loop=$foo}{$foo[bar]}{sectionelse} else {/section}total{$smarty.section.bar.total}');
+ $this->assertEquals("0123456789total10", $this->smarty->fetch($tpl));
+ }
+
+ public function testSection7()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value=[0,1,2,3,4,5,6,7,8,9]}{section name=bar loop=$foo}{$smarty.section.bar.index}{$smarty.section.bar.iteration}{sectionelse} else {/section}');
+ $this->assertEquals("011223344556677889910", $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/SetFilter/CompileSetfilterTest.php b/tests/UnitTests/TemplateSource/TagTests/SetFilter/CompileSetfilterTest.php
new file mode 100644
index 00000000..bbdbbeb1
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/SetFilter/CompileSetfilterTest.php
@@ -0,0 +1,35 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test nested setfilter
+ */
+ public function testNestedSetfilter()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo}{setfilter htmlspecialchars} {$foo}{setfilter escape:"mail"} {$foo}{/setfilter} {$foo}{/setfilter} {$foo}');
+ $tpl->assign('foo', '');
+ $this->assertEquals(" <a@b.c> <a@b.c> ", $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/Strip/CompileStripTest.php b/tests/UnitTests/TemplateSource/TagTests/Strip/CompileStripTest.php
new file mode 100644
index 00000000..097321dc
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/Strip/CompileStripTest.php
@@ -0,0 +1,34 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test strip tag
+ */
+ public function testStrip()
+ {
+ $tpl = $this->smarty->createTemplate("eval:{strip}{/strip}");
+ $this->assertEquals('', $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/CompileFunctionTest.php b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/CompileFunctionTest.php
new file mode 100644
index 00000000..54c70716
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/CompileFunctionTest.php
@@ -0,0 +1,180 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ * @dataProvider functionProvider
+ * test simple function call tag
+ *
+ */
+ public function testSimpleFunction_001($text)
+ {
+ $this->smarty->assign('param', 1);
+ $this->smarty->assign('default', 2);
+ $this->assertEquals("default param default 1 2 1", $this->smarty->fetch('test_template_function_001.tpl'), $text);
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ * @dataProvider functionProvider
+ * test simple function call tag cached
+ */
+ public function testSimpleFunctionCached_001($text)
+ {
+ $this->smarty->setCaching(1);
+ $this->smarty->assign('param', 1);
+ $this->smarty->assign('default', 2);
+ $this->assertEquals("default param default 1 2 1", $this->smarty->fetch('test_template_function_001.tpl'), $text);
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ * @dataProvider functionProvider
+ * test simple function call tag plugin
+ *
+ */
+ public function testSimpleFunctionPlugin_003()
+ {
+ $this->smarty->assign('param', 1);
+ $this->smarty->assign('default', 2, true);
+ $this->assertEquals("default 1", $this->smarty->fetch('test_template_function_003.tpl'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ * @dataProvider functionProvider
+ * test simple function call tag 2
+ *
+ */
+ public function testSimpleFunctionTag2($text)
+ {
+ $this->assertEquals("default param default param2 passed param2 default param", $this->smarty->fetch('test_template_function_tag2.tpl'), $text);
+ }
+
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ * @dataProvider functionProvider
+ * test simple function call recursive
+ */
+ public function testRecursiveFunction($text)
+ {
+ $this->assertEquals("012345", $this->smarty->fetch('test_template_function_tag4.tpl'), $text);
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ * @dataProvider functionProviderInline
+ * test inherited function call tag
+ *
+ */
+ public function testInheritedFunction($merge, $text)
+ {
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $this->assertEquals("012345", $this->smarty->fetch('test_template_function_tag5.tpl'), $text);
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ * @dataProvider functionProviderInline
+ * test function definition in include
+ *
+ */
+ public function testDefineFunctionInclude($merge, $text)
+ {
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $tpl = $this->smarty->createTemplate('test_template_function_tag6.tpl');
+ $this->assertEquals("012345", $this->smarty->fetch('test_template_function_tag6.tpl'), $text);
+ }
+
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ * @dataProvider functionProviderInline
+ * test external function definition cached
+ *
+ */
+ public function testExternalDefinedFunctionCached1($merge, $text)
+ {
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $cacheId = $merge ? 'merge' : null;
+ $this->smarty->caching = 1;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('test_template_function.tpl', $cacheId);
+ $tpl->assign('foo', 'foo');
+ $this->assertContains('foo foo', $this->smarty->fetch($tpl), $text);
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ * @dataProvider functionProviderInline
+ * test external function definition cached 2
+ *
+ */
+ public function testExternalDefinedFunctionCached12($merge, $text)
+ {
+ $this->smarty->setMergeCompiledIncludes($merge);
+ $cacheId = $merge ? 'merge' : null;
+ $this->smarty->caching = 1;
+ $this->smarty->cache_lifetime = 1000;
+ $tpl = $this->smarty->createTemplate('test_template_function.tpl', $cacheId);
+ $this->assertTrue($this->smarty->isCached($tpl), $text);
+ $tpl->assign('foo', 'bar');
+ $this->assertContains('foo bar', $this->smarty->fetch($tpl), $text);
+ }
+
+
+ /**
+ * Function data provider inline
+ */
+ public function functionProviderInline()
+ {
+ return array(
+ array(false, 'normal compile'),
+ array(false, 'normal call'),
+ array(true, 'merged compile'),
+ array(true, 'merged call'),
+ );
+ }
+ /**
+ * Function data provider inline
+ */
+ public function functionProvider()
+ {
+ return array(
+ array('compile'),
+ array('call'),
+ );
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/nocache_lib.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/nocache_lib.tpl
new file mode 100644
index 00000000..8602140e
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/nocache_lib.tpl
@@ -0,0 +1,6 @@
+{function 'nocache1' default1='d1' default2='d2'}
+ default1={$default1}
+ default2={$default1 nocache}
+ p1={$p1}
+ p2={$p2 nocache}
+{/function}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test0.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test0.tpl
new file mode 100644
index 00000000..ae27c661
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test0.tpl
@@ -0,0 +1,4 @@
+Test 1
+
+{include 'test7.tpl' compile_id = 4}
+
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test1.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test1.tpl
new file mode 100644
index 00000000..c8992cca
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test1.tpl
@@ -0,0 +1,7 @@
+Test 1
+
+{include 'test7.tpl' compile_id = $id}
+{include 'test6.tpl'}
+{include file="test2.tpl"}
+{include 'test6.tpl'}
+
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test2.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test2.tpl
new file mode 100644
index 00000000..9b526949
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test2.tpl
@@ -0,0 +1,3 @@
+Test 2
+
+{include file="test3.tpl" compile_id=4}
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test3.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test3.tpl
new file mode 100644
index 00000000..c4ca3221
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test3.tpl
@@ -0,0 +1,4 @@
+Test 3 {call name='f' nocache}
+
+{include file="test4.tpl" compile_id=9}
+{include file="test5.tpl" cache_id="7"}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test4.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test4.tpl
new file mode 100644
index 00000000..13b0cbbb
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test4.tpl
@@ -0,0 +1,3 @@
+Test 4
+
+{include file="test5.tpl" cache_id="7"}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test5.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test5.tpl
new file mode 100644
index 00000000..0a65c4c8
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test5.tpl
@@ -0,0 +1,4 @@
+test 5
+
+
+{call 'f'}
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test6.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test6.tpl
new file mode 100644
index 00000000..d7379f81
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test6.tpl
@@ -0,0 +1,8 @@
+test 6
+
+{function name='f'}
+
+ function f {$id} {$foo}
+
+{/function}
+
Time 6 = {$t6}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test7.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test7.tpl
new file mode 100644
index 00000000..cc378526
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/CachingTests/test7.tpl
@@ -0,0 +1,2 @@
+test 7
+
extern
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/template_function_lib.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/template_function_lib.tpl
new file mode 100644
index 00000000..a9a1c077
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/template_function_lib.tpl
@@ -0,0 +1 @@
+{function name=template_func1 default='d1'}{$foo|escape} {nocache}{$foo|escape}{/nocache} {/function}
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_define_function_tag.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_define_function_tag.tpl
new file mode 100644
index 00000000..35edac24
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_define_function_tag.tpl
@@ -0,0 +1 @@
+{function name=functest6i loop=0}{$loop}{if $loop < 5}{call name=functest6i loop=$loop+1}{/if}{/function}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_inherit_function_tag.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_inherit_function_tag.tpl
new file mode 100644
index 00000000..f50d697e
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_inherit_function_tag.tpl
@@ -0,0 +1 @@
+{call name=functest4}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_inherit_function_tag6.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_inherit_function_tag6.tpl
new file mode 100644
index 00000000..10d6e88b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_inherit_function_tag6.tpl
@@ -0,0 +1 @@
+{call name=functest6i}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function.tpl
new file mode 100644
index 00000000..0997bdd3
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function.tpl
@@ -0,0 +1 @@
+{include file='template_function_lib.tpl'}{call name=template_func1}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_001.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_001.tpl
new file mode 100644
index 00000000..194dde9a
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_001.tpl
@@ -0,0 +1 @@
+{function name=functest default='default'}{$default} {$param}{/function}{call name=functest param='param'} {call name=functest param=$param} {call name=functest param=$param default=$default}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_002.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_002.tpl
new file mode 100644
index 00000000..7b6dbc77
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_002.tpl
@@ -0,0 +1 @@
+{function name=functest default='default'}{$default} {$param nocache}{/function}{call name=functest param='param'} {call name=functest param=$param} {call name=functest param=$param default=$default}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_003.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_003.tpl
new file mode 100644
index 00000000..f71bed61
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_003.tpl
@@ -0,0 +1 @@
+{function name=functest default='default'}{$default} {counter start=1 nocache}{/function}{call name=functest}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_nocache_call.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_nocache_call.tpl
new file mode 100644
index 00000000..3be68715
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_nocache_call.tpl
@@ -0,0 +1 @@
+{include file='template_function_lib.tpl'}{call 'template_func1' nocache}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_tag2.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_tag2.tpl
new file mode 100644
index 00000000..2464e00a
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_tag2.tpl
@@ -0,0 +1 @@
+{function name=functest2 default='default'}{$default} {$param}{/function}{call name=functest2 param='param'} {call name=functest2 param='param2'} {call name=functest2 param='param2' default='passed'} {call name=functest2 param='param'}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_tag4.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_tag4.tpl
new file mode 100644
index 00000000..80cf6a0f
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_tag4.tpl
@@ -0,0 +1 @@
+{function name=functest4 loop=0}{$loop}{if $loop < 5}{call name=functest4 loop=$loop+1}{/if}{/function}{call name=functest4}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_tag5.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_tag5.tpl
new file mode 100644
index 00000000..f20a9617
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_tag5.tpl
@@ -0,0 +1 @@
+{function name=functest4 loop=0}{$loop}{if $loop < 5}{call name=functest4 loop=$loop+1}{/if}{/function}{include file='test_inherit_function_tag.tpl'}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_tag6.tpl b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_tag6.tpl
new file mode 100644
index 00000000..993a4945
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/TemplateFunction/templates/test_template_function_tag6.tpl
@@ -0,0 +1 @@
+{include file='test_define_function_tag.tpl'}{include file='test_inherit_function_tag6.tpl'}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/TagTests/While/CompileWhileTest.php b/tests/UnitTests/TemplateSource/TagTests/While/CompileWhileTest.php
new file mode 100644
index 00000000..ed3fec46
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/While/CompileWhileTest.php
@@ -0,0 +1,43 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test {while 'condition'} tag
+ */
+ public function testWhileCondition()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$x=0}{while $x<10}{$x}{$x=$x+1}{/while}');
+ $this->assertEquals("0123456789", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test {while 'statement'} tag
+ */
+ public function testWhileStatement()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$y=5}{while $y=$y-1}{$y}{/while}');
+ $this->assertEquals("4321", $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/_Attributes/AttributeTest.php b/tests/UnitTests/TemplateSource/TagTests/_Attributes/AttributeTest.php
new file mode 100644
index 00000000..9a2f0585
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/_Attributes/AttributeTest.php
@@ -0,0 +1,89 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test required attribute
+ */
+ public function testRequiredAttributeVar()
+ {
+ try {
+ $this->smarty->fetch('string:{assign value=1}');
+ }
+ catch (Exception $e) {
+ $this->assertContains('missing "var" attribute', $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for required attribute "var" has not been raised.');
+ }
+
+ /**
+ * test unexpected attribute
+ */
+ public function testUnexpectedAttribute()
+ {
+ try {
+ $this->smarty->fetch('string:{assign var=foo value=1 bar=2}');
+ }
+ catch (Exception $e) {
+ $this->assertContains('unexpected "bar" attribute', $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for unexpected attribute "bar" has not been raised.');
+ }
+
+ /**
+ * test illegal option value
+ */
+ public function testIllegalOptionValue()
+ {
+ try {
+ $this->smarty->fetch('string:{assign var=foo value=1 nocache=buh}');
+ }
+ catch (Exception $e) {
+ $this->assertContains(htmlentities('illegal value of option flag'), $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for illegal value of option flag has not been raised.');
+ }
+
+ /**
+ * test too many shorthands
+ */
+ public function testTooManyShorthands()
+ {
+ try {
+ $this->smarty->fetch('string:{assign foo 1 2}');
+ }
+ catch (Exception $e) {
+ $this->assertContains('too many shorthand attributes', $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for too many shorthand attributes has not been raised.');
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/_Error/CompileErrorTest.php b/tests/UnitTests/TemplateSource/TagTests/_Error/CompileErrorTest.php
new file mode 100644
index 00000000..a433d764
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/_Error/CompileErrorTest.php
@@ -0,0 +1,84 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test none existing template file error
+ */
+ public function testNoneExistingTemplateError()
+ {
+ try {
+ $this->smarty->fetch('eval:{include file=\'no.tpl\'}');
+ }
+ catch (Exception $e) {
+ $this->assertContains('Unable to load template', $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for none existing template has not been raised.');
+ }
+
+ /**
+ * test unkown tag error
+ */
+ public function testUnknownTagError()
+ {
+ try {
+ $this->smarty->fetch('eval:{unknown}');
+ }
+ catch (Exception $e) {
+ $this->assertContains('unknown tag "unknown"', $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for unknown Smarty tag has not been raised.');
+ }
+
+ /**
+ * test unclosed tag error
+ */
+ public function testUnclosedTagError()
+ {
+ try {
+ $this->smarty->fetch('eval:{if true}');
+ }
+ catch (Exception $e) {
+ $this->assertContains('unclosed {if} tag', $e->getMessage());
+
+ return;
+ }
+ $this->fail('Exception for unclosed Smarty tags has not been raised.');
+ }
+
+ /**
+ * @expectedException SmartyCompilerException
+ * @expectedExceptionMessage Syntax Error in template "599a9cf0e3623a3206bd02a0f5c151d5f5f3f69e"
+ * @expectedExceptionMessage Unexpected "}"
+ * test syntax error
+ */
+ public function testSyntaxError()
+ {
+ $this->smarty->fetch('eval:{assign var=}');
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/_Print/PrintNocacheTest.php b/tests/UnitTests/TemplateSource/TagTests/_Print/PrintNocacheTest.php
new file mode 100644
index 00000000..ea38ad15
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/_Print/PrintNocacheTest.php
@@ -0,0 +1,67 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test print nocache caching disabled
+ */
+ public function testPrintNocacheCachingNo1()
+ {
+ $this->smarty->caching = 0;
+ $this->smarty->assign('foo', 0);
+ $this->smarty->assign('bar', 'A');
+ $this->assertEquals("0A", $this->smarty->fetch('test_print_nocache.tpl'));
+ }
+
+ public function testPrintNocacheCachingNo2()
+ {
+ $this->smarty->caching = 0;
+ $this->smarty->assign('foo', 2);
+ $this->smarty->assign('bar', 'B');
+ $this->assertEquals("2B", $this->smarty->fetch('test_print_nocache.tpl'));
+ }
+
+ /**
+ * test print nocache caching enabled
+ */
+ public function testPrintNocacheCachingYes1()
+ {
+ $this->smarty->caching = 1;
+ $this->smarty->assign('foo', 0);
+ $this->smarty->assign('bar', 'A');
+ $this->assertEquals("0A", $this->smarty->fetch('test_print_nocache.tpl'));
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ */
+ public function testPrintNocacheCachingYes2()
+ {
+ $this->smarty->caching = 1;
+ $this->smarty->assign('foo', 2);
+ $this->smarty->assign('bar', 'B');
+ $this->assertEquals("2A", $this->smarty->fetch('test_print_nocache.tpl'));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/TagTests/_Print/templates/test_print_nocache.tpl b/tests/UnitTests/TemplateSource/TagTests/_Print/templates/test_print_nocache.tpl
new file mode 100644
index 00000000..344da984
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/TagTests/_Print/templates/test_print_nocache.tpl
@@ -0,0 +1 @@
+{$foo nocache=true}{$bar}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/ValueTests/Array/ArrayTest.php b/tests/UnitTests/TemplateSource/ValueTests/Array/ArrayTest.php
new file mode 100644
index 00000000..92b3ef43
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/ValueTests/Array/ArrayTest.php
@@ -0,0 +1,133 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test simple array definition
+ */
+ public function testSimpleArrayDefinition()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=[1,2,3,4,5]}{foreach $foo as $bar}{$bar}{/foreach}');
+ $this->assertEquals('12345', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test smarty2 array access
+ */
+ public function testSmarty2ArrayAccess()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=[1,2,3,4,5]}{$foo.0}{$foo.1}{$foo.2}');
+ $this->assertEquals('123', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test smarty3 array access
+ */
+ public function testSmarty3ArrayAccess()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=[1,2,3,4,5]}{$foo[0]}{$foo[1]}{$foo[2]}');
+ $this->assertEquals('123', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test indexed array definition
+ */
+ public function testIndexedArrayDefinition()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$x=\'d\'}{$foo=[a=>1,\'b\'=>2,"c"=>3,$x=>4]}{$foo[\'a\']}{$foo[\'b\']}{$foo[\'c\']}{$foo[\'d\']}');
+ $this->assertEquals('1234', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test nested array
+ */
+ public function testNestedArray()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=[1,2,[a,b,c],4,5]}{$foo[2][1]}');
+ $this->assertEquals('b', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test array math
+ */
+ public function testArrayMath1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=[1,2,[7,8,9],4,5]}{$foo[2][1]+1}');
+ $this->assertEquals('9', $this->smarty->fetch($tpl));
+ }
+
+ public function testArrayMath2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=[1,2,[7,8,9],4,5]}{$foo.2.1+1}');
+ $this->assertEquals('9', $this->smarty->fetch($tpl));
+ }
+
+ public function testArrayMath3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=[1,2,[7,8,9],4,5]}{2+$foo[2][1]}');
+ $this->assertEquals('10', $this->smarty->fetch($tpl));
+ }
+
+ public function testArrayMath4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=[1,2,[7,8,9],4,5]}{2+$foo.2.1}');
+ $this->assertEquals('10', $this->smarty->fetch($tpl));
+ }
+
+ public function testArrayMath5()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=[1,2,[7,8,9],4,5]}{$foo[2][0]+$foo[2][1]}');
+ $this->assertEquals('15', $this->smarty->fetch($tpl));
+ }
+
+ public function testArrayMath6()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=[1,2,[7,8,9],4,5]}{$foo.2.0+$foo.2.1}');
+ $this->assertEquals('15', $this->smarty->fetch($tpl));
+ }
+
+ public function testArrayVariableIndex1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=[1,2,[7,8,9],4,5]}{$x=2}{$y=0}{$foo.$x.$y}');
+ $this->assertEquals('7', $this->smarty->fetch($tpl));
+ }
+
+ public function testArrayVariableIndex2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=[1,2,[7,8,9],4,5]}{$x=2}{$foo.$x.0}');
+ $this->assertEquals('7', $this->smarty->fetch($tpl));
+ }
+
+ public function testArrayVariableIndex3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=[1,2,[7,8,9],4,5]}{$x=0}{$foo.2.$x}');
+ $this->assertEquals('7', $this->smarty->fetch($tpl));
+ }
+
+ public function testArrayVariableIndex4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=[1,2,[7,8,9],4,5]}{$x=[1,0]}{$foo.2.{$x.1}}');
+ $this->assertEquals('7', $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/ValueTests/ConstantTests/ConstantsTest.php b/tests/UnitTests/TemplateSource/ValueTests/ConstantTests/ConstantsTest.php
new file mode 100644
index 00000000..70d1282f
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/ValueTests/ConstantTests/ConstantsTest.php
@@ -0,0 +1,51 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test constants
+ */
+ public function testConstants()
+ {
+ define('MYCONSTANTS', 'hello world');
+ $tpl = $this->smarty->createTemplate('eval:{$smarty.const.MYCONSTANTS}');
+ $this->assertEquals("hello world", $this->smarty->fetch($tpl));
+ }
+
+ public function testConstants4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{TestConst::CONSTVAL}');
+ $this->assertEquals("okay", $this->smarty->fetch($tpl));
+ }
+
+ public function testConstants5()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{if TestConst::CONSTVAL == "okay"}yes{/if}');
+ $this->assertEquals("yes", $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/ValueTests/DoubleQuoted/DoubleQuotedStringTest.php b/tests/UnitTests/TemplateSource/ValueTests/DoubleQuoted/DoubleQuotedStringTest.php
new file mode 100644
index 00000000..a2bb1f00
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/ValueTests/DoubleQuoted/DoubleQuotedStringTest.php
@@ -0,0 +1,177 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test simple double quoted string
+ */
+ public function testSimpleDoubleQuotedString()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo="Hello World"}{$foo}', null, null, $this->smarty);
+ $this->assertEquals('Hello World', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test expression tags in double quoted strings
+ */
+ public function testTagsInDoubleQuotedString()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo="Hello {1+2} World"}{$foo}', null, null, $this->smarty);
+ $this->assertEquals('Hello 3 World', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test vars in double quoted strings
+ */
+ public function testVarsInDoubleQuotedString1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$bar=\'blah\'}{$foo="Hello $bar World"}{$foo}', null, null, $this->smarty);
+ $this->assertEquals('Hello blah World', $this->smarty->fetch($tpl));
+ }
+
+ public function testVarsInDoubleQuotedString2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$bar=\'blah\'}{$buh=\'buh\'}{$foo="Hello $bar$buh World"}{$foo}', null, null, $this->smarty);
+ $this->assertEquals('Hello blahbuh World', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test vars with backtick in double quoted strings
+ */
+ public function testVarsBacktickInDoubleQuotedString1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$bar=\'blah\'}{$foo="Hello `$bar`.test World"}{$foo}', null, null, $this->smarty);
+ $this->assertEquals('Hello blah.test World', $this->smarty->fetch($tpl));
+ }
+
+ public function testVarsBacktickInDoubleQuotedString2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$bar=\'blah\'}{$buh=\'buh\'}{$foo="Hello `$bar``$buh`.test World"}{$foo}', null, null, $this->smarty);
+ $this->assertEquals('Hello blahbuh.test World', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test variable vars with backtick in double quoted strings
+ */
+ public function testVariableVarsBacktickInDoubleQuotedString()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$barbuh=\'blah\'}{$buh=\'buh\'}{$foo="Hello `$bar{$buh}`.test World"}{$foo}', null, null, $this->smarty);
+ $this->assertEquals('Hello blah.test World', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test array vars with backtick in double quoted strings
+ */
+ public function testArrayVarsBacktickInDoubleQuotedString1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$bar[1][2]=\'blah\'}{$foo="Hello `$bar.1.2`.test World"}{$foo}', null, null, $this->smarty);
+ $this->assertEquals('Hello blah.test World', $this->smarty->fetch($tpl));
+ }
+
+ public function testArrayVarsBacktickInDoubleQuotedString2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$bar[1][2]=\'blah\'}{$foo="Hello `$bar[1][2]`.test World"}{$foo}', null, null, $this->smarty);
+ $this->assertEquals('Hello blah.test World', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test expression in backtick in double quoted strings
+ */
+ public function testExpressionBacktickInDoubleQuotedString()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$a=1}{"`$a+1`"}', null, null, $this->smarty);
+ $this->assertEquals('2', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test smartytag in double quoted strings
+ */
+ public function testSmartytagInDoubleQuotedString1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo="Hello {counter start=1} World"}{$foo}', null, null, $this->smarty);
+ $this->assertEquals('Hello 1 World', $this->smarty->fetch($tpl));
+ }
+
+ public function testSmartytagInDoubleQuotedString2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo="Hello {counter start=1}{counter} World"}{$foo}', null, null, $this->smarty);
+ $this->assertEquals('Hello 12 World', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test block smartytag in double quoted strings
+ */
+ public function testSmartyBlockTagInDoubleQuotedString1()
+ {
+ $this->smarty->assign('x', 1);
+ $this->smarty->assign('y', 1);
+ $this->smarty->assign('z', true);
+ $this->assertEquals('Hello 1 World', $this->smarty->fetch('string:{"Hello{if $z} {$x} {else}{$y}{/if}World"}'));
+ }
+
+ /**
+ * test vars in delimiter in double quoted strings
+ */
+ public function testVarsDelimiterInDoubleQuotedString()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$bar=\'blah\'}{$foo="Hello {$bar}.test World"}{$foo}', null, null, $this->smarty);
+ $this->assertEquals('Hello blah.test World', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test escaped quotes in double quoted strings
+ */
+ public function testEscapedQuotesInDoubleQuotedString()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo="Hello \" World"}{$foo}', null, null, $this->smarty);
+ $this->assertEquals('Hello " World', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test single quotes in double quoted strings
+ */
+ public function testSingleQuotesInDoubleQuotedString()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo="Hello \'World\'"}{$foo}', null, null, $this->smarty);
+ $this->assertEquals("Hello 'World'", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test single quote tags in double quoted strings
+ */
+ public function testSingleQuoteTagsInDoubleQuotedString()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo="Hello {\'World\'} Test"}{$foo}', null, null, $this->smarty);
+ $this->assertEquals("Hello World Test", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test empty double quoted strings
+ */
+ public function testEmptyDoubleQuotedString()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=""}{$foo}', null, null, $this->smarty);
+ $this->assertEquals("", $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/ValueTests/Math/MathTest.php b/tests/UnitTests/TemplateSource/ValueTests/Math/MathTest.php
new file mode 100644
index 00000000..678691e7
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/ValueTests/Math/MathTest.php
@@ -0,0 +1,108 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test PHP function as modifier
+ */
+ public function testSyntax()
+ {
+ $this->smarty->disableSecurity();
+ $expected = "20 -- 4";
+ $tpl = $this->smarty->createTemplate('eval:{$x = 4}{$y = 5}{$x * $y} -- {20 / 5}');
+ $this->assertEquals($expected, $this->smarty->fetch($tpl));
+ }
+
+ public function testFunction()
+ {
+ $this->smarty->disableSecurity();
+ $expected = "20 -- 4";
+ $tpl = $this->smarty->createTemplate('eval:{$x = 4}{$y = 5}{math equation="x * y" x=$x y=$y} -- {math equation="20 / 5"}');
+ $this->assertEquals($expected, $this->smarty->fetch($tpl));
+ }
+
+ public function testSyntaxSin()
+ {
+ $this->smarty->disableSecurity();
+ $expected = sin(4) . ' -- ' . sin(4);
+ $tpl = $this->smarty->createTemplate('eval:{$x = 4}{$x|sin} -- {$y = sin($x)}{$y}');
+ $this->assertEquals($expected, $this->smarty->fetch($tpl));
+ }
+
+ public function testFunctionSin()
+ {
+ $this->smarty->disableSecurity();
+ $expected = sin(4) . ' -- ' . sin(4);
+ $tpl = $this->smarty->createTemplate('eval:{$x = 4}{math equation="sin(x)" x=$x} -- {math equation="sin(x)" x=$x assign="y"}{$y}');
+ $this->assertEquals($expected, $this->smarty->fetch($tpl));
+ }
+
+ public function testSyntaxFloat()
+ {
+ $this->smarty->disableSecurity();
+ $expected = "22 -- 4.1";
+ $tpl = $this->smarty->createTemplate('eval:{$x = 4}{$y = 5.5}{$x * $y} -- {20.5 / 5}');
+ $this->assertEquals($expected, $this->smarty->fetch($tpl));
+ }
+
+ public function testFunctionFloat()
+ {
+ $this->smarty->disableSecurity();
+ $expected = "22 -- 4.1";
+ $tpl = $this->smarty->createTemplate('eval:{$x = 4}{$y = 5.5}{math equation="x * y" x=$x y=$y} -- {math equation="20.5 / 5"}');
+ $this->assertEquals($expected, $this->smarty->fetch($tpl));
+ }
+
+ public function testSyntaxFormat()
+ {
+ $this->smarty->disableSecurity();
+ $expected = "22.00 -- 4.10";
+ $tpl = $this->smarty->createTemplate('eval:{$x = 4}{$y = 5.5}{$z = $x * $y}{"%0.2f"|sprintf:$z} -- {$x = 20.5}{$y = 5}{$z = $x / $y}{"%0.2f"|sprintf:$z}');
+ $this->assertEquals($expected, $this->smarty->fetch($tpl));
+ }
+
+ public function testFunctionFormat()
+ {
+ $this->smarty->disableSecurity();
+ $expected = "22.00 -- 4.10";
+ $tpl = $this->smarty->createTemplate('eval:{$x = 4}{$y = 5.5}{math equation="x * y" x=$x y=$y format="%0.2f"} -- {math equation="20.5 / 5" format="%0.2f"}');
+ $this->assertEquals($expected, $this->smarty->fetch($tpl));
+ }
+
+ public function testSyntaxString()
+ {
+ $this->smarty->disableSecurity();
+ $expected = "22.00 -- 4.10";
+ $tpl = $this->smarty->createTemplate('eval:{$x = "4"}{$y = "5.5"}{$z = $x * $y}{"%0.2f"|sprintf:$z} -- {$x = "20.5"}{$y = "5"}{$z = $x / $y}{"%0.2f"|sprintf:$z}');
+ $this->assertEquals($expected, $this->smarty->fetch($tpl));
+ }
+
+ public function testFunctionString()
+ {
+ $this->smarty->disableSecurity();
+ $expected = "22.00 -- 4.10";
+ $tpl = $this->smarty->createTemplate('eval:{$x = "4"}{$y = "5.5"}{math equation="x * y" x=$x y=$y format="%0.2f"} -- {math equation="20.5 / 5" format="%0.2f"}');
+ $this->assertEquals($expected, $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/ValueTests/Modifier/ModifierTest.php b/tests/UnitTests/TemplateSource/ValueTests/Modifier/ModifierTest.php
new file mode 100644
index 00000000..fb656f99
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/ValueTests/Modifier/ModifierTest.php
@@ -0,0 +1,206 @@
+setUpSmarty(__DIR__);
+ $this->smarty->enableSecurity();
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test PHP function as modifier
+ */
+ public function testPHPFunctionModifier()
+ {
+ $this->smarty->security_policy->php_modifiers = array('strlen');
+ $tpl = $this->smarty->createTemplate('eval:{"hello world"|strlen}');
+ $this->assertEquals("11", $this->smarty->fetch($tpl));
+ }
+
+ public function testPHPFunctionModifier2()
+ {
+ $this->smarty->security_policy->php_modifiers = array('strlen');
+ $tpl = $this->smarty->createTemplate('eval:{assign var=foo value="hello world"}{$foo|strlen}');
+ $this->assertEquals("11", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test plugin as modifier
+ */
+ public function testPluginModifier()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"hello world"|truncate:6}');
+ $this->assertEquals("hel...", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test plugin as modifier with variable
+ */
+ public function testPluginModifierVar()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"hello world"|truncate:$foo}');
+ $tpl->assign('foo', 6);
+ $this->assertEquals("hel...", $this->smarty->fetch($tpl));
+ }
+
+ public function testPluginModifierVar2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"hello world"|truncate:$foo:" "}');
+ $tpl->assign('foo', 6);
+ $this->assertEquals("hel ", $this->smarty->fetch($tpl));
+ }
+
+ public function testPluginModifierVar3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"hello world"|truncate:$foo:$bar}');
+ $tpl->assign('foo', 6);
+ $tpl->assign('bar', ' ');
+ $this->assertEquals("hel ", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test modifier chaining
+ */
+ public function testModifierChaining()
+ {
+ $this->smarty->security_policy->php_modifiers = array('strlen');
+ $tpl = $this->smarty->createTemplate('eval:{"hello world"|truncate:6|strlen}');
+ $this->assertEquals("6", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test modifier in {if}
+ */
+ public function testModifierInsideIf()
+ {
+ $this->smarty->security_policy->php_modifiers = array('strlen');
+ $tpl = $this->smarty->createTemplate('eval:{if "hello world"|truncate:6|strlen == 6}okay{/if}');
+ $this->assertEquals("okay", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test modifier in expressions
+ */
+ public function testModifierInsideExpression()
+ {
+ $this->smarty->security_policy->php_modifiers = array('strlen');
+ $tpl = $this->smarty->createTemplate('eval:{"hello world"|truncate:6|strlen + ("hello world"|truncate:8|strlen)}');
+ $this->assertEquals("14", $this->smarty->fetch($tpl));
+ }
+
+ public function testModifierInsideExpression2()
+ {
+ $this->smarty->security_policy->php_modifiers = array('round');
+ $tpl = $this->smarty->createTemplate('eval:{1.1*7.1|round}');
+ $this->assertEquals("7.7", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test modifier at plugin result
+ */
+ public function testModifierAtPluginResult()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{counter|truncate:5 start=100000}');
+ $this->assertEquals("10...", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test unqouted string as modifier parameter
+ */
+ public function testModifierUnqoutedString()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{"hello world"|replace:hello:xxxxx}');
+ $this->assertEquals("xxxxx world", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test registered modifier function
+ */
+ public function testModifierRegisteredFunction()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_MODIFIER, 'testmodifier', 'testmodifier');
+ $tpl = $this->smarty->createTemplate('eval:{$foo|testmodifier}');
+ $tpl->assign('foo', 2);
+ $this->assertEquals("mymodifier function 2", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test registered modifier static class
+ */
+ public function testModifierRegisteredStaticClass()
+ {
+ $this->smarty->registerPlugin(Smarty::PLUGIN_MODIFIER, 'testmodifier', array('testmodifierclass', 'staticcall'));
+ $tpl = $this->smarty->createTemplate('eval:{$foo|testmodifier}');
+ $tpl->assign('foo', 1);
+ $this->assertEquals("mymodifier static 1", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test registered modifier method call
+ */
+ public function testModifierRegisteredMethodCall()
+ {
+ $obj = new testmodifierclass();
+ $this->smarty->registerPlugin(Smarty::PLUGIN_MODIFIER, 'testmodifier', array($obj, 'method'));
+ $tpl = $this->smarty->createTemplate('eval:{$foo|testmodifier}');
+ $tpl->assign('foo', 3);
+ $this->assertEquals("mymodifier method 3", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * @expectedException SmartyCompilerException
+ * @expectedExceptionMessage Syntax Error in template "4d2e368c483a648d14bbd59592da92aff3b96a2f"
+ * @expectedExceptionMessage unknown modifier "unknown"
+ * test unknown modifier error
+ */
+ public function testUnknownModifier()
+ {
+ $this->smarty->fetch('eval:{"hello world"|unknown}');
+ }
+
+ /**
+ * test default modifier
+ */
+ public function testDefaultModifier()
+ {
+ $this->smarty->default_modifiers = array('escape');
+ $tpl = $this->smarty->createTemplate('eval:{$foo}{$foo nofilter}');
+ $tpl->assign('foo', '');
+ $this->assertEquals('<bar>', $this->smarty->fetch($tpl));
+ }
+}
+
+function testmodifier($value)
+{
+ return "mymodifier function $value";
+}
+
+class testmodifierclass
+{
+ static function staticcall($value)
+ {
+ return "mymodifier static $value";
+ }
+
+ public function method($value)
+ {
+ return "mymodifier method $value";
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/ValueTests/Objects/ObjectVariableTest.php b/tests/UnitTests/TemplateSource/ValueTests/Objects/ObjectVariableTest.php
new file mode 100644
index 00000000..c2fc3320
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/ValueTests/Objects/ObjectVariableTest.php
@@ -0,0 +1,104 @@
+setUpSmarty(__DIR__);
+ $this->smarty->setForceCompile(true);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test simple object variable
+ */
+ public function testObjectVariableOutput()
+ {
+ $object = new VariableObject;
+ $tpl = $this->smarty->createTemplate('string:{$object->hello}');
+ $tpl->assign('object', $object);
+ $this->assertEquals('hello_world', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test simple object variable with variable property
+ */
+ public function testObjectVariableOutputVariableProperty()
+ {
+ $object = new VariableObject;
+ $this->smarty->disableSecurity();
+ $tpl = $this->smarty->createTemplate('string:{$p=\'hello\'}{$object->$p}');
+ $tpl->assign('object', $object);
+ $this->assertEquals('hello_world', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test simple object variable with method
+ */
+ public function testObjectVariableOutputMethod()
+ {
+ $object = new VariableObject;
+ $tpl = $this->smarty->createTemplate('string:{$object->myhello()}');
+ $tpl->assign('object', $object);
+ $this->assertEquals('hello world', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test simple object variable with method
+ */
+ public function testObjectVariableOutputVariableMethod()
+ {
+ $object = new VariableObject;
+ $this->smarty->disableSecurity();
+ $tpl = $this->smarty->createTemplate('string:{$p=\'myhello\'}{$object->$p()}');
+ $tpl->assign('object', $object);
+ $this->assertEquals('hello world', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test object variable in double quoted string
+ */
+ public function testObjectVariableOutputDoubleQuotes()
+ {
+ $object = new VariableObject;
+ $tpl = $this->smarty->createTemplate('string:{"double quoted `$object->hello` okay"}');
+ $tpl->assign('object', $object);
+ $this->assertEquals('double quoted hello_world okay', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test object variable in double quoted string as include name
+ */
+ public function testObjectVariableOutputDoubleQuotesInclude()
+ {
+ $object = new VariableObject;
+ $tpl = $this->smarty->createTemplate('string:{include file="`$object->hello`_test.tpl"}');
+ $tpl->assign('object', $object);
+ $this->assertEquals('hello world', $this->smarty->fetch($tpl));
+ }
+}
+
+Class VariableObject
+{
+ public $hello = 'hello_world';
+
+ public function myhello()
+ {
+ return 'hello world';
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/ValueTests/Objects/templates/hello_world_test.tpl b/tests/UnitTests/TemplateSource/ValueTests/Objects/templates/hello_world_test.tpl
new file mode 100644
index 00000000..95d09f2b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/ValueTests/Objects/templates/hello_world_test.tpl
@@ -0,0 +1 @@
+hello world
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/ValueTests/SingleQouted/SingleQuotedStringTest.php b/tests/UnitTests/TemplateSource/ValueTests/SingleQouted/SingleQuotedStringTest.php
new file mode 100644
index 00000000..a021b755
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/ValueTests/SingleQouted/SingleQuotedStringTest.php
@@ -0,0 +1,79 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test simple single quoted string
+ */
+ public function testSimpleSingleQuotedString()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=\'Hello World\'}{$foo}');
+ $this->assertEquals('Hello World', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test that tags not interpreted in single quoted strings
+ */
+ public function testTagsInSingleQuotedString()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=\'Hello {1+2} World\'}{$foo}');
+ $this->assertEquals('Hello {1+2} World', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test that vars not interpreted in single quoted strings
+ */
+ public function testVarsInSingleQuotedString()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=\'Hello $bar World\'}{$foo}');
+ $this->assertEquals('Hello $bar World', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test double quotes in single quoted strings
+ */
+ public function testDoubleQuotesInSingleQuotedString()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=\'Hello "World"\'}{$foo}');
+ $this->assertEquals('Hello "World"', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test escaped single quotes in single quoted strings
+ */
+ public function testEscapedSingleQuotesInSingleQuotedString()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=\'Hello \\\'World\'}{$foo}');
+ $this->assertEquals("Hello 'World", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test empty single quoted strings
+ */
+ public function testEmptySingleQuotedString()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=\'\'}{$foo}');
+ $this->assertEquals("", $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/ValueTests/Variables/Stream/StreamVariableTest.php b/tests/UnitTests/TemplateSource/ValueTests/Variables/Stream/StreamVariableTest.php
new file mode 100644
index 00000000..12372251
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/ValueTests/Variables/Stream/StreamVariableTest.php
@@ -0,0 +1,135 @@
+setUpSmarty(__DIR__);
+
+ stream_wrapper_register("var", "VariableStream")
+ or die("Failed to register protocol");
+ $fp = fopen("var://foo", "r+");
+ fwrite($fp, 'hello world');
+ fclose($fp);
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ public function tearDown()
+ {
+ parent::tearDown();
+ stream_wrapper_unregister("var");
+ }
+
+ /**
+ * test stream variable
+ */
+ public function testStreamVariable1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$var:foo}', null, null, $this->smarty);
+ $this->assertEquals('hello world', $this->smarty->fetch($tpl));
+ }
+ /*
+ public function testStreamVariable2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{var:\'foo\'}', null, null, $this->smarty);
+ $this->assertEquals('hello world', $this->smarty->fetch($tpl));
+ }
+
+ public function testStreamVariable3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{var:"foo"}', null, null, $this->smarty);
+ $this->assertEquals('hello world', $this->smarty->fetch($tpl));
+ }
+ */
+ /**
+ * test no existant stream variable
+ */
+ // public function testStreamVariable2()
+ // {
+ // $tpl = $this->smarty->createTemplate('eval:{$var:bar}', null, null, $this->smarty);
+ // $this->assertEquals('', $this->smarty->fetch($tpl));
+ // }
+}
+
+class VariableStream
+{
+ private $position;
+ private $varname;
+
+ public function stream_open($path, $mode, $options, &$opened_path)
+ {
+ $url = parse_url($path);
+ $this->varname = $url["host"];
+ $this->position = 0;
+
+ return true;
+ }
+
+ public function stream_read($count)
+ {
+ $p = &$this->position;
+ $ret = substr($GLOBALS[$this->varname], $p, $count);
+ $p += strlen($ret);
+
+ return $ret;
+ }
+
+ public function stream_write($data)
+ {
+ $v = &$GLOBALS[$this->varname];
+ $l = strlen($data);
+ $p = &$this->position;
+ $v = substr($v, 0, $p) . $data . substr($v, $p += $l);
+
+ return $l;
+ }
+
+ public function stream_tell()
+ {
+ return $this->position;
+ }
+
+ public function stream_eof()
+ {
+ return $this->position >= strlen($GLOBALS[$this->varname]);
+ }
+
+ public function stream_seek($offset, $whence)
+ {
+ $l = strlen($GLOBALS[$this->varname]);
+ $p = &$this->position;
+ switch ($whence) {
+ case SEEK_SET:
+ $newPos = $offset;
+ break;
+ case SEEK_CUR:
+ $newPos = $p + $offset;
+ break;
+ case SEEK_END:
+ $newPos = $l + $offset;
+ break;
+ default:
+ return false;
+ }
+ $ret = ($newPos >= 0 && $newPos <= $l);
+ if ($ret) {
+ $p = $newPos;
+ }
+ return $ret;
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/VariableScopeTest.php b/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/VariableScopeTest.php
new file mode 100644
index 00000000..942717a6
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/VariableScopeTest.php
@@ -0,0 +1,212 @@
+setUpSmarty(__DIR__);
+
+ $this->smarty->assign('foo', 'bar');
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test root variable
+ */
+ public function testVariableScope1_0()
+ {
+ $tpl = $this->smarty->createTemplate('foo.tpl', null, null, $this->smarty);
+ $this->assertEquals("bar", $this->smarty->fetch($tpl));
+ }
+
+ public function testVariableScope1_1()
+ {
+ $this->assertEquals("bar", $this->smarty->fetch('foo.tpl', null, null, $this->smarty));
+ }
+
+ public function testVariableScope12_0()
+ {
+ $tpl = $this->smarty->createTemplate('foo.tpl', $this->smarty);
+ $this->assertEquals("bar", $this->smarty->fetch($tpl));
+ }
+
+ public function testVariableScope12_1()
+ {
+ $this->assertEquals("bar", $this->smarty->fetch('foo.tpl', $this->smarty));
+ }
+
+ public function testVariableScope13()
+ {
+ $tpl = $this->smarty->createTemplate('foo.tpl', $this->smarty);
+ $this->assertEquals("bar", $tpl->fetch());
+ }
+
+ /**
+ * test root variable with data object chain
+ */
+ public function testVariableScope2()
+ {
+ $data1 = new Smarty_Data($this->smarty);
+ $data2 = new Smarty_Data($data1);
+ $tpl = $this->smarty->createTemplate('foo.tpl', null, null, $data2);
+ $this->assertEquals("bar", $this->smarty->fetch($tpl));
+ }
+
+ public function testVariableScope22()
+ {
+ $data1 = new Smarty_Data($this->smarty);
+ $data2 = new Smarty_Data($data1);
+ $tpl = $this->smarty->createTemplate('foo.tpl', $data2);
+ $this->assertEquals("bar", $this->smarty->fetch($tpl));
+ }
+
+ public function testVariableScope23()
+ {
+ $data1 = new Smarty_Data($this->smarty);
+ $data2 = new Smarty_Data($data1);
+ $tpl = $this->smarty->createTemplate('foo.tpl', $data2);
+ $this->assertEquals("bar", $tpl->fetch());
+ }
+
+ /**
+ * test overwrite variable with data object chain
+ */
+ public function testVariableScope3()
+ {
+ $data1 = new Smarty_Data($this->smarty);
+ $data1->assign('foo', 'newvalue');
+ $data2 = new Smarty_Data($data1);
+ $tpl = $this->smarty->createTemplate('foo.tpl', null, null, $data2);
+ // must see the new value
+ $this->assertEquals("newvalue", $this->smarty->fetch($tpl));
+ }
+
+ public function testVariableScope32()
+ {
+ $data1 = new Smarty_Data($this->smarty);
+ $data2 = new Smarty_Data($data1);
+ $tpl = $this->smarty->createTemplate('foo.tpl', $data2);
+ // must see the old value at root
+ $this->assertEquals("bar", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test local variable not seen global
+ */
+ public function testVariableScope4()
+ {
+ $this->smarty->setErrorReporting(error_reporting() & ~(E_NOTICE | E_USER_NOTICE));
+ $tpl = $this->smarty->createTemplate("eval:{\$foo2='localvar'}{\$foo2}", null, null, $this->smarty);
+ // must see local value
+ $this->assertEquals("localvar", $this->smarty->fetch($tpl));
+ // must see $foo2
+ $tpl2 = $this->smarty->createTemplate("eval:{\$foo2}", null, null, $this->smarty);
+ $this->assertEquals("", $this->smarty->fetch($tpl2));
+ }
+
+ public function testVariableScope42()
+ {
+ $this->smarty->setErrorReporting(error_reporting() & ~(E_NOTICE | E_USER_NOTICE));
+ $tpl = $this->smarty->createTemplate("eval:{\$foo2='localvar'}{\$foo2}", null, null, $this->smarty);
+ // must see local value
+ $this->assertEquals("localvar", $this->smarty->fetch($tpl));
+ // must see $foo2
+ $tpl2 = $this->smarty->createTemplate("eval:{\$foo2}", $this->smarty);
+ $this->assertEquals("", $this->smarty->fetch($tpl2));
+ }
+
+ /**
+ * test overwriting by global variable
+ */
+ public function testVariableScope5()
+ {
+ // create variable $foo2
+ $this->smarty->assign('foo2', 'oldvalue');
+ $tpl = $this->smarty->createTemplate("eval:{assign var=foo2 value='newvalue' scope=parent}{\$foo2}", null, null, $this->smarty);
+ // must see the new value
+ $this->assertEquals("newvalue", $this->smarty->fetch($tpl));
+ $tpl2 = $this->smarty->createTemplate("eval:{\$foo2}", null, null, $this->smarty);
+ // must see the new value at root
+ $this->assertEquals("newvalue", $this->smarty->fetch($tpl2));
+ }
+
+ public function testVariableScope52()
+ {
+ // create variable $foo2
+ $this->smarty->assign('foo2', 'oldvalue');
+ $tpl = $this->smarty->createTemplate("eval:{assign var=foo2 value='newvalue' scope=parent}{\$foo2}", null, null, $this->smarty);
+ // must see the new value
+ $this->assertEquals("newvalue", $this->smarty->fetch($tpl));
+ $tpl2 = $this->smarty->createTemplate("eval:{\$foo2}", $this->smarty);
+ // must see the new value at root
+ $this->assertEquals("newvalue", $this->smarty->fetch($tpl2));
+ }
+
+ /**
+ * test creation of global variable in outerscope
+ */
+ public function testVariableScope6()
+ {
+ // create global variable $foo2 in template
+ $tpl = $this->smarty->createTemplate("eval:{assign var=foo2 value='newvalue' scope=parent}{\$foo2}", null, null, $this->smarty);
+ // must see the new value
+ $this->assertEquals("newvalue", $this->smarty->fetch($tpl));
+ $tpl2 = $this->smarty->createTemplate("eval:{\$foo2}", null, null, $this->smarty);
+ // must see the new value at root
+ $this->assertEquals("newvalue", $this->smarty->fetch($tpl2));
+ }
+
+ public function testVariableScope62()
+ {
+ // create global variable $foo2 in template
+ $tpl = $this->smarty->createTemplate("eval:{assign var=foo2 value='newvalue' scope=parent}{\$foo2}", null, null, $this->smarty);
+ // must see the new value
+ $this->assertEquals("newvalue", $this->smarty->fetch($tpl));
+ $tpl2 = $this->smarty->createTemplate("eval:{\$foo2}", $this->smarty);
+ // must see the new value at root
+ $this->assertEquals("newvalue", $this->smarty->fetch($tpl2));
+ }
+
+ public function testDataArray()
+ {
+ // create global variable $foo2 in template
+ $tpl = $this->smarty->createTemplate("eval:{\$foo} {\$foo2}", array('foo' => 'bar', 'foo2' => 'bar2'));
+ $this->assertEquals("bar bar2", $this->smarty->fetch($tpl));
+ }
+
+ public function testDataArray2()
+ {
+ // create global variable $foo2 in template
+ $this->assertEquals("bar bar2", $this->smarty->fetch("eval:{\$foo} {\$foo2}", array('foo' => 'bar', 'foo2' => 'bar2')));
+ }
+
+ public function testAssigns()
+ {
+ $expected = " local local local parent root global parent root global parent root global";
+ $result = $this->smarty->fetch('assign.tpl');
+ $this->assertEquals($expected, $result);
+ }
+
+ public function testAssignsMerge()
+ {
+ $this->smarty->setMergeCompiledIncludes(true);
+ $expected = " local local local parent root global parent root global parent root global";
+ $result = $this->smarty->fetch('assign.tpl');
+ $this->assertEquals($expected, $result);
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/templates/assign.global.tpl b/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/templates/assign.global.tpl
new file mode 100644
index 00000000..1c0381f1
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/templates/assign.global.tpl
@@ -0,0 +1 @@
+{assign var="global" value="global" scope="global"}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/templates/assign.parent.tpl b/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/templates/assign.parent.tpl
new file mode 100644
index 00000000..d66b7328
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/templates/assign.parent.tpl
@@ -0,0 +1 @@
+{assign var="parent" value="parent" scope="parent"} {$local|default:"no-local"} {include "assign.root.tpl"} {$parent|default:"no-parent"} {$root|default:"no-root"} {$global|default:"no-global"}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/templates/assign.root.tpl b/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/templates/assign.root.tpl
new file mode 100644
index 00000000..a8559190
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/templates/assign.root.tpl
@@ -0,0 +1 @@
+{assign var="root" value="root" scope="root"} {$local|default:"no-local"} {include "assign.global.tpl"} {$parent|default:"no-parent"} {$root|default:"no-root"} {$global|default:"no-global"}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/templates/assign.tpl b/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/templates/assign.tpl
new file mode 100644
index 00000000..06a7be65
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/templates/assign.tpl
@@ -0,0 +1 @@
+{assign var="local" value="local"} {$local|default:"no-local"} {include "assign.parent.tpl"} {$parent|default:"no-parent"} {$root|default:"no-root"} {$global|default:"no-global"}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/templates/foo.tpl b/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/templates/foo.tpl
new file mode 100644
index 00000000..b9490d3b
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableScope/templates/foo.tpl
@@ -0,0 +1 @@
+{$foo}
\ No newline at end of file
diff --git a/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableVariable/VariableVariableTest.php b/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableVariable/VariableVariableTest.php
new file mode 100644
index 00000000..1f3935bf
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/ValueTests/Variables/VariableVariable/VariableVariableTest.php
@@ -0,0 +1,61 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test variable name in variable
+ */
+ public function testVariableVariable1()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=\'bar\'}{$bar=123}{${$foo}}');
+ $this->assertEquals('123', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test part of variable name in variable
+ */
+ public function testVariableVariable2()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=\'a\'}{$bar=123}{$b{$foo}r}');
+ $this->assertEquals('123', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test several parts of variable name in variable
+ */
+ public function testVariableVariable3()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=\'a\'}{$foo2=\'r\'}{$bar=123}{$b{$foo}{$foo2}}');
+ $this->assertEquals('123', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test nesed parts of variable name in variable
+ */
+ public function testVariableVariable4()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo=\'ar\'}{$foo2=\'oo\'}{$bar=123}{$b{$f{$foo2}}}');
+ $this->assertEquals('123', $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/Xml/XmlTest.php b/tests/UnitTests/TemplateSource/Xml/XmlTest.php
new file mode 100644
index 00000000..aa3110ff
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/Xml/XmlTest.php
@@ -0,0 +1,92 @@
+ tag handling
+ *
+ * @package PHPunit
+ * @author Uwe Tews
+ */
+
+/**
+ * class for tests
+ *
+ * @backupStaticAttributes enabled
+ */
+class XmlTest extends PHPUnit_Smarty
+{
+ public function setUp()
+ {
+ $this->setUpSmarty(__DIR__);
+ $this->smarty->enableSecurity();
+ $this->smarty->setForceCompile(true);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test standard xml
+ */
+ public function testXml()
+ {
+ $tpl = $this->smarty->createTemplate('xml.tpl');
+ $this->assertEquals('', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test standard xml Smarty::PHP_QUOTE
+ */
+ public function testXmlPhpQuote()
+ {
+ $this->smarty->security_policy->php_handling = Smarty::PHP_QUOTE;
+ $tpl = $this->smarty->createTemplate('xml.tpl');
+ $this->assertEquals('', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test standard xml Smarty::PHP_ALLOW
+ */
+ public function testXmlPhpAllow()
+ {
+ $this->smarty->security_policy->php_handling = Smarty::PHP_ALLOW;
+ $tpl = $this->smarty->createTemplate('xml.tpl');
+ $this->assertEquals('', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test standard xml
+ */
+ public function testXmlCaching()
+ {
+ $this->smarty->security_policy->php_handling = Smarty::PHP_PASSTHRU;
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $content = $this->smarty->fetch('xml.tpl');
+ $this->assertEquals('', $content);
+ }
+
+ /*
+ * test standard xml
+ */
+ public function testXmlCachingPhpQuote()
+ {
+ $this->smarty->security_policy->php_handling = Smarty::PHP_QUOTE;
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $content = $this->smarty->fetch('xml.tpl');
+ $this->assertEquals('', $content);
+ }
+
+ /*
+ * test standard xml
+ */
+ public function testXmlCachingPhpAllow()
+ {
+ $this->smarty->security_policy->php_handling = Smarty::PHP_ALLOW;
+ $this->smarty->caching = true;
+ $this->smarty->cache_lifetime = 1000;
+ $content = $this->smarty->fetch('xml.tpl');
+ $this->assertEquals('', $content);
+ }
+}
diff --git a/tests/UnitTests/TemplateSource/Xml/templates/xml.tpl b/tests/UnitTests/TemplateSource/Xml/templates/xml.tpl
new file mode 100644
index 00000000..b994f536
--- /dev/null
+++ b/tests/UnitTests/TemplateSource/Xml/templates/xml.tpl
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/tests/UnitTests/_Core/AutoEscape/AutoEscapeTest.php b/tests/UnitTests/_Core/AutoEscape/AutoEscapeTest.php
new file mode 100644
index 00000000..cc6fa243
--- /dev/null
+++ b/tests/UnitTests/_Core/AutoEscape/AutoEscapeTest.php
@@ -0,0 +1,31 @@
+setUpSmarty(__DIR__);
+ $this->smarty->setEscapeHtml(true);
+ }
+
+ /**
+ * test 'escapeHtml' property
+ */
+ public function testAutoEscape()
+ {
+ $tpl = $this->smarty->createTemplate('eval:{$foo}');
+ $tpl->assign('foo', '');
+ $this->assertEquals("<a@b.c>", $this->smarty->fetch($tpl));
+ }
+}
diff --git a/tests/UnitTests/_Core/Filter/FilterTest.php b/tests/UnitTests/_Core/Filter/FilterTest.php
new file mode 100644
index 00000000..2ab4700f
--- /dev/null
+++ b/tests/UnitTests/_Core/Filter/FilterTest.php
@@ -0,0 +1,155 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test autoload output filter
+ */
+ public function testAutoloadOutputFilter()
+ {
+ $this->smarty->autoload_filters['output'] = 'trimwhitespace';
+ $tpl = $this->smarty->createTemplate('eval:{"
hello world"}');
+ $this->assertEquals("
hello world", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test autoload variable filter
+ */
+ public function testAutoloadVariableFilter()
+ {
+ $this->smarty->autoload_filters['variable'] = 'htmlspecialchars';
+ $tpl = $this->smarty->createTemplate('eval:{""}');
+ $this->assertEquals("<test>", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test loaded filter
+ */
+ public function testLoadedOutputFilter()
+ {
+ $this->smarty->loadFilter(Smarty::FILTER_OUTPUT, 'trimwhitespace');
+ $tpl = $this->smarty->createTemplate('eval:{"
hello world"}');
+ $this->assertEquals("
hello world", $this->smarty->fetch($tpl));
+ }
+
+ public function testLoadedOutputFilterWrapper()
+ {
+ $this->smartyBC->load_filter(Smarty::FILTER_OUTPUT, 'trimwhitespace');
+ $tpl = $this->smartyBC->createTemplate('eval:{"
hello world"}');
+ $this->assertEquals("
hello world", $this->smartyBC->fetch($tpl));
+ }
+
+ /**
+ * test registered output filter
+ */
+ public function testRegisteredOutputFilter()
+ {
+ $this->smarty->registerFilter(Smarty::FILTER_OUTPUT, 'myoutputfilter');
+ $tpl = $this->smarty->createTemplate('eval:{"hello world"}');
+ $this->assertEquals("hello world", $this->smarty->fetch($tpl));
+ }
+
+ public function testRegisteredOutputFilterWrapper()
+ {
+ $this->smartyBC->register_outputfilter('myoutputfilter');
+ $tpl = $this->smartyBC->createTemplate('eval:{"hello world"}');
+ $this->assertEquals("hello world", $this->smartyBC->fetch($tpl));
+ }
+
+ /**
+ * test registered pre filter
+ */
+ public function testRegisteredPreFilter()
+ {
+ function myprefilter($input)
+ {
+ return '{$foo}' . $input;
+ }
+
+ $this->smarty->registerFilter(Smarty::FILTER_PRE, 'myprefilter');
+ $tpl = $this->smarty->createTemplate('eval:{" hello world"}');
+ $tpl->assign('foo', 'bar');
+ $this->assertEquals("bar hello world", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test registered pre filter class
+ */
+ public function testRegisteredPreFilterClass()
+ {
+ $this->smarty->registerFilter(Smarty::FILTER_PRE, array('myprefilterclass', 'myprefilter'));
+ $tpl = $this->smarty->createTemplate('eval:{" hello world"}');
+ $tpl->assign('foo', 'bar');
+ $this->assertEquals("bar hello world", $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test registered post filter
+ */
+ public function testRegisteredPostFilter()
+ {
+ function mypostfilter($input)
+ {
+ return '{$foo}' . $input;
+ }
+
+ $this->smarty->registerFilter(Smarty::FILTER_POST, 'mypostfilter');
+ $tpl = $this->smarty->createTemplate('eval:{" hello world"}');
+ $tpl->assign('foo', 'bar');
+ $this->assertEquals('{$foo} hello world', $this->smarty->fetch($tpl));
+ }
+
+ /**
+ * test variable filter
+ */
+ public function testLoadedVariableFilter()
+ {
+ $this->smarty->loadFilter("variable", "htmlspecialchars");
+ $tpl = $this->smarty->createTemplate('eval:{$foo}');
+ $tpl->assign('foo', '');
+ $this->assertEquals('<?php ?>', $this->smarty->fetch($tpl));
+ }
+}
+
+Class VarFilter
+{
+ function variablefilter($input, $smarty)
+ {
+ return 'var{$foo}' . $input;
+ }
+}
+
+function myoutputfilter($input)
+{
+ return str_replace(' ', ' ', $input);
+}
+
+class myprefilterclass
+{
+ static function myprefilter($input)
+ {
+ return '{$foo}' . $input;
+ }
+}
diff --git a/tests/UnitTests/_Core/Filter/LoadFilterTest.php b/tests/UnitTests/_Core/Filter/LoadFilterTest.php
new file mode 100644
index 00000000..2f35e0dc
--- /dev/null
+++ b/tests/UnitTests/_Core/Filter/LoadFilterTest.php
@@ -0,0 +1,29 @@
+setUpSmarty(__DIR__);
+ }
+
+ /**
+ * test loadFilter method
+ */
+ public function testLoadFilter()
+ {
+ $this->smarty->loadFilter('output', 'trimwhitespace');
+ $this->assertTrue(is_callable($this->smarty->registered_filters['output']['smarty_outputfilter_trimwhitespace']));
+ }
+}
diff --git a/tests/UnitTests/_Core/Filter/RegisterFilterTest.php b/tests/UnitTests/_Core/Filter/RegisterFilterTest.php
new file mode 100644
index 00000000..9f71eff0
--- /dev/null
+++ b/tests/UnitTests/_Core/Filter/RegisterFilterTest.php
@@ -0,0 +1,156 @@
+setUpSmarty(__DIR__);
+ }
+
+ /**
+ * test register->preFilter method for function
+ */
+ public function testRegisterPrefilterFunction()
+ {
+ $this->smarty->registerFilter(Smarty::FILTER_PRE, 'myfilter');
+ $this->assertTrue(is_callable($this->smarty->registered_filters['pre']['myfilter']));
+ }
+
+ /**
+ * test register->preFilter method for class method
+ */
+ public function testRegisterPrefiltermethod()
+ {
+ $this->smarty->registerFilter(Smarty::FILTER_PRE, array('myfilterclass', 'execute'));
+ $this->assertTrue(is_callable($this->smarty->registered_filters['pre']['myfilterclass_execute']));
+ }
+
+ /**
+ * test register->preFilter method for class object
+ */
+ public function testRegisterPrefilterObject()
+ {
+ $this->smarty->registerFilter(Smarty::FILTER_PRE, array(new myfilterclass, 'execute'));
+ $this->assertTrue(is_callable($this->smarty->registered_filters['pre']['myfilterclass_execute']));
+ }
+
+ /**
+ * test unregister->preFilter method for function
+ */
+ public function testUnegisterPrefilterFunction()
+ {
+ $this->smarty->registerFilter(Smarty::FILTER_PRE, 'myfilter');
+ $this->smarty->unregisterFilter(Smarty::FILTER_PRE, 'myfilter');
+ $this->assertFalse(isset($this->smarty->registered_filters['pre']['myfilter']));
+ }
+
+ /**
+ * test unregister->preFilter method for class method
+ */
+ public function testUnregisterPrefiltermethod()
+ {
+ $this->smarty->registerFilter(Smarty::FILTER_PRE, array('myfilterclass', 'execute'));
+ $this->smarty->unregisterFilter(Smarty::FILTER_PRE, array('myfilterclass', 'execute'));
+ $this->assertFalse(isset($this->smarty->registered_filters['pre']['myfilterclass_execute']));
+ }
+
+ /**
+ * test register->postFilter method for function
+ */
+ public function testRegisterPostfilterFunction()
+ {
+ $this->smarty->registerFilter(Smarty::FILTER_POST, 'myfilter');
+ $this->assertTrue(is_callable($this->smarty->registered_filters['post']['myfilter']));
+ }
+
+ /**
+ * test register->postFilter method for class method
+ */
+ public function testRegisterPostfiltermethod()
+ {
+ $this->smarty->registerFilter(Smarty::FILTER_POST, array('myfilterclass', 'execute'));
+ $this->assertTrue(is_callable($this->smarty->registered_filters['post']['myfilterclass_execute']));
+ }
+
+ /**
+ * test unregister->postFilter method for function
+ */
+ public function testUnegisterPostfilterFunction()
+ {
+ $this->smarty->registerFilter(Smarty::FILTER_POST, 'myfilter');
+ $this->smarty->unregisterFilter(Smarty::FILTER_POST, 'myfilter');
+ $this->assertFalse(isset($this->smarty->registered_filters['post']['myfilter']));
+ }
+
+ /**
+ * test unregister->postFilter method for class method
+ */
+ public function testUnregisterPostfiltermethod()
+ {
+ $this->smarty->registerFilter(Smarty::FILTER_POST, array('myfilterclass', 'execute'));
+ $this->smarty->unregisterFilter(Smarty::FILTER_POST, array('myfilterclass', 'execute'));
+ $this->assertFalse(isset($this->smarty->registered_filters['post']['myfilterclass_execute']));
+ }
+
+ /**
+ * test register->outputFilter method for function
+ */
+ public function testRegisterOutputfilterFunction()
+ {
+ $this->smarty->registerFilter(Smarty::FILTER_OUTPUT, 'myfilter');
+ $this->assertTrue(is_callable($this->smarty->registered_filters['output']['myfilter']));
+ }
+
+ /**
+ * test register->outputFilter method for class method
+ */
+ public function testRegisterOutputfiltermethod()
+ {
+ $this->smarty->registerFilter(Smarty::FILTER_OUTPUT, array('myfilterclass', 'execute'));
+ $this->assertTrue(is_callable($this->smarty->registered_filters['output']['myfilterclass_execute']));
+ }
+
+ /**
+ * test unregister->outputFilter method for function
+ */
+ public function testUnegisterOutputfilterFunction()
+ {
+ $this->smarty->registerFilter(Smarty::FILTER_OUTPUT, 'myfilter');
+ $this->smarty->unregisterFilter(Smarty::FILTER_OUTPUT, 'myfilter');
+ $this->assertFalse(isset($this->smarty->registered_filters['output']['myfilter']));
+ }
+
+ /**
+ * test unregister->outputFilter method for class method
+ */
+ public function testUnregisterOutputfiltermethod()
+ {
+ $this->smarty->registerFilter(Smarty::FILTER_OUTPUT, array('myfilterclass', 'execute'));
+ $this->smarty->unregisterFilter(Smarty::FILTER_OUTPUT, array('myfilterclass', 'execute'));
+ $this->assertFalse(isset($this->smarty->registered_filters['output']['myfilterclass_execute']));
+ }
+}
+
+function myfilter($input)
+{
+ return $input;
+}
+
+class myfilterclass
+{
+ static function execute($input)
+ {
+ return $input;
+ }
+}
diff --git a/tests/UnitTests/_Core/GetterSetter/GetterSetterTest.php b/tests/UnitTests/_Core/GetterSetter/GetterSetterTest.php
new file mode 100644
index 00000000..214589d5
--- /dev/null
+++ b/tests/UnitTests/_Core/GetterSetter/GetterSetterTest.php
@@ -0,0 +1,73 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+
+ /**
+ * test setter on Smarty object
+ */
+ public function testSmartySetter()
+ {
+ $this->smarty->setLeftDelimiter('<{');
+ $this->smarty->setRightDelimiter('}>');
+ $this->assertEquals('<{', $this->smarty->left_delimiter);
+ $this->assertEquals('}>', $this->smarty->right_delimiter);
+ }
+
+ /**
+ * test getter on Smarty object
+ */
+ public function testSmartyGetter()
+ {
+ $this->smarty->setLeftDelimiter('<{');
+ $this->smarty->setRightDelimiter('}>');
+ $this->assertEquals('<{', $this->smarty->getLeftDelimiter());
+ $this->assertEquals('}>', $this->smarty->getRightDelimiter());
+ }
+
+ /**
+ * test setter on Template object
+ */
+ public function testTemplateSetter()
+ {
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $tpl->setLeftDelimiter('<{');
+ $tpl->setRightDelimiter('}>');
+ $this->assertEquals('<{', $tpl->smarty->left_delimiter);
+ $this->assertEquals('}>', $tpl->smarty->right_delimiter);
+ $this->assertEquals('{', $this->smarty->left_delimiter);
+ $this->assertEquals('}', $this->smarty->right_delimiter);
+ }
+
+ /**
+ * test getter on Template object
+ */
+ public function testTemplateGetter()
+ {
+ $tpl = $this->smarty->createTemplate('helloworld.tpl');
+ $tpl->setLeftDelimiter('<{');
+ $tpl->setRightDelimiter('}>');
+ $this->assertEquals('<{', $tpl->getLeftDelimiter());
+ $this->assertEquals('}>', $tpl->getRightDelimiter());
+ }
+}
diff --git a/tests/UnitTests/_Core/LoadPlugin/DefaultPluginHandlerTest.php b/tests/UnitTests/_Core/LoadPlugin/DefaultPluginHandlerTest.php
new file mode 100644
index 00000000..76d0cd18
--- /dev/null
+++ b/tests/UnitTests/_Core/LoadPlugin/DefaultPluginHandlerTest.php
@@ -0,0 +1,151 @@
+setUpSmarty(__DIR__);
+ $this->smarty->setForceCompile(true);
+ $this->smarty->disableSecurity();
+ $this->smarty->registerDefaultPluginHandler('my_plugin_handler');
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ public function testDefaultFunctionScript()
+ {
+ $this->assertEquals("scriptfunction foo bar", $this->smarty->fetch('test_default_function_script.tpl'));
+ }
+
+ public function testDefaultFunctionScriptNotCachable1()
+ {
+ $this->smarty->assign('foo', 'foo');
+ $this->smarty->caching = 1;
+ $this->assertEquals("scriptfunction foo", $this->smarty->fetch('test_default_function_script_notcachable.tpl'));
+ }
+
+ public function testDefaultFunctionScriptNotCachable2()
+ {
+ $this->smarty->assign('foo', 'bar');
+ $this->smarty->caching = 1;
+ $this->assertEquals("scriptfunction bar", $this->smarty->fetch('test_default_function_script_notcachable.tpl'));
+ }
+
+ public function testDefaultFunctionLocal()
+ {
+ $this->assertEquals("localfunction foo bar", $this->smarty->fetch('test_default_function_local.tpl'));
+ }
+
+ public function testDefaultCompilerFunctionScript()
+ {
+ $this->assertEquals("echo 'scriptcompilerfunction '.'foo bar';", $this->smarty->fetch('test_default_compiler_function_script.tpl'));
+ }
+
+ public function testDefaultBlockScript()
+ {
+ $this->assertEquals("scriptblock foo bar", $this->smarty->fetch('test_default_block_script.tpl'));
+ }
+
+ public function testDefaultModifierScript()
+ {
+ $this->smarty->assign('foo', 'bar');
+ $this->assertEquals("scriptmodifier default bar", $this->smarty->fetch('test_default_modifier_script.tpl'));
+ }
+
+ public function testDefaultModifier()
+ {
+ $this->smarty->assign('foo', 'bar');
+ $this->assertEquals("localmodifier bar", $this->smarty->fetch('test_default_modifier.tpl'));
+ }
+}
+
+function my_plugin_handler($tag, $type, $template, &$callback, &$script, &$cachable)
+{
+ switch ($type) {
+ case Smarty::PLUGIN_FUNCTION:
+ switch ($tag) {
+ case 'scriptfunction':
+ $script = './scripts/script_function_tag.php';
+ $callback = 'default_script_function_tag';
+
+ return true;
+ case 'scriptfunctionnotcachable':
+ $script = './scripts/script_function_tag.php';
+ $callback = 'default_script_function_tag';
+ $cachable = false;
+
+ return true;
+ case 'localfunction':
+ $callback = 'default_local_function_tag';
+
+ return true;
+ default:
+ return false;
+ }
+ case Smarty::PLUGIN_COMPILER:
+ switch ($tag) {
+ case 'scriptcompilerfunction':
+ $script = './scripts/script_compiler_function_tag.php';
+ $callback = 'default_script_compiler_function_tag';
+
+ return true;
+ default:
+ return false;
+ }
+ case Smarty::PLUGIN_BLOCK:
+ switch ($tag) {
+ case 'scriptblock':
+ $script = './scripts/script_block_tag.php';
+ $callback = 'default_script_block_tag';
+
+ return true;
+ default:
+ return false;
+ }
+ case Smarty::PLUGIN_MODIFIER:
+ switch ($tag) {
+ case 'scriptmodifier':
+ $script = './scripts/script_modifier.php';
+ $callback = 'default_script_modifier';
+
+ return true;
+ case 'mydefaultmodifier':
+ $callback = 'default_local_modifier';
+
+ return true;
+ case 'mydefaultstaticmodifier':
+ $script = './scripts/script_default_static_modifier.php';
+ $callback = array('DefModifier', 'default_static_modifier');
+
+ return true;
+ default:
+ return false;
+ }
+ default:
+ return false;
+ }
+}
+
+function default_local_function_tag($params, $template)
+{
+ return 'localfunction ' . $params['value'];
+}
+
+function default_local_modifier($input)
+{
+ return 'localmodifier ' . $input;
+}
diff --git a/tests/UnitTests/_Core/LoadPlugin/LoadPluginTest.php b/tests/UnitTests/_Core/LoadPlugin/LoadPluginTest.php
new file mode 100644
index 00000000..b23b9951
--- /dev/null
+++ b/tests/UnitTests/_Core/LoadPlugin/LoadPluginTest.php
@@ -0,0 +1,52 @@
+setUpSmarty(__DIR__);
+ }
+
+ /**
+ * loadPlugin test unkown plugin
+ */
+ public function testLoadPluginErrorReturn()
+ {
+ $this->assertFalse($this->smarty->loadPlugin('Smarty_Not_Known'));
+ }
+
+ /**
+ * loadPlugin test Smarty_Internal_Debug exists
+ */
+ public function testLoadPluginSmartyInternalDebug()
+ {
+ $this->assertTrue($this->smarty->loadPlugin('Smarty_Internal_Debug') == true);
+ }
+
+ /**
+ * loadPlugin test $template_class exists
+ */
+ public function testLoadPluginSmartyTemplateClass()
+ {
+ $this->assertTrue($this->smarty->loadPlugin($this->smarty->template_class) == true);
+ }
+
+ /**
+ * loadPlugin test loaging from plugins_dir
+ */
+ public function testLoadPluginSmartyPluginCounter()
+ {
+ $this->assertTrue($this->smarty->loadPlugin('Smarty_Function_Counter') == true);
+ }
+}
diff --git a/tests/UnitTests/_Core/LoadPlugin/scripts/script_block_tag.php b/tests/UnitTests/_Core/LoadPlugin/scripts/script_block_tag.php
new file mode 100644
index 00000000..a61f14d6
--- /dev/null
+++ b/tests/UnitTests/_Core/LoadPlugin/scripts/script_block_tag.php
@@ -0,0 +1,7 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ public function error_handler($errno, $errstr, $errfile, $errline, $errcontext)
+ {
+ $this->_errors[] = $errfile . ' line ' . $errline;
+ }
+
+ public function testMuted()
+ {
+ set_error_handler(array($this, 'error_handler'));
+ Smarty::muteExpectedErrors();
+
+ $this->smarty->clearCache('default.tpl');
+ $this->smarty->clearCompiledTemplate('default.tpl');
+ $this->smarty->fetch('default.tpl');
+
+ $this->assertEquals($this->_errors, array());
+
+ @filemtime('ckxladanwijicajscaslyxck');
+ $error = array(__FILE__ . ' line ' . (__LINE__ - 1));
+ $this->assertEquals($this->_errors, $error);
+
+ Smarty::unmuteExpectedErrors();
+ restore_error_handler();
+ }
+
+ /**
+ *
+ * @rrunInSeparateProcess
+ *
+ */
+ public function testUnmuted()
+ {
+ set_error_handler(array($this, 'error_handler'));
+
+ $this->smarty->clearCache('default.tpl');
+ $this->smarty->clearCompiledTemplate('default.tpl');
+ $this->smarty->fetch('default.tpl');
+
+ $this->assertEquals(Smarty::$_IS_WINDOWS ? 5 : 4, count($this->_errors));
+
+ @filemtime('ckxladanwijicajscaslyxck');
+ $this->assertEquals(Smarty::$_IS_WINDOWS ? 6 : 5, count($this->_errors));
+
+ restore_error_handler();
+ }
+
+ /**
+ *
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testMutedCaching()
+ {
+ set_error_handler(array($this, 'error_handler'));
+ Smarty::muteExpectedErrors();
+
+ $this->smarty->caching = true;
+ $this->smarty->clearCache('default.tpl');
+ $this->smarty->clearCompiledTemplate('default.tpl');
+ $this->smarty->fetch('default.tpl');
+
+ $this->assertEquals($this->_errors, array());
+
+ @filemtime('ckxladanwijicajscaslyxck');
+ $error = array(__FILE__ . ' line ' . (__LINE__ - 1));
+ $this->assertEquals($error, $this->_errors);
+
+ Smarty::unmuteExpectedErrors();
+ restore_error_handler();
+ }
+
+ /**
+ * @run InSeparateProcess
+ * @preserveGlobalState disabled
+ *
+ */
+ public function testUnmutedCaching()
+ {
+ set_error_handler(array($this, 'error_handler'));
+
+ $this->smarty->caching = true;
+ $this->smarty->clearCache('default.tpl');
+ $this->smarty->clearCompiledTemplate('default.tpl');
+ $this->smarty->fetch('default.tpl');
+
+ $this->assertEquals(Smarty::$_IS_WINDOWS ? 7 : 5, count($this->_errors));
+
+ @filemtime('ckxladanwijicajscaslyxck');
+ $error = array(__FILE__ . ' line ' . (__LINE__ - 1));
+ $this->assertEquals(Smarty::$_IS_WINDOWS ? 8 : 6, count($this->_errors));
+
+ restore_error_handler();
+ }
+}
diff --git a/tests/UnitTests/_Core/MuteExpectedErrors/templates/default.tpl b/tests/UnitTests/_Core/MuteExpectedErrors/templates/default.tpl
new file mode 100644
index 00000000..585945d3
--- /dev/null
+++ b/tests/UnitTests/_Core/MuteExpectedErrors/templates/default.tpl
@@ -0,0 +1 @@
+{$foo|default:""} /* should compile something with @silence error suppression */
\ No newline at end of file
diff --git a/tests/UnitTests/_Core/PluginTests/OutputFilterTrimWhitespaceTest.php b/tests/UnitTests/_Core/PluginTests/OutputFilterTrimWhitespaceTest.php
new file mode 100644
index 00000000..90a4aa5f
--- /dev/null
+++ b/tests/UnitTests/_Core/PluginTests/OutputFilterTrimWhitespaceTest.php
@@ -0,0 +1,40 @@
+setUpSmarty(__DIR__);
+ $this->smarty->loadFilter('output', 'trimwhitespace');
+ }
+
+ public function testWhitespace()
+ {
+ $expected =
+' whitespace
+ foobar
+
+ foobar
+
';
+
+
+ $this->assertEquals($this->normalizeString($expected), $this->normalizeString($this->smarty->fetch('whitespace.tpl')));
+ }
+}
diff --git a/tests/UnitTests/_Core/PluginTests/PHPunitplugins/function.chain1.php b/tests/UnitTests/_Core/PluginTests/PHPunitplugins/function.chain1.php
new file mode 100644
index 00000000..64b6f05d
--- /dev/null
+++ b/tests/UnitTests/_Core/PluginTests/PHPunitplugins/function.chain1.php
@@ -0,0 +1,7 @@
+smarty->loadPlugin('smarty_function_chain2');
+
+ return smarty_function_chain2($params, $tpl);
+}
diff --git a/tests/UnitTests/_Core/PluginTests/PHPunitplugins/function.chain2.php b/tests/UnitTests/_Core/PluginTests/PHPunitplugins/function.chain2.php
new file mode 100644
index 00000000..480ba0e0
--- /dev/null
+++ b/tests/UnitTests/_Core/PluginTests/PHPunitplugins/function.chain2.php
@@ -0,0 +1,7 @@
+smarty->loadPlugin('smarty_function_chain3');
+
+ return smarty_function_chain3($params, $tpl);
+}
diff --git a/tests/UnitTests/_Core/PluginTests/PHPunitplugins/function.chain3.php b/tests/UnitTests/_Core/PluginTests/PHPunitplugins/function.chain3.php
new file mode 100644
index 00000000..6c0f9920
--- /dev/null
+++ b/tests/UnitTests/_Core/PluginTests/PHPunitplugins/function.chain3.php
@@ -0,0 +1,5 @@
+setUpSmarty(__DIR__);
+ }
+
+ public function testPluginChainedLoad()
+ {
+ $this->smarty->addPluginsDir(__DIR__ . "/PHPunitplugins/");
+ $this->assertContains('from chain3', $this->smarty->fetch('test_plugin_chained_load.tpl'));
+ }
+}
diff --git a/tests/UnitTests/_Core/PluginTests/Shared/SharedFunctionsTest.php b/tests/UnitTests/_Core/PluginTests/Shared/SharedFunctionsTest.php
new file mode 100644
index 00000000..35349413
--- /dev/null
+++ b/tests/UnitTests/_Core/PluginTests/Shared/SharedFunctionsTest.php
@@ -0,0 +1,29 @@
+setUpSmarty(__DIR__);
+ }
+
+ /**
+ * test smarty_function_escape_special_chars()
+ */
+ public function testEscapeSpecialChars()
+ {
+ require_once SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php';
+
+ $this->assertEquals('hello<world ©', smarty_function_escape_special_chars('helloassertEquals('ö€', smarty_function_escape_special_chars('ö€'));
+ }
+}
diff --git a/tests/UnitTests/_Core/PluginTests/helpers/_object_tostring.php b/tests/UnitTests/_Core/PluginTests/helpers/_object_tostring.php
new file mode 100644
index 00000000..4cb55e7f
--- /dev/null
+++ b/tests/UnitTests/_Core/PluginTests/helpers/_object_tostring.php
@@ -0,0 +1,26 @@
+string = (string) $string;
+ }
+
+ public function __toString()
+ {
+ return $this->string;
+ }
+}
+
+class _object_noString
+{
+ protected $string = null;
+
+ public function __construct($string)
+ {
+ $this->string = (string) $string;
+ }
+}
diff --git a/tests/UnitTests/_Core/PluginTests/templates/test_plugin_chained_load.tpl b/tests/UnitTests/_Core/PluginTests/templates/test_plugin_chained_load.tpl
new file mode 100644
index 00000000..3badb70f
--- /dev/null
+++ b/tests/UnitTests/_Core/PluginTests/templates/test_plugin_chained_load.tpl
@@ -0,0 +1 @@
+{chain1}
\ No newline at end of file
diff --git a/tests/UnitTests/_Core/PluginTests/templates/whitespace.tpl b/tests/UnitTests/_Core/PluginTests/templates/whitespace.tpl
new file mode 100644
index 00000000..0dc27012
--- /dev/null
+++ b/tests/UnitTests/_Core/PluginTests/templates/whitespace.tpl
@@ -0,0 +1,45 @@
+
+
+
+
+
+ whitespace
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ foobar
+
+
+ foobar
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/UnitTests/_Core/SmartyBC/SmartyBcTest.php b/tests/UnitTests/_Core/SmartyBC/SmartyBcTest.php
new file mode 100644
index 00000000..fc5f63ae
--- /dev/null
+++ b/tests/UnitTests/_Core/SmartyBC/SmartyBcTest.php
@@ -0,0 +1,35 @@
+setUpSmarty(__DIR__);
+ }
+
+
+ public function testInit()
+ {
+ $this->cleanDirs();
+ }
+ /**
+ * test {php} tag
+ */
+ public function testSmartyPhpTag()
+ {
+ $this->assertEquals('hello world', $this->smartyBC->fetch('eval:{php} echo "hello world"; {/php}'));
+ }
+}
diff --git a/tests/composer.json b/tests/composer.json
new file mode 100644
index 00000000..3a99dd54
--- /dev/null
+++ b/tests/composer.json
@@ -0,0 +1,42 @@
+{
+ "name": "smarty/smarty-phpunit",
+ "type": "library",
+ "description": "Smarty - the compiling PHP template engine PHPUnit tests",
+ "keywords": ["templating"],
+ "homepage": "http://www.smarty.net",
+ "license": "LGPL-3.0",
+ "authors": [
+ {
+ "name": "Monte Ohrt",
+ "email": "monte@ohrt.com"
+ },
+ {
+ "name": "Uwe Tews",
+ "email": "uwe.tews@googlemail.com"
+ },
+ {
+ "name": "Rodney Rehm",
+ "email": "rodney.rehm@medialize.de"
+ }
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.org/smarty",
+ "issues": "http://code.google.com/p/smarty-php/issues/list",
+ "forum": "http://www.smarty.net/forums/"
+ },
+ "require": {
+ "phpunit/phpunit": "*",
+ "php": ">=5.2"
+ },
+ "autoload": {
+ "classmap": [
+ "Bootstrap.php",
+ "PHPUnit_Smarty.php"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1.x-dev"
+ }
+ }
+}
diff --git a/tests/config.xml b/tests/config.xml
new file mode 100644
index 00000000..42b76161
--- /dev/null
+++ b/tests/config.xml
@@ -0,0 +1,17 @@
+
+
+ true
+
+ false
+ false
+ false
+
+
+ false
+
+
+ mysql:dbname=test;host=localhost
+ smarty
+
+
+
\ No newline at end of file
diff --git a/tests/phpunit-coverage.bat b/tests/phpunit-coverage.bat
new file mode 100644
index 00000000..80bc0551
--- /dev/null
+++ b/tests/phpunit-coverage.bat
@@ -0,0 +1 @@
+php ../../phpunit/phpunit/phpunit --coverage-html ./coverage ./
\ No newline at end of file
diff --git a/tests/phpunit.bat b/tests/phpunit.bat
new file mode 100644
index 00000000..de97f5a4
--- /dev/null
+++ b/tests/phpunit.bat
@@ -0,0 +1 @@
+php ../../phpunit/phpunit/phpunit ./
\ No newline at end of file
diff --git a/tests/phpunit.sh b/tests/phpunit.sh
new file mode 100644
index 00000000..bf10b578
--- /dev/null
+++ b/tests/phpunit.sh
@@ -0,0 +1,3 @@
+#! /bin/bash
+
+php ../../phpunit/phpunit/phpunit ./
diff --git a/tests/phpunit.xml b/tests/phpunit.xml
new file mode 100644
index 00000000..7fdbe1a7
--- /dev/null
+++ b/tests/phpunit.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+ UnitTests
+
+
+
+ ./
+ cache
+ templates_c
+
+
+ ../smarty/libs
+ ../smarty/libs/plugins
+ ../smarty/libs/sysplugins
+ ../smarty/demo/plugins
+
+
+
+ highlight="false" lowUpperBound="35" highLowerBound="70"/>
+
+
+
+
diff --git a/tests/phpunit_hhvm.sh b/tests/phpunit_hhvm.sh
new file mode 100644
index 00000000..54c98c0a
--- /dev/null
+++ b/tests/phpunit_hhvm.sh
@@ -0,0 +1,3 @@
+#! /bin/bash
+
+hhvm ../../phpunit/phpunit/phpunit ./