More test, reformat code to PSR-0

This commit is contained in:
Ivan Shalganov 2014-02-27 16:30:44 +04:00
parent e00d6c7e50
commit c210303b72
18 changed files with 229 additions and 276 deletions

View File

@ -30,7 +30,7 @@ For example,
It is new or current item
{case 'current'}
It is current item
{case 'new', $.const.NEW_STATUS}
{case 'new', 'newer'}
It is new item, again
{default}
I don't know the type {$type}

View File

@ -302,7 +302,7 @@ class Fenom
*/
public function setCompileDir($dir)
{
if(!is_writable($dir)) {
if (!is_writable($dir)) {
throw new LogicException("Cache directory $dir is not writable");
}
$this->_compile_dir = $dir;
@ -630,7 +630,7 @@ class Fenom
public function addProvider($scm, \Fenom\ProviderInterface $provider, $compile_path = null)
{
$this->_providers[$scm] = $provider;
if($compile_path) {
if ($compile_path) {
$this->_compiles[$scm] = $compile_path;
}
return $this;
@ -738,7 +738,7 @@ class Fenom
public function getTemplate($template, $options = 0)
{
$options |= $this->_options;
if(is_array($template)) {
if (is_array($template)) {
$key = dechex($options) . "@" . implode(",", $template);
} else {
$key = dechex($options) . "@" . $template;
@ -805,12 +805,12 @@ class Fenom
*/
private function _getCacheName($tpl, $options)
{
if(is_array($tpl)) {
if (is_array($tpl)) {
$hash = implode(".", $tpl) . ":" . $options;
foreach($tpl as &$t) {
foreach ($tpl as &$t) {
$t = str_replace(":", "_", basename($t));
}
return implode("~", $tpl).".".sprintf("%x.%x.php", crc32($hash), strlen($hash));
return implode("~", $tpl) . "." . sprintf("%x.%x.php", crc32($hash), strlen($hash));
} else {
$hash = $tpl . ":" . $options;
return sprintf("%s.%x.%x.php", str_replace(":", "_", basename($tpl)), crc32($hash), strlen($hash));
@ -829,12 +829,12 @@ class Fenom
public function compile($tpl, $store = true, $options = 0)
{
$options = $this->_options | $options;
if(is_string($tpl)) {
if (is_string($tpl)) {
$template = $this->getRawTemplate()->load($tpl);
} else {
$template = $this->getRawTemplate()->load($tpl[0], false);
unset($tpl[0]);
foreach($tpl as $t) {
foreach ($tpl as $t) {
$template->extend($t);
}
}

View File

@ -8,6 +8,7 @@
* file that was distributed with this source code.
*/
namespace Fenom;
use Fenom\Error\InvalidUsageException;
use Fenom\Error\UnexpectedTokenException;
use Fenom\Tokenizer;
@ -36,20 +37,20 @@ class Compiler
$cname = $tpl->parsePlainArg($tokens, $name);
$p = $tpl->parseParams($tokens);
if ($name) {
if($tpl->getStorage()->getOptions() & \Fenom::FORCE_INCLUDE) {
if ($tpl->getStorage()->getOptions() & \Fenom::FORCE_INCLUDE) {
$inc = $tpl->getStorage()->compile($name, false);
$tpl->addDepend($inc);
$var = $tpl->tmpVar();
if($p) {
return $var.' = $var; $var = ' . self::toArray($p) . ' + $var; ?>' . $inc->getBody() . '<?php $var = '.$var.'; unset('.$var.');';
if ($p) {
return $var . ' = $var; $var = ' . self::toArray($p) . ' + $var; ?>' . $inc->getBody() . '<?php $var = ' . $var . '; unset(' . $var . ');';
} else {
return $var.' = $var; ?>' . $inc->getBody() . '<?php $var = '.$var.'; unset('.$var.');';
return $var . ' = $var; ?>' . $inc->getBody() . '<?php $var = ' . $var . '; unset(' . $var . ');';
}
} elseif(!$tpl->getStorage()->templateExists($name)) {
} elseif (!$tpl->getStorage()->templateExists($name)) {
throw new \LogicException("Template $name not found");
}
}
if($p) {
if ($p) {
return '$tpl->getStorage()->getTemplate(' . $cname . ')->display(' . self::toArray($p) . ' + $var);';
} else {
return '$tpl->getStorage()->getTemplate(' . $cname . ')->display($var);';
@ -339,7 +340,7 @@ class Compiler
$scope["last"] = array();
$scope["default"] = '';
$scope["var"] = $scope->tpl->tmpVar();
$scope["expr"] = $scope["var"].' = strval('.$expr.')';
$scope["expr"] = $scope["var"] . ' = strval(' . $expr . ')';
// lazy init
return '';
}
@ -414,15 +415,15 @@ class Compiler
{
self::_caseResort($scope);
$expr = $scope["var"];
$code = $scope["expr"].";\n";
$code = $scope["expr"] . ";\n";
$default = $scope["default"];
foreach ($scope["case"] as $case => $content) {
if(is_numeric($case)) {
if (is_numeric($case)) {
$case = "'$case'";
}
$code .= "if($expr == $case) {\n?>$content<?php\n} else";
}
$code .= " {\n?>$default<?php\n}\nunset(".$scope["var"].")";
$code .= " {\n?>$default<?php\n}\nunset(" . $scope["var"] . ")";
return $code;
}
@ -478,12 +479,12 @@ class Compiler
throw new InvalidUsageException("Tags {extends} can not be nested");
}
$cname = $tpl->parsePlainArg($tokens, $name);
if($name) {
if ($name) {
$tpl->extends = $name;
} else {
$tpl->dynamic_extends = $cname;
}
if(!$tpl->extend_body) {
if (!$tpl->extend_body) {
$tpl->addPostCompile(__CLASS__ . "::extendBody");
$tpl->extend_body = true;
}
@ -496,18 +497,18 @@ class Compiler
*/
public static function extendBody($tpl, &$body)
{
if($tpl->dynamic_extends) {
if(!$tpl->ext_stack) {
if ($tpl->dynamic_extends) {
if (!$tpl->ext_stack) {
$tpl->ext_stack[] = $tpl->getName();
}
foreach($tpl->ext_stack as &$t) {
foreach ($tpl->ext_stack as &$t) {
$stack[] = "'$t'";
}
$stack[] = $tpl->dynamic_extends;
$body = '<?php $tpl->getStorage()->display(array('.implode(', ', $stack).'), $var); ?>';
$body = '<?php $tpl->getStorage()->display(array(' . implode(', ', $stack) . '), $var); ?>';
} else {
$child = $tpl;
while($child && $child->extends) {
while ($child && $child->extends) {
$parent = $tpl->extend($child->extends);
$child = $parent->extends ? $parent : false;
}
@ -549,7 +550,7 @@ class Compiler
$scope->tpl->_compatible = true;
}
$scope["cname"] = $scope->tpl->parsePlainArg($tokens, $name);
if(!$name) {
if (!$name) {
throw new \RuntimeException("Only static names for blocks allowed");
}
$scope["name"] = $name;
@ -565,27 +566,27 @@ class Compiler
$tpl = $scope->tpl;
$name = $scope["name"];
if(isset($tpl->blocks[$name])) { // block defined
$block = &$tpl->blocks[$name];
if($block['use_parent']) {
if (isset($tpl->blocks[$name])) { // block defined
$block = & $tpl->blocks[$name];
if ($block['use_parent']) {
$parent = $scope->getContent();
$block['block'] = str_replace($block['use_parent']." ?>", "?>".$parent, $block['block']);
$block['block'] = str_replace($block['use_parent'] . " ?>", "?>" . $parent, $block['block']);
}
if(!$block["import"]) { // not from {use} - redefine block
if (!$block["import"]) { // not from {use} - redefine block
$scope->replaceContent($block["block"]);
return;
} elseif($block["import"] != $tpl->getName()) { // tag {use} was in another template
} elseif ($block["import"] != $tpl->getName()) { // tag {use} was in another template
$tpl->blocks[$scope["name"]]["import"] = false;
$scope->replaceContent($block["block"]);
}
}
$tpl->blocks[$scope["name"]] = array(
"from" => $tpl->getName(),
"import" => false,
"use_parent" => $scope["use_parent"],
"block" => $scope->getContent()
"from" => $tpl->getName(),
"import" => false,
"use_parent" => $scope["use_parent"],
"block" => $scope->getContent()
);
}
@ -599,8 +600,8 @@ class Compiler
public static function tagParent($tokens, Scope $scope)
{
$block_scope = $scope->tpl->getParentScope('block');
if(!$block_scope['use_parent']) {
$block_scope['use_parent'] = "/* %%parent#".mt_rand(0, 1e6)."%% */";
if (!$block_scope['use_parent']) {
$block_scope['use_parent'] = "/* %%parent#" . mt_rand(0, 1e6) . "%% */";
}
return $block_scope['use_parent'];
}

View File

@ -9,6 +9,7 @@
*/
namespace Fenom\Error;
use Fenom\Tokenizer;
/**

View File

@ -8,6 +8,7 @@
* file that was distributed with this source code.
*/
namespace Fenom;
use Fenom;
/**

View File

@ -8,6 +8,7 @@
* file that was distributed with this source code.
*/
namespace Fenom;
use Fenom;
use Fenom\Error\UnexpectedTokenException;
use Fenom\Error\CompileException;
@ -154,9 +155,9 @@ class Template extends Render
*/
public function __construct(Fenom $fenom, $options)
{
$this->_fenom = $fenom;
$this->_options = $options;
$this->_filters = $this->_fenom->getFilters();
$this->_fenom = $fenom;
$this->_options = $options;
$this->_filters = $this->_fenom->getFilters();
$this->_tag_filters = $this->_fenom->getTagFilters();
}
@ -175,8 +176,8 @@ class Template extends Render
*/
public function getParentScope($tag)
{
for($i = count($this->_stack) - 1; $i>=0; $i--) {
if($this->_stack[$i]->name == $tag) {
for ($i = count($this->_stack) - 1; $i >= 0; $i--) {
if ($this->_stack[$i]->name == $tag) {
return $this->_stack[$i];
}
}
@ -279,8 +280,8 @@ class Template extends Render
$this->_appendText($tag);
}
} else {
if($this->_tag_filters) {
foreach($this->_tag_filters as $filter) {
if ($this->_tag_filters) {
foreach ($this->_tag_filters as $filter) {
$_tag = call_user_func($filter, $_tag, $this);
}
}
@ -510,10 +511,10 @@ class Template extends Render
public function importBlocks($tpl)
{
$donor = $this->_fenom->compile($tpl, false);
foreach($donor->blocks as $name => $block) {
if(!isset($this->blocks[ $name ])) {
foreach ($donor->blocks as $name => $block) {
if (!isset($this->blocks[$name])) {
$block['import'] = $this->getName();
$this->blocks[ $name ] = $block;
$this->blocks[$name] = $block;
}
}
$this->addDepend($donor);
@ -526,13 +527,13 @@ class Template extends Render
*/
public function extend($tpl)
{
if(!$this->_body) {
if (!$this->_body) {
$this->compile();
}
$parent = $this->_fenom->getRawTemplate()->load($tpl, false);
$parent->blocks = &$this->blocks;
$parent->blocks = & $this->blocks;
$parent->extended = $this->getName();
if(!$this->ext_stack) {
if (!$this->ext_stack) {
$this->ext_stack[] = $this->getName();
}
$this->ext_stack[] = $parent->getName();
@ -540,7 +541,7 @@ class Template extends Render
$parent->ext_stack = $this->ext_stack;
$parent->compile();
$this->_body = $parent->_body;
$this->_src = $parent->_src;
$this->_src = $parent->_src;
$this->addDepend($parent);
return $parent;
}
@ -634,11 +635,11 @@ class Template extends Render
$name = $action . "." . $name;
}
return $this->parseMacroCall($tokens, $name);
} elseif($tokens->is(T_DOUBLE_COLON, T_NS_SEPARATOR)) { // static method call
} elseif ($tokens->is(T_DOUBLE_COLON, T_NS_SEPARATOR)) { // static method call
$tokens->back();
$p = $tokens->p;
$static = $this->parseStatic($tokens);
if($tokens->is("(")) {
if ($tokens->is("(")) {
return $this->out($this->parseExpr($tokens->seek($p)));
} else {
return $this->out(Compiler::smartFuncParser($static, $tokens, $this));
@ -678,7 +679,7 @@ class Template extends Render
if ($tags = $this->_fenom->getTagOwners($action)) { // unknown template tag
throw new TokenizeException("Unexpected tag '$action' (this tag can be used with '" . implode("', '", $tags) . "')");
} else {
throw new TokenizeException("Unexpected tag $action");
throw new TokenizeException("Unexpected tag '$action'");
}
}
@ -699,8 +700,8 @@ class Template extends Render
// parse term
$term = $this->parseTerm($tokens, $var); // term of the expression
if ($term !== false) {
if($this->_options & Fenom::FORCE_VERIFY) {
$term = '(isset('.$term.') ? '.$term.' : null)';
if ($this->_options & Fenom::FORCE_VERIFY) {
$term = '(isset(' . $term . ') ? ' . $term . ' : null)';
$var = false;
}
if ($tokens->is('|')) {
@ -806,13 +807,13 @@ class Template extends Render
throw new \LogicException("Forbidden to call methods");
}
do { // parse call-chunks: $var->func()->func()->prop->func()->...
if($tokens->is('(')) {
if ($tokens->is('(')) {
$code .= $this->parseArgs($tokens);
}
if($tokens->is(T_OBJECT_OPERATOR) && $tokens->isNext(T_STRING)) {
$code .= '->'.$tokens->next()->getAndNext();
if ($tokens->is(T_OBJECT_OPERATOR) && $tokens->isNext(T_STRING)) {
$code .= '->' . $tokens->next()->getAndNext();
}
} while($tokens->is('(', T_OBJECT_OPERATOR));
} while ($tokens->is('(', T_OBJECT_OPERATOR));
} elseif ($tokens->is(Tokenizer::MACRO_INCDEC)) {
$code .= $tokens->getAndNext();
} else {
@ -836,7 +837,7 @@ class Template extends Render
throw new \Exception("Function " . $tokens->getAndNext() . " not found");
}
$code = $unary . $func . $this->parseArgs($tokens->next());
} elseif($tokens->isNext(T_NS_SEPARATOR, T_DOUBLE_COLON)) {
} elseif ($tokens->isNext(T_NS_SEPARATOR, T_DOUBLE_COLON)) {
$method = $this->parseStatic($tokens);
$args = $this->parseArgs($tokens);
$code = $unary . $method . $args;
@ -874,8 +875,8 @@ class Template extends Render
*/
public function parseVariable(Tokenizer $tokens, $var = null)
{
if(!$var) {
$var = '$var["' . substr( $tokens->get(T_VARIABLE), 1) . '"]';
if (!$var) {
$var = '$var["' . substr($tokens->get(T_VARIABLE), 1) . '"]';
$tokens->next();
}
while ($t = $tokens->key()) {
@ -952,14 +953,14 @@ class Template extends Render
$tokens->need('.')->next();
$var = $this->parseName($tokens);
if (!defined($var)) {
$var = 'constant(' . var_export($var, true) . ')';
$var = '@constant(' . var_export($var, true) . ')';
}
break;
case 'version':
$var = '\Fenom::VERSION';
break;
default:
throw new UnexpectedTokenException($tokens);
throw new UnexpectedTokenException($tokens->back());
}
return $var;
@ -981,13 +982,13 @@ class Template extends Render
if ($tokens->is(":")) {
$tokens->next();
if ($empty) {
if($is_var) {
if ($is_var) {
return '(empty(' . $var . ') ? (' . $this->parseExpr($tokens) . ') : ' . $var . ')';
} else {
return '(' . $var . ' ?: (' . $this->parseExpr($tokens) . ')';
return '(' . $var . ' ?: (' . $this->parseExpr($tokens) . '))';
}
} else {
if($is_var) {
if ($is_var) {
return '(isset(' . $var . ') ? ' . $var . ' : (' . $this->parseExpr($tokens) . '))';
} else {
return '((' . $var . ' !== null) ? ' . $var . ' : (' . $this->parseExpr($tokens) . '))';
@ -995,13 +996,13 @@ class Template extends Render
}
} elseif ($tokens->is(Tokenizer::MACRO_BINARY, Tokenizer::MACRO_BOOLEAN, Tokenizer::MACRO_MATH) || !$tokens->valid()) {
if ($empty) {
if($is_var) {
if ($is_var) {
return '!empty(' . $var . ')';
} else {
return '(' . $var . ')';
}
} else {
if($is_var) {
if ($is_var) {
return 'isset(' . $var . ')';
} else {
return '(' . $var . ' !== null)';
@ -1012,13 +1013,13 @@ class Template extends Render
$tokens->need(':')->skip();
$expr2 = $this->parseExpr($tokens);
if ($empty) {
if($is_var) {
if ($is_var) {
return '(empty(' . $var . ') ? ' . $expr2 . ' : ' . $expr1 . ')';
} else {
return '(' . $var . ' ? ' . $expr1 . ' : ' . $expr2 . ')';
}
} else {
if($is_var) {
if ($is_var) {
return '(isset(' . $var . ') ? ' . $expr1 . ' : ' . $expr2 . ')';
} else {
return '((' . $var . ' !== null) ? ' . $expr1 . ' : ' . $expr2 . ')';
@ -1169,7 +1170,7 @@ class Template extends Render
break;
case '$':
$tokens->next()->need('.')->next()->need(T_CONST)->next();
return 'constant('.$this->parseName($tokens).')';
return @constant($this->parseName($tokens));
default:
throw new UnexpectedTokenException($tokens);
}
@ -1254,7 +1255,7 @@ class Template extends Render
{
while ($tokens->is("|")) {
$modifier = $tokens->getNext(Tokenizer::MACRO_STRING);
if($tokens->isNext(T_DOUBLE_COLON, T_NS_SEPARATOR)) {
if ($tokens->isNext(T_DOUBLE_COLON, T_NS_SEPARATOR)) {
$mods = $this->parseStatic($tokens);
} else {
$mods = $this->_fenom->getModifier($modifier, $this);
@ -1369,11 +1370,11 @@ class Template extends Render
}
if ($recursive) {
$recursive['recursive'] = true;
return '$tpl->getMacro("' . $name . '")->__invoke('.Compiler::toArray($args).', $tpl);';
return '$tpl->getMacro("' . $name . '")->__invoke(' . Compiler::toArray($args) . ', $tpl);';
} else {
$vars = $this->tmpVar();
return $vars . ' = $var; $var = ' . Compiler::toArray($args) . ';' . PHP_EOL . '?>' .
$macro["body"] . '<?php' . PHP_EOL . '$var = '.$vars.'; unset(' . $vars . ');';
return $vars . ' = $var; $var = ' . Compiler::toArray($args) . ';' . PHP_EOL . '?>' .
$macro["body"] . '<?php' . PHP_EOL . '$var = ' . $vars . '; unset(' . $vars . ');';
}
}
@ -1385,7 +1386,7 @@ class Template extends Render
*/
public function parseStatic(Tokenizer $tokens)
{
if($this->_options & Fenom::DENY_STATICS) {
if ($this->_options & Fenom::DENY_STATICS) {
throw new \LogicException("Static methods are disabled");
}
$tokens->skipIf(T_NS_SEPARATOR);
@ -1399,7 +1400,7 @@ class Template extends Render
}
$tokens->need(T_DOUBLE_COLON)->next()->need(T_STRING);
$static = $name . "::" . $tokens->getAndNext();
if(!is_callable($static)) {
if (!is_callable($static)) {
throw new \RuntimeException("Method $static doesn't exist");
}
return $static;

View File

@ -594,6 +594,8 @@ class Tokenizer
public function end()
{
$this->p = $this->_max;
unset($this->prev, $this->curr, $this->next);
return $this;
}
/**

View File

@ -1,5 +1,6 @@
<?php
namespace Fenom;
use Fenom, Fenom\Provider as FS;
class TestCase extends \PHPUnit_Framework_TestCase
@ -124,7 +125,7 @@ class TestCase extends \PHPUnit_Framework_TestCase
if ($dump) {
echo "\n========= DUMP BEGIN ===========\n" . $code . "\n--- to ---\n" . $tpl->getBody() . "\n========= DUMP END =============\n";
}
$this->assertSame(Modifier::strip($result), Modifier::strip($tpl->fetch($vars), true), "Test $code");
$this->assertSame(Modifier::strip($result, true), Modifier::strip($tpl->fetch($vars), true), "Test $code");
return $tpl;
}
@ -276,20 +277,24 @@ class TestCase extends \PHPUnit_Framework_TestCase
}
}
class Helper {
class Helper
{
public $word = 'helper';
public function __construct($word) {
public function __construct($word)
{
$this->word = $word;
$this->self = $this;
}
public function chunk() {
public function chunk()
{
return $this;
}
public function __toString() {
public function __toString()
{
return $this->word;
}
}

View File

@ -2,7 +2,7 @@
$loader = include(__DIR__ . "/../vendor/autoload.php");
/* @var Composer\Autoload\ClassLoader $loader */
$loader->add('Fenom', __DIR__.'/cases');
$loader->add('Fenom', __DIR__ . '/cases');
define('FENOM_RESOURCES', __DIR__ . "/resources");

View File

@ -1,157 +0,0 @@
<?php
namespace Fenom;
use Fenom, Fenom\TestCase;
class ExtendsTemplateTest_ extends TestCase
{
public function _testSandbox()
{
$this->fenom = Fenom::factory(FENOM_RESOURCES . '/provider', FENOM_RESOURCES . '/compile');
try {
print_r($this->fenom->getTemplate('use/child.tpl')->getBody());
} catch (\Exception $e) {
echo "$e";
}
exit;
}
/**
* Templates skeletons
* @param array $vars
* @return array
*/
public static function templates(array $vars)
{
return array(
array(
"name" => "level.0.tpl",
"level" => 0,
"blocks" => array(
"b1" => "default {\$default}",
"b2" => "empty 0"
),
"result" => array(
"b1" => "default " . $vars["default"],
"b2" => "empty 0"
),
),
array(
"name" => "level.1.tpl",
"level" => 1,
"use" => false,
"blocks" => array(
"b1" => "from level 1"
),
"result" => array(
"b1" => "from level 1",
"b2" => "empty 0"
),
),
array(
"name" => "level.2.tpl",
"level" => 2,
"use" => false,
"blocks" => array(
"b2" => "from level 2",
"b4" => "unused block"
),
"result" => array(
"b1" => "from level 1",
"b2" => "from level 2"
),
),
array(
"name" => "level.3.tpl",
"level" => 3,
"use" => false,
"blocks" => array(
"b1" => "from level 3",
"b2" => "also from level 3"
),
"result" => array(
"b1" => "from level 3",
"b2" => "also from level 3"
),
)
);
}
/**
* Generate templates by skeletons
*
* @param $block_mask
* @param $extend_mask
* @param array $skels
* @return array
*/
public static function generate($block_mask, $extend_mask, $skels)
{
$t = array();
foreach ($skels as $level => $tpl) {
$src = 'level#' . $level . ' ';
foreach ($tpl["blocks"] as $bname => &$bcode) {
$src .= sprintf($block_mask, $bname, $bname . ': ' . $bcode) . " level#$level ";
}
$dst = "level#0 ";
foreach ($tpl["result"] as $bname => &$bcode) {
$dst .= $bname . ': ' . $bcode . ' level#0 ';
}
if ($level) {
$src = sprintf($extend_mask, $level - 1) . ' ' . $src;
}
$t[$tpl["name"]] = array("src" => $src, "dst" => $dst);
}
return $t;
}
public function _testTemplateExtends()
{
$vars = array(
"b1" => "b1",
"b2" => "b2",
"b3" => "b3",
"b4" => "b4",
"level" => "level",
"default" => 5
);
$tpls = self::generate('{block "%s"}%s{/block}', '{extends "level.%d.tpl"}', self::templates($vars));
foreach ($tpls as $name => $tpl) {
$this->tpl($name, $tpl["src"]);
$this->assertSame($this->fenom->fetch($name, $vars), $tpl["dst"]);
}
return;
$vars["default"]++;
$this->fenom->flush();
$tpls = self::generate('{block "{$%s}"}%s{/block}', '{extends "level.%d.tpl"}', self::templates($vars));
arsort($tpls);
foreach ($tpls as $name => $tpl) {
$this->tpl("d." . $name, $tpl["src"]);
$this->assertSame($this->fenom->fetch("d." . $name, $vars), $tpl["dst"]);
}
$vars["default"]++;
$this->fenom->flush();
$tpls = self::generate('{block "%s"}%s{/block}', '{extends "$level.%d.tpl"}', self::templates($vars));
arsort($tpls);
foreach ($tpls as $name => $tpl) {
$this->tpl("x." . $name, $tpl["src"]);
$this->assertSame($this->fenom->fetch("x." . $name, $vars), $tpl["dst"]);
}
}
/**
* @group use
*/
public function testUse()
{
$this->fenom = Fenom::factory(FENOM_RESOURCES . '/provider', FENOM_RESOURCES . '/compile');
$this->assertSame("<html>\n block 1 blocks \n block 2 child \n</html>", $this->fenom->fetch('use/child.tpl'));
}
public function _testParent()
{
}
}

View File

@ -1,5 +1,6 @@
<?php
namespace Fenom;
use Fenom, Fenom\TestCase;
class ExtendsTest extends TestCase
@ -34,7 +35,8 @@ Content of the footer";
/**
* @group testAutoExtends
*/
public function testAutoExtends() {
public function testAutoExtends()
{
$result = "Before header
Child 2 header
Before body
@ -49,7 +51,8 @@ Footer from use";
), array()));
}
public function testStaticExtendLevel1() {
public function testStaticExtendLevel1()
{
$result = "Before header
Content of the header
Before body
@ -59,7 +62,8 @@ Content of the footer";
$this->assertSame($result, $this->fenom->fetch('extends/static/child.1.tpl', array()));
}
public function testStaticExtendLevel3() {
public function testStaticExtendLevel3()
{
$result = "Before header
Child 2 header
Before body
@ -69,7 +73,8 @@ Footer from use";
$this->assertSame($result, $this->fenom->fetch('extends/static/child.3.tpl', array()));
}
public function testAutoAndStaticExtend() {
public function testAutoAndStaticExtend()
{
$result = "Before header
Child 2 header
Before body
@ -83,7 +88,8 @@ Footer from use";
), array()));
}
public function testStaticExtendNested() {
public function testStaticExtendNested()
{
$result = "Before body
Before header
@ -94,7 +100,8 @@ Footer from use";
$this->assertSame($result, $this->fenom->fetch('extends/static/nested/child.1.tpl', array()));
}
public function testDynamicExtendLevel2() {
public function testDynamicExtendLevel2()
{
$result = "Before header
Child 2 header
Before body
@ -104,7 +111,8 @@ Footer from use";
$this->assertSame($result, $this->fenom->fetch('extends/dynamic/child.2.tpl', array()));
}
public function testDynamicExtendLevel3() {
public function testDynamicExtendLevel3()
{
$result = "Before header
Child 2 header
Before body
@ -114,7 +122,8 @@ Footer from use";
$this->assertSame($result, $this->fenom->fetch('extends/dynamic/child.3.tpl', array()));
}
public function testDynamicExtendLevel4() {
public function testDynamicExtendLevel4()
{
$result = "Before header
Child 2 header
Before body

View File

@ -65,8 +65,8 @@ class MacrosTest extends TestCase
// $this->fenom->compile("macro_recursive.tpl")->display([]);
// $this->fenom->flush();
// var_dump($this->fenom->fetch("macro_recursive.tpl", []));
var_dump( $this->fenom->compile("macro_recursive_import.tpl")->display(array()));
var_dump( $this->fenom->display("macro_recursive_import.tpl", array()));
var_dump($this->fenom->compile("macro_recursive_import.tpl")->display(array()));
var_dump($this->fenom->display("macro_recursive_import.tpl", array()));
} catch (\Exception $e) {
var_dump($e->getMessage() . ": " . $e->getTraceAsString());
}

View File

@ -1,5 +1,6 @@
<?php
namespace Fenom;
use Fenom;
use Fenom\TestCase;
@ -103,7 +104,8 @@ class ProviderTest extends TestCase
), $list);
}
public function testRm() {
public function testRm()
{
$this->assertTrue(is_dir(FENOM_RESOURCES . '/template/sub'));
Provider::rm(FENOM_RESOURCES . '/template/sub');
$this->assertFalse(is_dir(FENOM_RESOURCES . '/template/sub'));

View File

@ -1,5 +1,6 @@
<?php
namespace Fenom;
use Fenom,
Fenom\Render;

View File

@ -1,5 +1,6 @@
<?php
namespace Fenom;
use Fenom\Template,
Fenom,
Fenom\Render;
@ -74,8 +75,10 @@ class TemplateTest extends TestCase
array('hello, {$b.3[$b.c_char]}!', $c, 'hello, Username!'),
array('hello, {$b[3].c}!', $c, 'hello, Username!'),
array('hello, {$b[2+1].c}!', $c, 'hello, Username!'),
array('hello, {$b[(2+1)].c}!', $c, 'hello, Username!'),
array('hello, {$b[9/3].c}!', $c, 'hello, Username!'),
array('hello, {$b[3].$c}!', $c, 'hello, Username!'),
array('hello, {$b[(3)].$c}!', $c, 'hello, Username!'),
array('hello, {$b[3][$b.c_char]}!', $c, 'hello, Username!'),
array('hello, {$b[ "m{$b.c_char}p" ]} and {$b.3[$b.c_char]}!',
$c, 'hello, Master and Username!'),
@ -90,6 +93,7 @@ class TemplateTest extends TestCase
array('hello, {$b.obj->list.a|upper}!',
$c, 'hello, WORLD!'),
array('hello, {$b[ $b.obj->c ]}!', $b, 'hello, Username!'),
array('hello, {$b[ ( $b.obj->c ) ]}!', $b, 'hello, Username!'),
array('hello, {$b[ "{$b.obj->c}" ]}!',
$b, 'hello, Username!'),
array('hello, {"World"}!', $a, 'hello, World!'),
@ -222,6 +226,7 @@ class TemplateTest extends TestCase
array('If: {$a + (*6)} end', 'Fenom\Error\CompileException', "Unexpected token '*'"),
array('If: {$a + ( 6} end', 'Fenom\Error\CompileException', "Unexpected end of expression, expect ')'"),
array('If: {$a end', 'Fenom\Error\CompileException', "Unclosed tag in line"),
array('If: {!!$a}', 'Fenom\Error\CompileException', "Unexpected token '!'"),
);
}
@ -429,6 +434,8 @@ class TemplateTest extends TestCase
return array(
// ?
array('{if $a?} right {/if}', $a),
array('{if 1?} right {/if}', $a),
array('{if 0?} no way {else} right {/if}', $a),
array('{if $unexists?} no way {else} right {/if}', $a),
array('{if $empty.array?} no way {else} right {/if}', $a),
array('{if $empty.int?} no way {else} right {/if}', $a),
@ -450,11 +457,17 @@ class TemplateTest extends TestCase
array('{$empty.double?:"empty"}', $a, "empty"),
array('{$empty.bool?:"empty"}', $a, "empty"),
array('{$empty.unexist?:"empty"}', $a, "empty"),
array('{0?:"empty"}', $a, "empty"),
// ? ... : ....
array('{$unexists ? "no way" : "right"}', $a),
array('{0 ? "no way" : "right"}', $a),
array('{$a ? "right" : "no way"}', $a),
array('{1 ? "right" : "no way"}', $a),
// !
array('{if $a!} right {/if}', $a),
array('{if 1!} right {/if}', $a),
array('{if 0!} right {/if}', $a),
array('{if null!} no way {else} right {/if}', $a),
array('{if $unexists!} no way {else} right {/if}', $a),
array('{if $empty.array!} right {/if}', $a),
array('{if $empty.int!} right {/if}', $a),
@ -470,9 +483,11 @@ class TemplateTest extends TestCase
// ! ... : ...
array('{$unexists ! "no way" : "right"}', $a),
array('{$a ! "right" : "no way"}', $a),
array('{1 ! "right" : "no way"}', $a),
// !: ...
array('{$unexists !: "right"}', $a),
array('{$a !: "right"}', $a, '1'),
array('{1 !: "right"}', $a, '1'),
);
}
@ -646,6 +661,7 @@ class TemplateTest extends TestCase
return array(
array('Layers: {foreach $list as $e} block1 {if 1} {foreachelse} {/if} {/foreach} end', 'Fenom\Error\CompileException', "Unexpected tag 'foreachelse' (this tag can be used with 'foreach')"),
array('Layers: {foreach $list as $e} block1 {if 1} {/foreach} {/if} end', 'Fenom\Error\CompileException', "Unexpected closing of the tag 'foreach'"),
array('Layers: {blah} end', 'Fenom\Error\CompileException', "Unexpected tag 'blah'"),
array('Layers: {for $a=4 to=6} block1 {if 1} {forelse} {/if} {/for} end', 'Fenom\Error\CompileException', "Unexpected tag 'forelse' (this tag can be used with 'for')"),
array('Layers: {for $a=4 to=6} block1 {if 1} {/for} {/if} end', 'Fenom\Error\CompileException', "Unexpected closing of the tag 'for'"),
array('Layers: {switch 1} {if 1} {case 1} {/if} {/switch} end', 'Fenom\Error\CompileException', "Unexpected tag 'case' (this tag can be used with 'switch')"),
@ -679,6 +695,7 @@ class TemplateTest extends TestCase
array('{if $one is not 1} block1 {else} block2 {/if}', 'block2'),
array('{if $one is not 2} block1 {else} block2 {/if}', 'block1'),
array('{if $one is $one} block1 {else} block2 {/if}', 'block1'),
array('{if $bool is true} block1 {else} block2 {/if}', 'block1'),
array('{if $float is float} block1 {else} block2 {/if}', 'block1'),
array('{if $float is not float} block1 {else} block2 {/if}', 'block2'),
array('{if $obj is object} block1 {else} block2 {/if}', 'block1'),
@ -744,7 +761,19 @@ class TemplateTest extends TestCase
);
}
public static function providerConcat() {
public static function providerInOperatorInvalid()
{
return array(
array('{$one not all 3}', 'Fenom\Error\CompileException', "Unexpected token 'not'"),
array('{$one in all}', 'Fenom\Error\CompileException', "Unexpected token 'all'"),
array('{$one in string [1,2,3]}', 'Fenom\Error\CompileException', "Can not use string operation for array"),
array('{$one in list "blah"}', 'Fenom\Error\CompileException', "Can not use array operation for string"),
array('{$one in true}', 'Fenom\Error\CompileException', "Unexpected token 'true'"),
);
}
public static function providerConcat()
{
return array(
array('{"string" ~ $one ~ up("end")}', "string1END"),
array('{"string" ~ $one++ ~ "end"}', "string1end"),
@ -754,7 +783,8 @@ class TemplateTest extends TestCase
);
}
public static function providerAccessor() {
public static function providerAccessor()
{
return array(
array('{$.get.one}', 'get1'),
array('{$.post.one}', 'post1'),
@ -765,6 +795,7 @@ class TemplateTest extends TestCase
array('{$.cookie.one}', 'cookie1'),
array('{$.server.one}', 'server1'),
array('{$.const.PHP_EOL}', PHP_EOL),
array('{$.const.MY}', ''),
array('{$.version}', Fenom::VERSION),
array('{"string"|append:"_":$.get.one}', 'string_get1'),
@ -780,7 +811,16 @@ class TemplateTest extends TestCase
);
}
public function providerStatic() {
public static function providerAccessorInvalid()
{
return array(
array('{$.nope.one}', 'Fenom\Error\CompileException', "Unexpected token 'nope'"),
array('{$.get.one}', 'Fenom\Error\SecurityException', 'Accessor are disabled', Fenom::DENY_ACCESSOR),
);
}
public function providerStatic()
{
return array(
array('{Fenom\TemplateTest::multi x=3 y=4}', '12'),
array('{Fenom\TemplateTest::multi(3,4)}', '12'),
@ -789,7 +829,8 @@ class TemplateTest extends TestCase
);
}
public function providerStaticInvalid() {
public function providerStaticInvalid()
{
return array(
array('{Fenom\TemplateTest::multi x=3 y=4}', 'Fenom\Error\SecurityException', "Static methods are disabled", Fenom::DENY_STATICS),
array('{Fenom\TemplateTest::multi(3,4)}', 'Fenom\Error\SecurityException', "Static methods are disabled", Fenom::DENY_STATICS),
@ -809,14 +850,22 @@ class TemplateTest extends TestCase
var_dump($this->fenom->compileCode('{Fenom\TemplateTest::multi(3,4)}')->getBody());
} catch (\Exception $e) {
print_r($e->getMessage() . "\n" . $e->getTraceAsString());
while($e->getPrevious()) {
while ($e->getPrevious()) {
$e = $e->getPrevious();
print_r("\n\n".$e->getMessage() . "\n" . $e->getTraceAsString());
print_r("\n\n" . $e->getMessage() . "\n" . $e->getTraceAsString());
}
}
exit;
}
/**
* @dataProvider providerScalars
*/
public function testScalars($code, $result)
{
$this->exec("{" . $code . "}", $this->values, $result);
}
/**
* @dataProvider providerVars
*/
@ -1048,6 +1097,15 @@ class TemplateTest extends TestCase
$this->exec($code, self::getVars(), $result);
}
/**
* @group in_operator_invalid
* @dataProvider providerInOperatorInvalid
*/
public function testInOperatorInvalid($code, $exception, $message, $options = 0)
{
$this->execError($code, $exception, $message, $options);
}
/**
* @dataProvider providerConcat
*/
@ -1065,6 +1123,15 @@ class TemplateTest extends TestCase
$this->exec($code, self::getVars(), $result);
}
/**
* @group accessor
* @dataProvider providerAccessorInvalid
*/
public function testAccessorInvalid($code, $exception, $message, $options = 0)
{
$this->execError($code, $exception, $message, $options);
}
/**
* @group static
* @dataProvider providerStatic
@ -1074,7 +1141,8 @@ class TemplateTest extends TestCase
$this->exec($code, self::getVars(), $result, true);
}
public static function multi($x, $y = 42) {
public static function multi($x, $y = 42)
{
return $x * $y;
}

View File

@ -1,11 +1,20 @@
<?php
namespace Fenom;
use Fenom\Error\UnexpectedTokenException;
use Fenom\Tokenizer;
class TokenizerTest extends \PHPUnit_Framework_TestCase
{
public function testGetName()
{
$this->assertSame('T_DOUBLE_COLON', Tokenizer::getName(T_DOUBLE_COLON));
$this->assertSame('++', Tokenizer::getName('++'));
$this->assertSame('T_STRING', Tokenizer::getName(array(308, 'all', "", 1, "T_STRING")));
$this->assertNull(Tokenizer::getName(false));
}
public function testTokens()
{
$code = 'hello, please resolve this example: sin($x)+tan($x*$t) = {U|[0,1]}';
@ -66,6 +75,7 @@ class TokenizerTest extends \PHPUnit_Framework_TestCase
$this->assertSame($code, $tokens->getSnippetAsString(-100, 100));
$this->assertSame('+', $tokens->getSnippetAsString(100, -100));
$this->assertSame('sin($x)+tan($x*$t)', $tokens->getSnippetAsString(-4, 6));
$this->assertSame('}', $tokens->end()->current());
}
public function testSkip()

View File

@ -20,7 +20,8 @@ class FenomTest extends \Fenom\TestCase
);
}
public function testCreating() {
public function testCreating()
{
$time = $this->tpl('temp.tpl', 'Template 1 a');
$fenom = new Fenom($provider = new \Fenom\Provider(FENOM_RESOURCES . '/template'));
$fenom->setCompileDir(FENOM_RESOURCES . '/compile');
@ -32,7 +33,8 @@ class FenomTest extends \Fenom\TestCase
$fenom->clearAllCompiles();
}
public function testFactory() {
public function testFactory()
{
$time = $this->tpl('temp.tpl', 'Template 1 a');
$fenom = Fenom::factory($provider = new \Fenom\Provider(FENOM_RESOURCES . '/template'), FENOM_RESOURCES . '/compile', Fenom::AUTO_ESCAPE);
$this->assertInstanceOf('Fenom\Template', $tpl = $fenom->getTemplate('temp.tpl'));
@ -166,7 +168,8 @@ class FenomTest extends \Fenom\TestCase
/**
* @group tag-filter
*/
public function testTagFilter() {
public function testTagFilter()
{
$tags = array();
$punit = $this;
$this->fenom->addTagFilter(function ($text, $tpl) use (&$tags, $punit) {
@ -180,20 +183,23 @@ class FenomTest extends \Fenom\TestCase
$this->assertSame(array('var $a', '/var', '$b'), $tags);
}
public function testAddInlineCompilerSmart() {
$this->fenom->addCompilerSmart('SayA','TestTags');
public function testAddInlineCompilerSmart()
{
$this->fenom->addCompilerSmart('SayA', 'TestTags');
$this->tpl('inline_compiler.tpl', 'I just {SayA}.');
$this->assertSame('I just Say A.', $this->fenom->fetch('inline_compiler.tpl', array()));
}
public function testAddBlockCompilerSmart() {
public function testAddBlockCompilerSmart()
{
$this->fenom->addBlockCompilerSmart('SayBlock', 'TestTags', array('SaySomething'), array('SaySomething'));
$this->tpl('block_compiler.tpl', '{SayBlock} and {SaySomething}. It is all, {/SayBlock}');
$this->assertSame('Start saying and say blah-blah-blah. It is all, Stop saying',
$this->fenom->fetch('block_compiler.tpl', array()));
}
public function testAddFunctions() {
public function testAddFunctions()
{
$this->fenom->setOptions(Fenom::DENY_NATIVE_FUNCS);
$this->assertFalse($this->fenom->isAllowedFunction('substr'));
$this->fenom->addAllowedFunctions(array('substr'));
@ -202,22 +208,26 @@ class FenomTest extends \Fenom\TestCase
}
class TestTags
{
class TestTags {
public static function tagSayA() {
public static function tagSayA()
{
return 'echo "Say A"';
}
public static function SayBlockOpen() {
public static function SayBlockOpen()
{
return 'echo "Start saying"';
}
public static function tagSaySomething() {
public static function tagSaySomething()
{
return 'echo "say blah-blah-blah"';
}
public static function SayBlockClose() {
public static function SayBlockClose()
{
return 'echo "Stop saying"';
}
}

View File

@ -1,3 +1,2 @@
{use 'extends/auto/use.tpl'}
{block 'header'}Child 2 header{/block}