Merge branch 'origin/develop'

This commit is contained in:
Ivan Shalganov 2013-09-15 16:41:37 +04:00
commit 847e594aa6
10 changed files with 96 additions and 71 deletions

View File

@ -17,7 +17,7 @@ use Fenom\Template;
*/
class Fenom
{
const VERSION = '1.3';
const VERSION = '1.4';
/* Actions */
const INLINE_COMPILER = 1;
@ -246,10 +246,6 @@ class Fenom
'type' => self::BLOCK_COMPILER,
'open' => 'Fenom\Compiler::autoescapeOpen',
'close' => 'Fenom\Compiler::autoescapeClose'
),
'unset' => array(
'type' => self::INLINE_COMPILER,
'parser' => 'Fenom\Compiler::tagUnset'
)
);
@ -434,18 +430,18 @@ class Fenom
"float_tags" => array()
);
if (method_exists($storage, $compiler . "Open")) {
$c["open"] = $compiler . "Open";
$c["open"] = array($storage, $compiler . "Open");
} else {
throw new \LogicException("Open compiler {$compiler}Open not found");
}
if (method_exists($storage, $compiler . "Close")) {
$c["close"] = $compiler . "Close";
$c["close"] = array($storage, $compiler . "Close");
} else {
throw new \LogicException("Close compiler {$compiler}Close not found");
}
foreach ($tags as $tag) {
if (method_exists($storage, "tag" . $tag)) {
$c["tags"][$tag] = "tag" . $tag;
$c["tags"][$tag] = array($storage, "tag" . $tag);
if ($floats && in_array($tag, $floats)) {
$c['float_tags'][$tag] = 1;
}
@ -544,17 +540,6 @@ class Fenom
return false;
}
/**
* @param string $function
* @param Fenom\Template $template
* @return bool|string
* @deprecated
*/
public function getFunction($function, Template $template = null)
{
return $this->getTag($function, $template);
}
/**
* Returns tag info
*
@ -771,7 +756,6 @@ class Fenom
$fenom = $this; // used in template
$_tpl = include($this->_compile_dir . "/" . $file_name);
/* @var Fenom\Render $_tpl */
// var_dump($tpl, $_tpl->isValid()); exit;
if (!($this->_options & self::AUTO_RELOAD) || ($this->_options & self::AUTO_RELOAD) && $_tpl->isValid()) {
return $_tpl;
}

View File

@ -1034,4 +1034,5 @@ class Compiler
{
$scope->tpl->escape = $scope["escape"];
}
}

View File

@ -25,10 +25,6 @@ class UnexpectedTokenException extends \RuntimeException
}
if (!$tokens->curr) {
$this->message = "Unexpected end of " . ($where ? : "expression") . "$expect";
} elseif ($tokens->curr[0] === T_WHITESPACE) {
$this->message = "Unexpected whitespace$expect";
} elseif ($tokens->curr[0] === T_BAD_CHARACTER) {
$this->message = "Unexpected bad characters (below ASCII 32 except \\t, \\n and \\r) in " . ($where ? : "expression") . "$expect";
} else {
$this->message = "Unexpected token '" . $tokens->current() . "' in " . ($where ? : "expression") . "$expect";
}

View File

@ -85,6 +85,7 @@ class Render extends \ArrayObject
$this->_fenom = $fenom;
$props += self::$_props;
$this->_name = $props["name"];
$this->_base_name = $props["base_name"];
$this->_scm = $props["scm"];
$this->_time = $props["time"];
$this->_depends = $props["depends"];

View File

@ -163,7 +163,7 @@ class Template extends Render
{
$this->_name = $name;
$this->_crc = crc32($this->_name);
if ($provider = strstr($name, ":", true)) {
if ($provider = strstr($name, ':', true)) {
$this->_scm = $provider;
$this->_base_name = substr($name, strlen($provider) + 1);
} else {

View File

@ -114,6 +114,7 @@ class TestCase extends \PHPUnit_Framework_TestCase
* @param string $result expected result.
* @param int $options
* @param bool $dump dump source and result code (for debug)
* @return \Fenom\Template
*/
public function exec($code, $vars, $result, $options = 0, $dump = false)
{
@ -123,6 +124,7 @@ class TestCase extends \PHPUnit_Framework_TestCase
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");
return $tpl;
}
public function execTpl($name, $code, $vars, $result, $dump = false)
@ -162,9 +164,10 @@ class TestCase extends \PHPUnit_Framework_TestCase
{
$template = $this->fenom->compileCode($tpl);
if ($debug) {
print_r("$tpl:\n" . $template->getBody());
print_r("\nDEBUG $tpl:\n" . $template->getBody());
}
$this->assertSame($result, $template->fetch($this->values));
return $template;
}
@ -271,37 +274,3 @@ class TestCase extends \PHPUnit_Framework_TestCase
);
}
}
class Fake implements \ArrayAccess
{
public $vars;
public function offsetExists($offset)
{
return true;
}
public function offsetGet($offset)
{
if ($offset == "object") {
return new self();
} else {
return new self($offset);
}
}
public function offsetSet($offset, $value)
{
$this->vars[$offset] = $value;
}
public function offsetUnset($offset)
{
unset($this->vars[$offset]);
}
public function proxy()
{
return implode(", ", func_get_args());
}
}

View File

@ -14,6 +14,8 @@ class CustomProviderTest extends TestCase
public function testCustom()
{
$this->assertTrue($this->fenom->templateExists('my:include.tpl'));
$this->assertFalse($this->fenom->templateExists('my:include-none.tpl'));
$this->assertRender("start: {include 'my:include.tpl'}", 'start: include template');
//$this->assertRender("start: {import 'my:macros.tpl' as ops} {ops.add a=3 b=6}");
}

View File

@ -209,6 +209,7 @@ class TemplateTest extends TestCase
array('If: {$a != 5 => 4} end', 'Fenom\Error\CompileException', "Unexpected token '=>'"),
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"),
);
}
@ -266,7 +267,7 @@ class TemplateTest extends TestCase
"username" => "Master",
"email" => "dev@null.net"
);
$result = 'Include <b>Welcome, Master (dev@null.net)</b> template';
$result = 'Include <b>Welcome, Master (dev@null.net)</b> template';
return array(
array('Include {insert "welcome.tpl"} template', $a, $result),
array("Include {insert 'welcome.tpl'} template", $a, $result),
@ -684,6 +685,7 @@ class TemplateTest extends TestCase
array('{if null is set} block1 {else} block2 {/if}', 'block2'),
array('{if 0 is empty} block1 {else} block2 {/if}', 'block1'),
array('{if "" is empty} block1 {else} block2 {/if}', 'block1'),
array('{if [] is empty} block1 {else} block2 {/if}', 'block1'),
array('{if "data" is empty} block1 {else} block2 {/if}', 'block2'),
array('{if time() is not empty} block1 {else} block2 {/if}', 'block1'),
// is empty
@ -700,8 +702,10 @@ class TemplateTest extends TestCase
// event, odd
array('{if $one is odd} block1 {else} block2 {/if}', 'block1'),
array('{if $one is even} block1 {else} block2 {/if}', 'block2'),
array('{if ($one + 1) is even} block1 {else} block2 {/if}', 'block1'),
array('{if $two is even} block1 {else} block2 {/if}', 'block1'),
array('{if $two is odd} block1 {else} block2 {/if}', 'block2'),
array('{if ($two+1) is odd} block1 {else} block2 {/if}', 'block1'),
// template
array('{if "welcome.tpl" is template} block1 {else} block2 {/if}', 'block1'),
array('{if "welcome2.tpl" is template} block1 {else} block2 {/if}', 'block2'),
@ -754,13 +758,19 @@ class TemplateTest extends TestCase
array('{$.get.one?}', '1'),
array('{$.get.one is set}', '1'),
array('{$.get.two is empty}', '1'),
array('{$.version}', Fenom::VERSION),
array('{$.tpl?}', '1'),
array('{$.tpl.name}', 'runtime.tpl'),
array('{$.tpl.time}', '0'),
array('{$.tpl.schema}', ''),
);
}
public function _testSandbox()
{
try {
var_dump($this->fenom->setOptions(Fenom::FORCE_VERIFY)->compileCode('{if $unexist} block1 {else} block2 {/if}')->getBody());
var_dump($this->fenom->setOptions(Fenom::FORCE_VERIFY)->addFilter(function ($txt) {return $txt;})->compileCode('- <?php {$a} ?> -')->fetch(['a' => 1]));
} catch (\Exception $e) {
print_r($e->getMessage() . "\n" . $e->getTraceAsString());
}
@ -839,7 +849,11 @@ class TemplateTest extends TestCase
*/
public function testInsert($code, $vars, $result)
{
$this->exec($code, $vars, $result);
$this->values = $vars;
$this->tpl("insert.tpl", $code);
$tpl = $this->fenom->getTemplate('insert.tpl');
$this->assertSame($result, $tpl->fetch($vars));
$this->assertTrue($tpl->isValid());
}
/**

View File

@ -1,5 +1,6 @@
<?php
namespace Fenom;
use Fenom\Error\UnexpectedTokenException;
use Fenom\Tokenizer;
class TokenizerTest extends \PHPUnit_Framework_TestCase
@ -46,6 +47,7 @@ class TokenizerTest extends \PHPUnit_Framework_TestCase
$this->assertSame("sin", $tokens->getNext($tokens::MACRO_STRING));
$this->assertSame("sin", $tokens->current());
$this->assertTrue($tokens->isPrev(":"));
$this->assertSame(T_STRING, $tokens->key());
$this->assertTrue($tokens->is(T_STRING));
$this->assertTrue($tokens->is($tokens::MACRO_STRING));
@ -58,8 +60,9 @@ class TokenizerTest extends \PHPUnit_Framework_TestCase
$tokens->next();
$this->assertSame("+", $tokens->getNext($tokens::MACRO_BINARY));
$this->assertSame('sin($x)+tan($x*$t)', $tokens->getSnippetAsString(-4, 6));
$this->assertSame($code, $tokens->getSnippetAsString(-100, 100));
$this->assertSame('+', $tokens->getSnippetAsString(100, -100));
$this->assertSame('sin($x)+tan($x*$t)', $tokens->getSnippetAsString(-4, 6));
}
public function testSkip()

View File

@ -21,13 +21,26 @@ class FenomTest extends \Fenom\TestCase
}
public function testCreating() {
$time = $this->tpl('template1.tpl', 'Template 1 a');
Fenom::factory(FENOM_RESOURCES . '/template', FENOM_RESOURCES . '/compile');
$fenom = new Fenom($provider =new \Fenom\Provider(FENOM_RESOURCES . '/template'), FENOM_RESOURCES . '/compile', Fenom::AUTO_ESCAPE);
$this->assertInstanceOf('Fenom\Template', $tpl = $fenom->getTemplate('template1.tpl'));
$time = $this->tpl('temp.tpl', 'Template 1 a');
$fenom = new Fenom($provider = new \Fenom\Provider(FENOM_RESOURCES . '/template'));
$fenom->setCompileDir(FENOM_RESOURCES . '/compile');
$this->assertInstanceOf('Fenom\Template', $tpl = $fenom->getTemplate('temp.tpl'));
$this->assertSame($provider, $tpl->getProvider());
$this->assertSame('template1.tpl', $tpl->getBaseName());
$this->assertSame('temp.tpl', $tpl->getBaseName());
$this->assertSame('temp.tpl', $tpl->getName());
$this->assertSame($time, $tpl->getTime());
$fenom->clearAllCompiles();
}
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'));
$this->assertSame($provider, $tpl->getProvider());
$this->assertSame('temp.tpl', $tpl->getBaseName());
$this->assertSame('temp.tpl', $tpl->getName());
$this->assertSame($time, $tpl->getTime());
$fenom->clearAllCompiles();
}
public function testCompileFile()
@ -146,6 +159,48 @@ class FenomTest extends \Fenom\TestCase
return "|--- $text ---|";
});
$this->assertSame('+++ |--- == hello ---||--- world == ---| +++', $this->fenom->compileCode('hello {var $user} god {/var} world')->fetch(array()));
$this->assertSame('+++ |--- == hello ---||--- world == ---| +++', $this->fenom->compileCode('hello {var $user} misterio {/var} world')->fetch(array()));
$this->assertSame('+++ |--- == hello ---||--- world == ---| +++', $this->fenom->compileCode('hello {var $user} <?php misterio ?> {/var} world')->fetch(array()));
}
}
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() {
$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() {
$this->fenom->setOptions(Fenom::DENY_NATIVE_FUNCS);
$this->assertFalse($this->fenom->isAllowedFunction('substr'));
$this->fenom->addAllowedFunctions(array('substr'));
$this->assertTrue($this->fenom->isAllowedFunction('substr'));
}
}
class TestTags {
public static function tagSayA() {
return 'echo "Say A"';
}
public static function SayBlockOpen() {
return 'echo "Start saying"';
}
public static function tagSaySomething() {
return 'echo "say blah-blah-blah"';
}
public static function SayBlockClose() {
return 'echo "Stop saying"';
}
}