diff --git a/docs/tags/switch.md b/docs/tags/switch.md index 1a19599..189fb62 100644 --- a/docs/tags/switch.md +++ b/docs/tags/switch.md @@ -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} diff --git a/src/Fenom.php b/src/Fenom.php index 7fb7090..0d69369 100644 --- a/src/Fenom.php +++ b/src/Fenom.php @@ -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); } } diff --git a/src/Fenom/Compiler.php b/src/Fenom/Compiler.php index 152b901..08fce9e 100644 --- a/src/Fenom/Compiler.php +++ b/src/Fenom/Compiler.php @@ -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() . '' . $inc->getBody() . '' . $inc->getBody() . '' . $inc->getBody() . '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$default$defaultparsePlainArg($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 = 'getStorage()->display(array('.implode(', ', $stack).'), $var); ?>'; + $body = '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']; } diff --git a/src/Fenom/Error/UnexpectedTokenException.php b/src/Fenom/Error/UnexpectedTokenException.php index 3087148..a31557b 100644 --- a/src/Fenom/Error/UnexpectedTokenException.php +++ b/src/Fenom/Error/UnexpectedTokenException.php @@ -9,6 +9,7 @@ */ namespace Fenom\Error; + use Fenom\Tokenizer; /** diff --git a/src/Fenom/Render.php b/src/Fenom/Render.php index fbc3776..68062ba 100644 --- a/src/Fenom/Render.php +++ b/src/Fenom/Render.php @@ -8,6 +8,7 @@ * file that was distributed with this source code. */ namespace Fenom; + use Fenom; /** diff --git a/src/Fenom/Template.php b/src/Fenom/Template.php index 163ec9d..2444481 100644 --- a/src/Fenom/Template.php +++ b/src/Fenom/Template.php @@ -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"] . '' . + $macro["body"] . '_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; diff --git a/src/Fenom/Tokenizer.php b/src/Fenom/Tokenizer.php index a699369..29bdb10 100644 --- a/src/Fenom/Tokenizer.php +++ b/src/Fenom/Tokenizer.php @@ -594,6 +594,8 @@ class Tokenizer public function end() { $this->p = $this->_max; + unset($this->prev, $this->curr, $this->next); + return $this; } /** diff --git a/tests/TestCase.php b/tests/TestCase.php index 3adcbfe..bb2fa11 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -1,5 +1,6 @@ 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; } } diff --git a/tests/autoload.php b/tests/autoload.php index 710169b..3a14596 100644 --- a/tests/autoload.php +++ b/tests/autoload.php @@ -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"); diff --git a/tests/cases/Fenom/ExtendsTemplateTest.php b/tests/cases/Fenom/ExtendsTemplateTest.php deleted file mode 100644 index 7decd15..0000000 --- a/tests/cases/Fenom/ExtendsTemplateTest.php +++ /dev/null @@ -1,157 +0,0 @@ -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("\n block 1 blocks \n block 2 child \n", $this->fenom->fetch('use/child.tpl')); - } - - public function _testParent() - { - - } -} - diff --git a/tests/cases/Fenom/ExtendsTest.php b/tests/cases/Fenom/ExtendsTest.php index 0a27ec1..1b1a950 100644 --- a/tests/cases/Fenom/ExtendsTest.php +++ b/tests/cases/Fenom/ExtendsTest.php @@ -1,5 +1,6 @@ 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 diff --git a/tests/cases/Fenom/MacrosTest.php b/tests/cases/Fenom/MacrosTest.php index e777dd0..6994a9c 100644 --- a/tests/cases/Fenom/MacrosTest.php +++ b/tests/cases/Fenom/MacrosTest.php @@ -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()); } diff --git a/tests/cases/Fenom/ProviderTest.php b/tests/cases/Fenom/ProviderTest.php index 3d684c5..6974eb5 100644 --- a/tests/cases/Fenom/ProviderTest.php +++ b/tests/cases/Fenom/ProviderTest.php @@ -1,5 +1,6 @@ assertTrue(is_dir(FENOM_RESOURCES . '/template/sub')); Provider::rm(FENOM_RESOURCES . '/template/sub'); $this->assertFalse(is_dir(FENOM_RESOURCES . '/template/sub')); diff --git a/tests/cases/Fenom/RenderTest.php b/tests/cases/Fenom/RenderTest.php index c71565b..fdcd07a 100644 --- a/tests/cases/Fenom/RenderTest.php +++ b/tests/cases/Fenom/RenderTest.php @@ -1,5 +1,6 @@ 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; } diff --git a/tests/cases/Fenom/TokenizerTest.php b/tests/cases/Fenom/TokenizerTest.php index 6bb3dc6..49c6d1f 100644 --- a/tests/cases/Fenom/TokenizerTest.php +++ b/tests/cases/Fenom/TokenizerTest.php @@ -1,11 +1,20 @@ 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() diff --git a/tests/cases/FenomTest.php b/tests/cases/FenomTest.php index 2fc7836..1678ecd 100644 --- a/tests/cases/FenomTest.php +++ b/tests/cases/FenomTest.php @@ -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"'; } } diff --git a/tests/resources/provider/extends/auto/child.2.tpl b/tests/resources/provider/extends/auto/child.2.tpl index 4ecd770..019a292 100644 --- a/tests/resources/provider/extends/auto/child.2.tpl +++ b/tests/resources/provider/extends/auto/child.2.tpl @@ -1,3 +1,2 @@ - {use 'extends/auto/use.tpl'} {block 'header'}Child 2 header{/block}