add more test and fix a wrong test, also comment some not-used-at-all codes.

If need some of thease code back, create a test case for them.
This commit is contained in:
fzerorubigd 2014-07-04 21:50:30 +04:30
parent a68318f4c5
commit 0a35a913c2
No known key found for this signature in database
GPG Key ID: D6EE858AF9D2999A
3 changed files with 122 additions and 62 deletions

View File

@ -160,46 +160,8 @@ class Template
$buffer = rtrim($buffer); $buffer = rtrim($buffer);
} }
$tmp = ''; $tmp = $this->_renderInternal($current, $context);
switch ($current[Tokenizer::TYPE]) {
case Tokenizer::T_END_SECTION:
break; // Its here just for handling whitespace trim.
case Tokenizer::T_SECTION :
$newStack = isset($current[Tokenizer::NODES])
? $current[Tokenizer::NODES] : array();
array_push($this->_stack, array(0, $newStack, false));
$tmp = $this->_section($context, $current);
array_pop($this->_stack);
break;
case Tokenizer::T_INVERTED :
$newStack = isset($current[Tokenizer::NODES]) ?
$current[Tokenizer::NODES] : array();
array_push($this->_stack, array(0, $newStack, false));
$tmp = $this->_inverted($context, $current);
array_pop($this->_stack);
break;
case Tokenizer::T_COMMENT :
$tmp = '';
break;
case Tokenizer::T_PARTIAL:
case Tokenizer::T_PARTIAL_2:
$tmp = $this->_partial($context, $current);
break;
case Tokenizer::T_UNESCAPED:
case Tokenizer::T_UNESCAPED_2:
$tmp = $this->_get($context, $current, false);
break;
case Tokenizer::T_ESCAPED:
$tmp = $this->_get($context, $current, true);
break;
case Tokenizer::T_TEXT:
$tmp = $current[Tokenizer::VALUE];
break;
default:
throw new \RuntimeException(
'Invalid node type : ' . json_encode($current)
);
}
if ($rTrim) { if ($rTrim) {
$tmp = ltrim($tmp); $tmp = ltrim($tmp);
} }
@ -222,6 +184,63 @@ class Template
return $buffer; return $buffer;
} }
/**
* Render tokens base on type of tokens
*
* @param array $current current token
* @param mixed $context current context
*
* @return string
*/
protected function _renderInternal($current, $context)
{
$result = '';
switch ($current[Tokenizer::TYPE]) {
case Tokenizer::T_END_SECTION:
break; // Its here just for handling whitespace trim.
case Tokenizer::T_SECTION :
$newStack = isset($current[Tokenizer::NODES])
? $current[Tokenizer::NODES] : array();
array_push($this->_stack, array(0, $newStack, false));
$result = $this->_section($context, $current);
array_pop($this->_stack);
break;
case Tokenizer::T_INVERTED :
$newStack = isset($current[Tokenizer::NODES]) ?
$current[Tokenizer::NODES] : array();
array_push($this->_stack, array(0, $newStack, false));
$result = $this->_inverted($context, $current);
array_pop($this->_stack);
break;
case Tokenizer::T_COMMENT :
$result = '';
break;
case Tokenizer::T_PARTIAL:
case Tokenizer::T_PARTIAL_2:
$result = $this->_partial($context, $current);
break;
case Tokenizer::T_UNESCAPED:
case Tokenizer::T_UNESCAPED_2:
$result = $this->_get($context, $current, false);
break;
case Tokenizer::T_ESCAPED:
$result = $this->_get($context, $current, true);
break;
case Tokenizer::T_TEXT:
$result = $current[Tokenizer::VALUE];
break;
/* How we could have another type of token? this part of code
is not used at all.
default:
throw new \RuntimeException(
'Invalid node type : ' . json_encode($current)
);
*/
}
return $result;
}
/** /**
* Discard top tree * Discard top tree
* *

View File

@ -115,23 +115,24 @@ class Tokenizer
* Scan and tokenize template source. * Scan and tokenize template source.
* *
* @param string $text Mustache template source to tokenize * @param string $text Mustache template source to tokenize
* @param string $delimiters Optional, pass opening and closing delimiters * @internal string $delimiters Optional, pass opening and closing delimiters
* *
* @return array Set of Mustache tokens * @return array Set of Mustache tokens
*/ */
public function scan($text, $delimiters = null) public function scan($text/*, $delimiters = null*/)
{ {
if ($text instanceof String) { if ($text instanceof String) {
$text = $text->getString(); $text = $text->getString();
} }
$this->reset(); $this->reset();
/* Actually we not support this. so this code is not used at all, yet.
if ($delimiters = trim($delimiters)) { if ($delimiters = trim($delimiters)) {
list($otag, $ctag) = explode(' ', $delimiters); list($otag, $ctag) = explode(' ', $delimiters);
$this->otag = $otag; $this->otag = $otag;
$this->ctag = $ctag; $this->ctag = $ctag;
} }
*/
$len = strlen($text); $len = strlen($text);
for ($i = 0; $i < $len; $i++) { for ($i = 0; $i < $len; $i++) {
@ -148,14 +149,14 @@ class Tokenizer
switch ($this->state) { switch ($this->state) {
case self::IN_TEXT: case self::IN_TEXT:
if ($this->tagChange(self::T_UNESCAPED.$this->otag, $text, $i) and $this->escaped) { if ($this->tagChange($this->otag. self::T_TRIM, $text, $i) and !$this->escaped) {
$this->buffer .= "{{{";
$i += 2;
continue;
} elseif ($this->tagChange($this->otag. self::T_TRIM, $text, $i) and !$this->escaped) {
$this->flushBuffer(); $this->flushBuffer();
$this->state = self::IN_TAG_TYPE; $this->state = self::IN_TAG_TYPE;
$this->trimLeft = true; $this->trimLeft = true;
} elseif ($this->tagChange(self::T_UNESCAPED.$this->otag, $text, $i) and $this->escaped) {
$this->buffer .= "{{{";
$i += 2;
continue;
} elseif ($this->tagChange($this->otag, $text, $i) and !$this->escaped) { } elseif ($this->tagChange($this->otag, $text, $i) and !$this->escaped) {
$i--; $i--;
$this->flushBuffer(); $this->flushBuffer();
@ -238,7 +239,7 @@ class Tokenizer
if ($this->tagType == self::T_UNESCAPED) { if ($this->tagType == self::T_UNESCAPED) {
if ($this->ctag == '}}') { if ($this->ctag == '}}') {
$i++; $i++;
} else { } /* else { // I can't remember why this part is here! the ctag is always }} and
// Clean up `{{{ tripleStache }}}` style tokens. // Clean up `{{{ tripleStache }}}` style tokens.
$lastIndex = count($this->tokens) - 1; $lastIndex = count($this->tokens) - 1;
$lastName = $this->tokens[$lastIndex][self::NAME]; $lastName = $this->tokens[$lastIndex][self::NAME];
@ -247,7 +248,7 @@ class Tokenizer
substr($lastName, 0, -1) substr($lastName, 0, -1)
); );
} }
} } */
} }
} else { } else {
$this->buffer .= $text[$i]; $this->buffer .= $text[$i];

View File

@ -160,7 +160,6 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
); );
} }
/** /**
* Test helpers (internal helpers) * Test helpers (internal helpers)
* *
@ -284,7 +283,7 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
array(), array(),
'fail' 'fail'
), ),
array ( array(
' {{~#if 1}}OK {{~else~}} NO {{~/if~}} END', ' {{~#if 1}}OK {{~else~}} NO {{~/if~}} END',
array(), array(),
'OKEND' 'OKEND'
@ -309,6 +308,11 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
array('data' => array('key' => 'result')), array('data' => array('key' => 'result')),
'result' 'result'
), ),
array(
'{{= (( )) =}}((#if 1))OK((else))NO((/if))',
array(),
'OK'
)
); );
} }
@ -366,12 +370,43 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
}); });
$this->assertEquals('<strong>Test</strong>', $engine->render('{{safeStringTest}}', array())); $this->assertEquals('<strong>Test</strong>', $engine->render('{{safeStringTest}}', array()));
$engine->addHelper('argsTest', function($template, $context, $arg) { $engine->addHelper('argsTest', function ($template, $context, $arg) {
$parsed_args = $template->parseArguments($arg); $parsedArgs = $template->parseArguments($arg);
return implode(' ', $parsed_args); return implode(' ', $parsedArgs);
}); });
$this->assertEquals("a \"b\" c", $engine->render('{{{argsTest "a" "\"b\"" \'c\'}}}', array())); $this->assertEquals("a \"b\" c", $engine->render('{{{argsTest "a" "\"b\"" \'c\'}}}', array()));
// This is just a fun thing to do :)
$that = $this;
$engine->addHelper('stopToken',
function ($template, $context, $arg) use ($that) {
/** @var $template \Handlebars\Template */
$parsedArgs = $template->parseArguments($arg);
$first = array_shift($parsedArgs);
$last = array_shift($parsedArgs);
if ($last == 'yes') {
$template->setStopToken($first);
$that->assertEquals($first, $template->getStopToken());
$buffer = $template->render($context);
$template->setStopToken(false);
$template->discard($context);
} else {
$template->setStopToken($first);
$that->assertEquals($first, $template->getStopToken());
$template->discard($context);
$template->setStopToken(false);
$buffer = $template->render($context);
}
return $buffer;
});
$this->assertEquals("Used", $engine->render('{{# stopToken fun no}}Not used{{ fun }}Used{{/stopToken }}', array()));
$this->assertEquals("Not used", $engine->render('{{# stopToken any yes}}Not used{{ any }}Used{{/stopToken }}', array()));
$this->setExpectedException('InvalidArgumentException');
$engine->getHelpers()->call('invalid', $engine->loadTemplate(''), new \Handlebars\Context(), '', '');
} }
public function testInvalidHelperMustacheStyle() public function testInvalidHelperMustacheStyle()
@ -400,6 +435,7 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('yes', $engine->render('{{#x}}yes{{/x}}', array('x' => true))); $this->assertEquals('yes', $engine->render('{{#x}}yes{{/x}}', array('x' => true)));
$this->assertEquals('', $engine->render('{{#x}}yes{{/x}}', array('x' => false))); $this->assertEquals('', $engine->render('{{#x}}yes{{/x}}', array('x' => false)));
$this->assertEquals('yes', $engine->render('{{^x}}yes{{/x}}', array('x' => false))); $this->assertEquals('yes', $engine->render('{{^x}}yes{{/x}}', array('x' => false)));
$this->assertEquals('', $engine->render('{{^x}}yes{{/x}}', array('x' => true)));
$this->assertEquals('1234', $engine->render('{{#x}}{{this}}{{/x}}', array('x' => array(1, 2, 3, 4)))); $this->assertEquals('1234', $engine->render('{{#x}}{{this}}{{/x}}', array('x' => array(1, 2, 3, 4))));
$this->assertEquals('012', $engine->render('{{#x}}{{@index}}{{/x}}', array('x' => array('a', 'b', 'c')))); $this->assertEquals('012', $engine->render('{{#x}}{{@index}}{{/x}}', array('x' => array('a', 'b', 'c'))));
$this->assertEquals('abc', $engine->render('{{#x}}{{@key}}{{/x}}', array('x' => array('a' => 1, 'b' => 2, 'c' => 3)))); $this->assertEquals('abc', $engine->render('{{#x}}{{@key}}{{/x}}', array('x' => array('a' => 1, 'b' => 2, 'c' => 3))));
@ -649,10 +685,8 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
$obj = new DateTime(); $obj = new DateTime();
$time = $obj->getTimestamp(); $time = $obj->getTimestamp();
$this->assertEquals($time, $engine->render('{{time.getTimestamp}}', array('time' => $obj))); $this->assertEquals($time, $engine->render('{{time.getTimestamp}}', array('time' => $obj)));
} }
public function testContext() public function testContext()
{ {
$test = new stdClass(); $test = new stdClass();
@ -760,7 +794,6 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
return (string)$a; return (string)$a;
}, $args); }, $args);
$this->assertEquals($args, $expected_array); $this->assertEquals($args, $expected_array);
} }
public function stringLiteralInCustomHelperProvider() public function stringLiteralInCustomHelperProvider()
@ -828,7 +861,6 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
$this->assertInstanceOf("InvalidArgumentException", $e); $this->assertInstanceOf("InvalidArgumentException", $e);
} }
} }
} }
/** /**
@ -839,24 +871,32 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
$loader = new \Handlebars\Loader\StringLoader(); $loader = new \Handlebars\Loader\StringLoader();
$engine = new \Handlebars\Handlebars(array('loader' => $loader)); $engine = new \Handlebars\Handlebars(array('loader' => $loader));
$engine->addHelper('test', function ($template, $context, $arg) { $engine->addHelper('test', function ($template, $context, $arg) {
return $arg.'Test.'; return $arg . 'Test.';
}); });
// assert that nested syntax is accepted and sub-helper is run // assert that nested syntax is accepted and sub-helper is run
$this->assertEquals('Test.Test.', $engine->render('{{test (test)}}', array())); $this->assertEquals('Test.Test.', $engine->render('{{test (test)}}', array()));
$engine->addHelper('add', function ($template, $context, $arg) { $engine->addHelper('add', function ($template, $context, $arg) {
$values = explode( " ", $arg ); $values = explode(" ", $arg);
return $values[0] + $values[1]; return $values[0] + $values[1];
}); });
// assert that subexpression result is inserted correctly as argument to top level helper // assert that subexpression result is inserted correctly as argument to top level helper
$this->assertEquals('42', $engine->render('{{add 21 (add 10 (add 5 6))}}', array())); $this->assertEquals('42', $engine->render('{{add 21 (add 10 (add 5 6))}}', array()));
// assert that bracketed expressions within string literals are treated correctly // assert that bracketed expressions within string literals are treated correctly
$this->assertEquals("'(test)'Test.", $engine->render("{{test '(test)'}}", array())); $this->assertEquals("'(test)'Test.", $engine->render("{{test '(test)'}}", array()));
$this->assertEquals("')'Test.Test.", $engine->render("{{test (test ')')}}", array())); $this->assertEquals("')'Test.Test.", $engine->render("{{test (test ')')}}", array()));
} }
/**
* Delimiter change test
*/
public function testDelimiterChange()
{
$engine = new \Handlebars\Handlebars();
//$engine->set
}
} }