Compare commits
10
Commits
e62b7c3849
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e28f07fd2 | ||
|
|
a22207adc4 | ||
|
|
12566be05e | ||
|
|
b03b889490 | ||
|
|
30853456a5 | ||
|
|
93f824d09a | ||
|
|
af4f8f7c0e | ||
|
|
53944831cf | ||
|
|
454b4c63e9 | ||
|
|
f6c45e8c17 |
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "mustache/mustache",
|
"name": "inforsistemas/mustache",
|
||||||
"description": "A Mustache implementation in PHP.",
|
"description": "A Mustache implementation in PHP.",
|
||||||
"keywords": ["templating", "mustache"],
|
"keywords": ["templating", "mustache"],
|
||||||
"homepage": "https://github.com/bobthecow/mustache.php",
|
"homepage": "https://github.com/bobthecow/mustache.php",
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ class Mustache_Compiler
|
|||||||
case Mustache_Tokenizer::T_PARTIAL:
|
case Mustache_Tokenizer::T_PARTIAL:
|
||||||
$code .= $this->partial(
|
$code .= $this->partial(
|
||||||
$node[Mustache_Tokenizer::NAME],
|
$node[Mustache_Tokenizer::NAME],
|
||||||
|
isset($node[Mustache_Tokenizer::DYNAMIC]) ? $node[Mustache_Tokenizer::DYNAMIC] : false,
|
||||||
isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
|
isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
|
||||||
$level
|
$level
|
||||||
);
|
);
|
||||||
@@ -125,6 +126,7 @@ class Mustache_Compiler
|
|||||||
case Mustache_Tokenizer::T_PARENT:
|
case Mustache_Tokenizer::T_PARENT:
|
||||||
$code .= $this->parent(
|
$code .= $this->parent(
|
||||||
$node[Mustache_Tokenizer::NAME],
|
$node[Mustache_Tokenizer::NAME],
|
||||||
|
isset($node[Mustache_Tokenizer::DYNAMIC]) ? $node[Mustache_Tokenizer::DYNAMIC] : false,
|
||||||
isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
|
isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
|
||||||
$node[Mustache_Tokenizer::NODES],
|
$node[Mustache_Tokenizer::NODES],
|
||||||
$level
|
$level
|
||||||
@@ -419,6 +421,30 @@ class Mustache_Compiler
|
|||||||
return sprintf($this->prepare(self::INVERTED_SECTION, $level), $method, $id, $filters, $this->walk($nodes, $level));
|
return sprintf($this->prepare(self::INVERTED_SECTION, $level), $method, $id, $filters, $this->walk($nodes, $level));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DYNAMIC_NAME = '$this->resolveValue($context->%s(%s), $context)';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate Mustache Template dynamic name resolution PHP source.
|
||||||
|
*
|
||||||
|
* @param string $id Tag name
|
||||||
|
* @param bool $dynamic True if the name is dynamic
|
||||||
|
*
|
||||||
|
* @return string Dynamic name resolution PHP source code
|
||||||
|
*/
|
||||||
|
private function resolveDynamicName($id, $dynamic)
|
||||||
|
{
|
||||||
|
if (!$dynamic) {
|
||||||
|
return var_export($id, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$method = $this->getFindMethod($id);
|
||||||
|
$id = ($method !== 'last') ? var_export($id, true) : '';
|
||||||
|
|
||||||
|
// TODO: filters?
|
||||||
|
|
||||||
|
return sprintf(self::DYNAMIC_NAME, $method, $id);
|
||||||
|
}
|
||||||
|
|
||||||
const PARTIAL_INDENT = ', $indent . %s';
|
const PARTIAL_INDENT = ', $indent . %s';
|
||||||
const PARTIAL = '
|
const PARTIAL = '
|
||||||
if ($partial = $this->mustache->loadPartial(%s)) {
|
if ($partial = $this->mustache->loadPartial(%s)) {
|
||||||
@@ -429,13 +455,14 @@ class Mustache_Compiler
|
|||||||
/**
|
/**
|
||||||
* Generate Mustache Template partial call PHP source.
|
* Generate Mustache Template partial call PHP source.
|
||||||
*
|
*
|
||||||
* @param string $id Partial name
|
* @param string $id Partial name
|
||||||
* @param string $indent Whitespace indent to apply to partial
|
* @param bool $dynamic Partial name is dynamic
|
||||||
|
* @param string $indent Whitespace indent to apply to partial
|
||||||
* @param int $level
|
* @param int $level
|
||||||
*
|
*
|
||||||
* @return string Generated partial call PHP source code
|
* @return string Generated partial call PHP source code
|
||||||
*/
|
*/
|
||||||
private function partial($id, $indent, $level)
|
private function partial($id, $dynamic, $indent, $level)
|
||||||
{
|
{
|
||||||
if ($indent !== '') {
|
if ($indent !== '') {
|
||||||
$indentParam = sprintf(self::PARTIAL_INDENT, var_export($indent, true));
|
$indentParam = sprintf(self::PARTIAL_INDENT, var_export($indent, true));
|
||||||
@@ -445,7 +472,7 @@ class Mustache_Compiler
|
|||||||
|
|
||||||
return sprintf(
|
return sprintf(
|
||||||
$this->prepare(self::PARTIAL, $level),
|
$this->prepare(self::PARTIAL, $level),
|
||||||
var_export($id, true),
|
$this->resolveDynamicName($id, $dynamic),
|
||||||
$indentParam
|
$indentParam
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -469,23 +496,25 @@ class Mustache_Compiler
|
|||||||
* Generate Mustache Template inheritance parent call PHP source.
|
* Generate Mustache Template inheritance parent call PHP source.
|
||||||
*
|
*
|
||||||
* @param string $id Parent tag name
|
* @param string $id Parent tag name
|
||||||
|
* @param bool $dynamic Tag name is dynamic
|
||||||
* @param string $indent Whitespace indent to apply to parent
|
* @param string $indent Whitespace indent to apply to parent
|
||||||
* @param array $children Child nodes
|
* @param array $children Child nodes
|
||||||
* @param int $level
|
* @param int $level
|
||||||
*
|
*
|
||||||
* @return string Generated PHP source code
|
* @return string Generated PHP source code
|
||||||
*/
|
*/
|
||||||
private function parent($id, $indent, array $children, $level)
|
private function parent($id, $dynamic, $indent, array $children, $level)
|
||||||
{
|
{
|
||||||
$realChildren = array_filter($children, array(__CLASS__, 'onlyBlockArgs'));
|
$realChildren = array_filter($children, array(__CLASS__, 'onlyBlockArgs'));
|
||||||
|
$partialName = $this->resolveDynamicName($id, $dynamic);
|
||||||
|
|
||||||
if (empty($realChildren)) {
|
if (empty($realChildren)) {
|
||||||
return sprintf($this->prepare(self::PARENT_NO_CONTEXT, $level), var_export($id, true));
|
return sprintf($this->prepare(self::PARENT_NO_CONTEXT, $level), $partialName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprintf(
|
return sprintf(
|
||||||
$this->prepare(self::PARENT, $level),
|
$this->prepare(self::PARENT, $level),
|
||||||
var_export($id, true),
|
$partialName,
|
||||||
$this->walk($realChildren, $level + 1)
|
$this->walk($realChildren, $level + 1)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -215,10 +215,6 @@ class Mustache_Context
|
|||||||
if (!($frame instanceof Closure)) {
|
if (!($frame instanceof Closure)) {
|
||||||
// Note that is_callable() *will not work here*
|
// Note that is_callable() *will not work here*
|
||||||
// See https://github.com/bobthecow/mustache.php/wiki/Magic-Methods
|
// See https://github.com/bobthecow/mustache.php/wiki/Magic-Methods
|
||||||
if (method_exists($frame, $id)) {
|
|
||||||
return $frame->$id();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($frame->$id)) {
|
if (isset($frame->$id)) {
|
||||||
return $frame->$id;
|
return $frame->$id;
|
||||||
}
|
}
|
||||||
@@ -226,6 +222,11 @@ class Mustache_Context
|
|||||||
if ($frame instanceof ArrayAccess && isset($frame[$id])) {
|
if ($frame instanceof ArrayAccess && isset($frame[$id])) {
|
||||||
return $frame[$id];
|
return $frame[$id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (method_exists($frame, $id)) {
|
||||||
|
return $frame->$id();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
+10
-8
@@ -23,18 +23,20 @@
|
|||||||
*/
|
*/
|
||||||
class Mustache_Engine
|
class Mustache_Engine
|
||||||
{
|
{
|
||||||
const VERSION = '2.14.2';
|
const VERSION = '2.14.2';
|
||||||
const SPEC_VERSION = '1.2.2';
|
const SPEC_VERSION = '1.3.0';
|
||||||
|
|
||||||
const PRAGMA_FILTERS = 'FILTERS';
|
const PRAGMA_FILTERS = 'FILTERS';
|
||||||
const PRAGMA_BLOCKS = 'BLOCKS';
|
const PRAGMA_BLOCKS = 'BLOCKS';
|
||||||
const PRAGMA_ANCHORED_DOT = 'ANCHORED-DOT';
|
const PRAGMA_ANCHORED_DOT = 'ANCHORED-DOT';
|
||||||
|
const PRAGMA_DYNAMIC_NAMES = 'DYNAMIC-NAMES';
|
||||||
|
|
||||||
// Known pragmas
|
// Known pragmas
|
||||||
private static $knownPragmas = array(
|
private static $knownPragmas = array(
|
||||||
self::PRAGMA_FILTERS => true,
|
self::PRAGMA_FILTERS => true,
|
||||||
self::PRAGMA_BLOCKS => true,
|
self::PRAGMA_BLOCKS => true,
|
||||||
self::PRAGMA_ANCHORED_DOT => true,
|
self::PRAGMA_ANCHORED_DOT => true,
|
||||||
|
self::PRAGMA_DYNAMIC_NAMES => true,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Template cache
|
// Template cache
|
||||||
|
|||||||
+74
-8
@@ -23,6 +23,7 @@ class Mustache_Parser
|
|||||||
|
|
||||||
private $pragmaFilters;
|
private $pragmaFilters;
|
||||||
private $pragmaBlocks;
|
private $pragmaBlocks;
|
||||||
|
private $pragmaDynamicNames;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process an array of Mustache tokens and convert them into a parse tree.
|
* Process an array of Mustache tokens and convert them into a parse tree.
|
||||||
@@ -37,8 +38,9 @@ class Mustache_Parser
|
|||||||
$this->lineTokens = 0;
|
$this->lineTokens = 0;
|
||||||
$this->pragmas = $this->defaultPragmas;
|
$this->pragmas = $this->defaultPragmas;
|
||||||
|
|
||||||
$this->pragmaFilters = isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS]);
|
$this->pragmaFilters = isset($this->pragmas[Mustache_Engine::PRAGMA_FILTERS]);
|
||||||
$this->pragmaBlocks = isset($this->pragmas[Mustache_Engine::PRAGMA_BLOCKS]);
|
$this->pragmaBlocks = isset($this->pragmas[Mustache_Engine::PRAGMA_BLOCKS]);
|
||||||
|
$this->pragmaDynamicNames = isset($this->pragmas[Mustache_Engine::PRAGMA_DYNAMIC_NAMES]);
|
||||||
|
|
||||||
return $this->buildTree($tokens);
|
return $this->buildTree($tokens);
|
||||||
}
|
}
|
||||||
@@ -84,11 +86,21 @@ class Mustache_Parser
|
|||||||
$this->lineTokens = 0;
|
$this->lineTokens = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->pragmaFilters && isset($token[Mustache_Tokenizer::NAME])) {
|
if ($token[Mustache_Tokenizer::TYPE] !== Mustache_Tokenizer::T_COMMENT) {
|
||||||
list($name, $filters) = $this->getNameAndFilters($token[Mustache_Tokenizer::NAME]);
|
if ($this->pragmaDynamicNames && isset($token[Mustache_Tokenizer::NAME])) {
|
||||||
if (!empty($filters)) {
|
list($name, $isDynamic) = $this->getDynamicName($token);
|
||||||
$token[Mustache_Tokenizer::NAME] = $name;
|
if ($isDynamic) {
|
||||||
$token[Mustache_Tokenizer::FILTERS] = $filters;
|
$token[Mustache_Tokenizer::NAME] = $name;
|
||||||
|
$token[Mustache_Tokenizer::DYNAMIC] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->pragmaFilters && isset($token[Mustache_Tokenizer::NAME])) {
|
||||||
|
list($name, $filters) = $this->getNameAndFilters($token[Mustache_Tokenizer::NAME]);
|
||||||
|
if (!empty($filters)) {
|
||||||
|
$token[Mustache_Tokenizer::NAME] = $name;
|
||||||
|
$token[Mustache_Tokenizer::FILTERS] = $filters;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +127,11 @@ class Mustache_Parser
|
|||||||
throw new Mustache_Exception_SyntaxException($msg, $token);
|
throw new Mustache_Exception_SyntaxException($msg, $token);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($token[Mustache_Tokenizer::NAME] !== $parent[Mustache_Tokenizer::NAME]) {
|
$sameName = $token[Mustache_Tokenizer::NAME] !== $parent[Mustache_Tokenizer::NAME];
|
||||||
|
$tokenDynamic = isset($token[Mustache_Tokenizer::DYNAMIC]) && $token[Mustache_Tokenizer::DYNAMIC];
|
||||||
|
$parentDynamic = isset($parent[Mustache_Tokenizer::DYNAMIC]) && $parent[Mustache_Tokenizer::DYNAMIC];
|
||||||
|
|
||||||
|
if ($sameName || ($tokenDynamic !== $parentDynamic)) {
|
||||||
$msg = sprintf(
|
$msg = sprintf(
|
||||||
'Nesting error: %s (on line %d) vs. %s (on line %d)',
|
'Nesting error: %s (on line %d) vs. %s (on line %d)',
|
||||||
$parent[Mustache_Tokenizer::NAME],
|
$parent[Mustache_Tokenizer::NAME],
|
||||||
@@ -280,6 +296,52 @@ class Mustache_Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse dynamic names.
|
||||||
|
*
|
||||||
|
* @throws Mustache_Exception_SyntaxException when a tag does not allow *
|
||||||
|
* @throws Mustache_Exception_SyntaxException on multiple *s, or dots or filters with *
|
||||||
|
*/
|
||||||
|
private function getDynamicName(array $token)
|
||||||
|
{
|
||||||
|
$name = $token[Mustache_Tokenizer::NAME];
|
||||||
|
$isDynamic = false;
|
||||||
|
|
||||||
|
if (preg_match('/^\s*\*\s*/', $name)) {
|
||||||
|
$this->ensureTagAllowsDynamicNames($token);
|
||||||
|
$name = preg_replace('/^\s*\*\s*/', '', $name);
|
||||||
|
$isDynamic = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array($name, $isDynamic);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the given token supports dynamic tag names.
|
||||||
|
*
|
||||||
|
* @throws Mustache_Exception_SyntaxException when a tag does not allow *
|
||||||
|
*
|
||||||
|
* @param array $token
|
||||||
|
*/
|
||||||
|
private function ensureTagAllowsDynamicNames(array $token)
|
||||||
|
{
|
||||||
|
switch ($token[Mustache_Tokenizer::TYPE]) {
|
||||||
|
case Mustache_Tokenizer::T_PARTIAL:
|
||||||
|
case Mustache_Tokenizer::T_PARENT:
|
||||||
|
case Mustache_Tokenizer::T_END_SECTION:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$msg = sprintf(
|
||||||
|
'Invalid dynamic name: %s in %s tag',
|
||||||
|
$token[Mustache_Tokenizer::NAME],
|
||||||
|
Mustache_Tokenizer::getTagName($token[Mustache_Tokenizer::TYPE])
|
||||||
|
);
|
||||||
|
|
||||||
|
throw new Mustache_Exception_SyntaxException($msg, $token);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Split a tag name into name and filters.
|
* Split a tag name into name and filters.
|
||||||
*
|
*
|
||||||
@@ -312,6 +374,10 @@ class Mustache_Parser
|
|||||||
case Mustache_Engine::PRAGMA_FILTERS:
|
case Mustache_Engine::PRAGMA_FILTERS:
|
||||||
$this->pragmaFilters = true;
|
$this->pragmaFilters = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Mustache_Engine::PRAGMA_DYNAMIC_NAMES:
|
||||||
|
$this->pragmaDynamicNames = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,9 +53,26 @@ class Mustache_Tokenizer
|
|||||||
self::T_BLOCK_VAR => true,
|
self::T_BLOCK_VAR => true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private static $tagNames = array(
|
||||||
|
self::T_SECTION => 'section',
|
||||||
|
self::T_INVERTED => 'inverted section',
|
||||||
|
self::T_END_SECTION => 'section end',
|
||||||
|
self::T_COMMENT => 'comment',
|
||||||
|
self::T_PARTIAL => 'partial',
|
||||||
|
self::T_PARENT => 'parent',
|
||||||
|
self::T_DELIM_CHANGE => 'set delimiter',
|
||||||
|
self::T_ESCAPED => 'variable',
|
||||||
|
self::T_UNESCAPED => 'unescaped variable',
|
||||||
|
self::T_UNESCAPED_2 => 'unescaped variable',
|
||||||
|
self::T_PRAGMA => 'pragma',
|
||||||
|
self::T_BLOCK_VAR => 'block variable',
|
||||||
|
self::T_BLOCK_ARG => 'block variable',
|
||||||
|
);
|
||||||
|
|
||||||
// Token properties
|
// Token properties
|
||||||
const TYPE = 'type';
|
const TYPE = 'type';
|
||||||
const NAME = 'name';
|
const NAME = 'name';
|
||||||
|
const DYNAMIC = 'dynamic';
|
||||||
const OTAG = 'otag';
|
const OTAG = 'otag';
|
||||||
const CTAG = 'ctag';
|
const CTAG = 'ctag';
|
||||||
const LINE = 'line';
|
const LINE = 'line';
|
||||||
@@ -357,6 +374,7 @@ class Mustache_Tokenizer
|
|||||||
return $end + $this->ctagLen - 1;
|
return $end + $this->ctagLen - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private function throwUnclosedTagException()
|
private function throwUnclosedTagException()
|
||||||
{
|
{
|
||||||
$name = trim($this->buffer);
|
$name = trim($this->buffer);
|
||||||
@@ -375,4 +393,16 @@ class Mustache_Tokenizer
|
|||||||
self::INDEX => $this->seenTag - $this->otagLen,
|
self::INDEX => $this->seenTag - $this->otagLen,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the human readable name for a tag type.
|
||||||
|
*
|
||||||
|
* @param string $tagType One of the tokenizer T_* constants
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
static function getTagName($tagType)
|
||||||
|
{
|
||||||
|
return isset(self::$tagNames[$tagType]) ? self::$tagNames[$tagType] : 'unknown';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Mustache.php.
|
||||||
|
*
|
||||||
|
* (c) 2010-2017 Justin Hileman
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group dynamic-names
|
||||||
|
* @group functional
|
||||||
|
*/
|
||||||
|
class Mustache_Test_Functional_DynamicPartialsTest extends PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
private $mustache;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
$this->mustache = new Mustache_Engine(array(
|
||||||
|
'pragmas' => array(Mustache_Engine::PRAGMA_DYNAMIC_NAMES),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValidDynamicNamesExamples()
|
||||||
|
{
|
||||||
|
// technically not all dynamic names, but also not invalid
|
||||||
|
return array(
|
||||||
|
array('{{>* foo }}'),
|
||||||
|
array('{{>* foo.bar.baz }}'),
|
||||||
|
array('{{=* *=}}'),
|
||||||
|
array('{{! *foo }}'),
|
||||||
|
array('{{! foo.*bar }}'),
|
||||||
|
array('{{% FILTERS }}{{! foo | *bar }}'),
|
||||||
|
array('{{% BLOCKS }}{{< *foo }}{{/ *foo }}'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getValidDynamicNamesExamples
|
||||||
|
*/
|
||||||
|
public function testLegalInheritanceExamples($template)
|
||||||
|
{
|
||||||
|
$this->assertSame('', $this->mustache->render($template));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDynamicNameParseErrors()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('{{# foo }}{{/ *foo }}'),
|
||||||
|
array('{{^ foo }}{{/ *foo }}'),
|
||||||
|
array('{{% BLOCKS }}{{< foo }}{{/ *foo }}'),
|
||||||
|
array('{{% BLOCKS }}{{$ foo }}{{/ *foo }}'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getDynamicNameParseErrors
|
||||||
|
* @expectedException Mustache_Exception_SyntaxException
|
||||||
|
* @expectedExceptionMessage Nesting error:
|
||||||
|
*/
|
||||||
|
public function testDynamicNameParseErrors($template)
|
||||||
|
{
|
||||||
|
$this->mustache->render($template);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testDynamicBlocks()
|
||||||
|
{
|
||||||
|
$tpl = '{{% BLOCKS }}{{< *partial }}{{$ bar }}{{ value }}{{/ bar }}{{/ *partial }}';
|
||||||
|
|
||||||
|
$this->mustache->setPartials(array(
|
||||||
|
'foobarbaz' => '{{% BLOCKS }}{{$ foo }}foo{{/ foo }}{{$ bar }}bar{{/ bar }}{{$ baz }}baz{{/ baz }}',
|
||||||
|
'qux' => 'qux',
|
||||||
|
));
|
||||||
|
|
||||||
|
$result = $this->mustache->render($tpl, array(
|
||||||
|
'partial' => 'foobarbaz',
|
||||||
|
'value' => 'BAR',
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertSame($result, 'fooBARbaz');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Mustache.php.
|
||||||
|
*
|
||||||
|
* (c) 2010-2017 Justin Hileman
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A PHPUnit test case wrapping the Mustache Spec.
|
||||||
|
*
|
||||||
|
* @group mustache-spec
|
||||||
|
* @group functional
|
||||||
|
*/
|
||||||
|
class Mustache_Test_Functional_MustacheDynamicNamesSpecTest extends Mustache_Test_SpecTestCase
|
||||||
|
{
|
||||||
|
public static function setUpBeforeClass()
|
||||||
|
{
|
||||||
|
self::$mustache = new Mustache_Engine(array(
|
||||||
|
'pragmas' => array(Mustache_Engine::PRAGMA_DYNAMIC_NAMES),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For some reason data providers can't mark tests skipped, so this test exists
|
||||||
|
* simply to provide a 'skipped' test if the `spec` submodule isn't initialized.
|
||||||
|
*/
|
||||||
|
public function testSpecInitialized()
|
||||||
|
{
|
||||||
|
if (!file_exists(dirname(__FILE__) . '/../../../../vendor/spec/specs/')) {
|
||||||
|
$this->markTestSkipped('Mustache spec submodule not initialized: run "git submodule update --init"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group dynamic-names
|
||||||
|
* @dataProvider loadDynamicNamesSpec
|
||||||
|
*/
|
||||||
|
public function testDynamicNamesSpec($desc, $source, $partials, $data, $expected)
|
||||||
|
{
|
||||||
|
$template = self::loadTemplate($source, $partials);
|
||||||
|
$this->assertEquals($expected, $template->render($data), $desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadDynamicNamesSpec()
|
||||||
|
{
|
||||||
|
return $this->loadSpec('~dynamic-names');
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+1
-1
Submodule vendor/spec updated: b2aeb3c283...5d3b58ea35
Reference in New Issue
Block a user