Update to proposed PSR-1 coding standard.
* 4 space (no tab) indent * K&R-style braces
This commit is contained in:
+33
-33
@@ -38,10 +38,10 @@ define('EXAMPLE_PATH', realpath(dirname(__FILE__) . '/../test/fixtures/examples'
|
||||
* @return string
|
||||
*/
|
||||
function getLowerCaseName($name) {
|
||||
return preg_replace_callback("/([A-Z])/", create_function (
|
||||
'$match',
|
||||
'return "_" . strtolower($match[1]);'
|
||||
), lcfirst($name));
|
||||
return preg_replace_callback("/([A-Z])/", create_function (
|
||||
'$match',
|
||||
'return "_" . strtolower($match[1]);'
|
||||
), lcfirst($name));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,10 +57,10 @@ function getLowerCaseName($name) {
|
||||
* @return string
|
||||
*/
|
||||
function getUpperCaseName($name) {
|
||||
return preg_replace_callback("/_([a-z])/", create_function (
|
||||
'$match',
|
||||
'return strtoupper($match{1});'
|
||||
), ucfirst($name));
|
||||
return preg_replace_callback("/_([a-z])/", create_function (
|
||||
'$match',
|
||||
'return strtoupper($match{1});'
|
||||
), ucfirst($name));
|
||||
}
|
||||
|
||||
|
||||
@@ -72,8 +72,8 @@ function getUpperCaseName($name) {
|
||||
* @return mixed
|
||||
*/
|
||||
function out($value) {
|
||||
echo $value . "\n";
|
||||
return $value;
|
||||
echo $value . "\n";
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,8 +89,8 @@ function out($value) {
|
||||
* @return string
|
||||
*/
|
||||
function buildPath($directory, $filename = null, $extension = null) {
|
||||
return out(EXAMPLE_PATH . '/' . $directory.
|
||||
($extension !== null && $filename !== null ? '/' . $filename. "." . $extension : ""));
|
||||
return out(EXAMPLE_PATH . '/' . $directory.
|
||||
($extension !== null && $filename !== null ? '/' . $filename. "." . $extension : ""));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,9 +102,9 @@ function buildPath($directory, $filename = null, $extension = null) {
|
||||
* @return void
|
||||
*/
|
||||
function createDirectory($directory) {
|
||||
if(!@mkdir(buildPath($directory))) {
|
||||
die("FAILED to create directory\n");
|
||||
}
|
||||
if(!@mkdir(buildPath($directory))) {
|
||||
die("FAILED to create directory\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,13 +119,13 @@ function createDirectory($directory) {
|
||||
* @return void
|
||||
*/
|
||||
function createFile($directory, $filename, $extension, $content = "") {
|
||||
$handle = @fopen(buildPath($directory, $filename, $extension), "w");
|
||||
if($handle) {
|
||||
fwrite($handle, $content);
|
||||
fclose($handle);
|
||||
} else {
|
||||
die("FAILED to create file\n");
|
||||
}
|
||||
$handle = @fopen(buildPath($directory, $filename, $extension), "w");
|
||||
if($handle) {
|
||||
fwrite($handle, $content);
|
||||
fclose($handle);
|
||||
} else {
|
||||
die("FAILED to create file\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -143,12 +143,12 @@ function createFile($directory, $filename, $extension, $content = "") {
|
||||
* @return void
|
||||
*/
|
||||
function main($example_name) {
|
||||
$lowercase = getLowerCaseName($example_name);
|
||||
$uppercase = getUpperCaseName($example_name);
|
||||
createDirectory($lowercase);
|
||||
createFile($lowercase, $lowercase, "mustache");
|
||||
createFile($lowercase, $lowercase, "txt");
|
||||
createFile($lowercase, $uppercase, "php", <<<CONTENT
|
||||
$lowercase = getLowerCaseName($example_name);
|
||||
$uppercase = getUpperCaseName($example_name);
|
||||
createDirectory($lowercase);
|
||||
createFile($lowercase, $lowercase, "mustache");
|
||||
createFile($lowercase, $lowercase, "txt");
|
||||
createFile($lowercase, $uppercase, "php", <<<CONTENT
|
||||
<?php
|
||||
|
||||
class {$uppercase} {
|
||||
@@ -156,16 +156,16 @@ class {$uppercase} {
|
||||
}
|
||||
|
||||
CONTENT
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
// check if enougth arguments are given
|
||||
if(count($argv) > 1) {
|
||||
// get the name of the example
|
||||
$example_name = $argv[1];
|
||||
// get the name of the example
|
||||
$example_name = $argv[1];
|
||||
|
||||
main($example_name);
|
||||
main($example_name);
|
||||
|
||||
} else {
|
||||
echo USAGE;
|
||||
echo USAGE;
|
||||
}
|
||||
|
||||
+47
-43
@@ -12,54 +12,58 @@
|
||||
/**
|
||||
* Mustache class autoloader.
|
||||
*/
|
||||
class Mustache_Autoloader {
|
||||
class Mustache_Autoloader
|
||||
{
|
||||
|
||||
private $baseDir;
|
||||
private $baseDir;
|
||||
|
||||
/**
|
||||
* Autoloader constructor.
|
||||
*
|
||||
* @param string $baseDir Mustache library base directory (default: dirname(__FILE__).'/..')
|
||||
*/
|
||||
public function __construct($baseDir = null) {
|
||||
if ($baseDir === null) {
|
||||
$this->baseDir = dirname(__FILE__).'/..';
|
||||
} else {
|
||||
$this->baseDir = rtrim($baseDir, '/');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Autoloader constructor.
|
||||
*
|
||||
* @param string $baseDir Mustache library base directory (default: dirname(__FILE__).'/..')
|
||||
*/
|
||||
public function __construct($baseDir = null)
|
||||
{
|
||||
if ($baseDir === null) {
|
||||
$this->baseDir = dirname(__FILE__).'/..';
|
||||
} else {
|
||||
$this->baseDir = rtrim($baseDir, '/');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new instance as an SPL autoloader.
|
||||
*
|
||||
* @param string $baseDir Mustache library base directory (default: dirname(__FILE__).'/..')
|
||||
*
|
||||
* @return Mustache_Autoloader Registered Autoloader instance
|
||||
*/
|
||||
static public function register($baseDir = null) {
|
||||
$loader = new self($baseDir);
|
||||
spl_autoload_register(array($loader, 'autoload'));
|
||||
/**
|
||||
* Register a new instance as an SPL autoloader.
|
||||
*
|
||||
* @param string $baseDir Mustache library base directory (default: dirname(__FILE__).'/..')
|
||||
*
|
||||
* @return Mustache_Autoloader Registered Autoloader instance
|
||||
*/
|
||||
static public function register($baseDir = null)
|
||||
{
|
||||
$loader = new self($baseDir);
|
||||
spl_autoload_register(array($loader, 'autoload'));
|
||||
|
||||
return $loader;
|
||||
}
|
||||
return $loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload Mustache classes.
|
||||
*
|
||||
* @param string $class
|
||||
*/
|
||||
public function autoload($class) {
|
||||
if ($class[0] === '\\') {
|
||||
$class = substr($class, 1);
|
||||
}
|
||||
/**
|
||||
* Autoload Mustache classes.
|
||||
*
|
||||
* @param string $class
|
||||
*/
|
||||
public function autoload($class)
|
||||
{
|
||||
if ($class[0] === '\\') {
|
||||
$class = substr($class, 1);
|
||||
}
|
||||
|
||||
if (strpos($class, 'Mustache') !== 0) {
|
||||
return;
|
||||
}
|
||||
if (strpos($class, 'Mustache') !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$file = sprintf('%s/%s.php', $this->baseDir, str_replace('_', '/', $class));
|
||||
if (is_file($file)) {
|
||||
require $file;
|
||||
}
|
||||
}
|
||||
$file = sprintf('%s/%s.php', $this->baseDir, str_replace('_', '/', $class));
|
||||
if (is_file($file)) {
|
||||
require $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+321
-306
@@ -14,355 +14,370 @@
|
||||
*
|
||||
* This class is responsible for turning a Mustache token parse tree into normal PHP source code.
|
||||
*/
|
||||
class Mustache_Compiler {
|
||||
class Mustache_Compiler
|
||||
{
|
||||
|
||||
private $sections;
|
||||
private $source;
|
||||
private $indentNextLine;
|
||||
private $customEscape;
|
||||
private $charset;
|
||||
private $sections;
|
||||
private $source;
|
||||
private $indentNextLine;
|
||||
private $customEscape;
|
||||
private $charset;
|
||||
|
||||
/**
|
||||
* Compile a Mustache token parse tree into PHP source code.
|
||||
*
|
||||
* @param string $source Mustache Template source code
|
||||
* @param string $tree Parse tree of Mustache tokens
|
||||
* @param string $name Mustache Template class name
|
||||
*
|
||||
* @return string Generated PHP source code
|
||||
*/
|
||||
public function compile($source, array $tree, $name, $customEscape = false, $charset = 'UTF-8') {
|
||||
$this->sections = array();
|
||||
$this->source = $source;
|
||||
$this->indentNextLine = true;
|
||||
$this->customEscape = $customEscape;
|
||||
$this->charset = $charset;
|
||||
/**
|
||||
* Compile a Mustache token parse tree into PHP source code.
|
||||
*
|
||||
* @param string $source Mustache Template source code
|
||||
* @param string $tree Parse tree of Mustache tokens
|
||||
* @param string $name Mustache Template class name
|
||||
*
|
||||
* @return string Generated PHP source code
|
||||
*/
|
||||
public function compile($source, array $tree, $name, $customEscape = false, $charset = 'UTF-8')
|
||||
{
|
||||
$this->sections = array();
|
||||
$this->source = $source;
|
||||
$this->indentNextLine = true;
|
||||
$this->customEscape = $customEscape;
|
||||
$this->charset = $charset;
|
||||
|
||||
return $this->writeCode($tree, $name);
|
||||
}
|
||||
return $this->writeCode($tree, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for walking the Mustache token parse tree.
|
||||
*
|
||||
* @throws InvalidArgumentException upon encountering unknown token types.
|
||||
*
|
||||
* @param array $tree Parse tree of Mustache tokens
|
||||
* @param int $level (default: 0)
|
||||
*
|
||||
* @return string Generated PHP source code;
|
||||
*/
|
||||
private function walk(array $tree, $level = 0) {
|
||||
$code = '';
|
||||
$level++;
|
||||
foreach ($tree as $node) {
|
||||
switch ($node[Mustache_Tokenizer::TYPE]) {
|
||||
case Mustache_Tokenizer::T_SECTION:
|
||||
$code .= $this->section(
|
||||
$node[Mustache_Tokenizer::NODES],
|
||||
$node[Mustache_Tokenizer::NAME],
|
||||
$node[Mustache_Tokenizer::INDEX],
|
||||
$node[Mustache_Tokenizer::END],
|
||||
$node[Mustache_Tokenizer::OTAG],
|
||||
$node[Mustache_Tokenizer::CTAG],
|
||||
$level
|
||||
);
|
||||
break;
|
||||
/**
|
||||
* Helper function for walking the Mustache token parse tree.
|
||||
*
|
||||
* @throws InvalidArgumentException upon encountering unknown token types.
|
||||
*
|
||||
* @param array $tree Parse tree of Mustache tokens
|
||||
* @param int $level (default: 0)
|
||||
*
|
||||
* @return string Generated PHP source code;
|
||||
*/
|
||||
private function walk(array $tree, $level = 0)
|
||||
{
|
||||
$code = '';
|
||||
$level++;
|
||||
foreach ($tree as $node) {
|
||||
switch ($node[Mustache_Tokenizer::TYPE]) {
|
||||
case Mustache_Tokenizer::T_SECTION:
|
||||
$code .= $this->section(
|
||||
$node[Mustache_Tokenizer::NODES],
|
||||
$node[Mustache_Tokenizer::NAME],
|
||||
$node[Mustache_Tokenizer::INDEX],
|
||||
$node[Mustache_Tokenizer::END],
|
||||
$node[Mustache_Tokenizer::OTAG],
|
||||
$node[Mustache_Tokenizer::CTAG],
|
||||
$level
|
||||
);
|
||||
break;
|
||||
|
||||
case Mustache_Tokenizer::T_INVERTED:
|
||||
$code .= $this->invertedSection(
|
||||
$node[Mustache_Tokenizer::NODES],
|
||||
$node[Mustache_Tokenizer::NAME],
|
||||
$level
|
||||
);
|
||||
break;
|
||||
case Mustache_Tokenizer::T_INVERTED:
|
||||
$code .= $this->invertedSection(
|
||||
$node[Mustache_Tokenizer::NODES],
|
||||
$node[Mustache_Tokenizer::NAME],
|
||||
$level
|
||||
);
|
||||
break;
|
||||
|
||||
case Mustache_Tokenizer::T_PARTIAL:
|
||||
case Mustache_Tokenizer::T_PARTIAL_2:
|
||||
$code .= $this->partial(
|
||||
$node[Mustache_Tokenizer::NAME],
|
||||
isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
|
||||
$level
|
||||
);
|
||||
break;
|
||||
case Mustache_Tokenizer::T_PARTIAL:
|
||||
case Mustache_Tokenizer::T_PARTIAL_2:
|
||||
$code .= $this->partial(
|
||||
$node[Mustache_Tokenizer::NAME],
|
||||
isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '',
|
||||
$level
|
||||
);
|
||||
break;
|
||||
|
||||
case Mustache_Tokenizer::T_UNESCAPED:
|
||||
case Mustache_Tokenizer::T_UNESCAPED_2:
|
||||
$code .= $this->variable($node[Mustache_Tokenizer::NAME], false, $level);
|
||||
break;
|
||||
case Mustache_Tokenizer::T_UNESCAPED:
|
||||
case Mustache_Tokenizer::T_UNESCAPED_2:
|
||||
$code .= $this->variable($node[Mustache_Tokenizer::NAME], false, $level);
|
||||
break;
|
||||
|
||||
case Mustache_Tokenizer::T_COMMENT:
|
||||
break;
|
||||
case Mustache_Tokenizer::T_COMMENT:
|
||||
break;
|
||||
|
||||
case Mustache_Tokenizer::T_ESCAPED:
|
||||
$code .= $this->variable($node[Mustache_Tokenizer::NAME], true, $level);
|
||||
break;
|
||||
case Mustache_Tokenizer::T_ESCAPED:
|
||||
$code .= $this->variable($node[Mustache_Tokenizer::NAME], true, $level);
|
||||
break;
|
||||
|
||||
|
||||
case Mustache_Tokenizer::T_TEXT:
|
||||
$code .= $this->text($node[Mustache_Tokenizer::VALUE], $level);
|
||||
break;
|
||||
case Mustache_Tokenizer::T_TEXT:
|
||||
$code .= $this->text($node[Mustache_Tokenizer::VALUE], $level);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidArgumentException('Unknown node type: '.json_encode($node));
|
||||
}
|
||||
}
|
||||
default:
|
||||
throw new InvalidArgumentException('Unknown node type: '.json_encode($node));
|
||||
}
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
return $code;
|
||||
}
|
||||
|
||||
const KLASS = '<?php
|
||||
const KLASS = '<?php
|
||||
|
||||
class %s extends Mustache_Template {
|
||||
public function renderInternal(Mustache_Context $context, $indent = \'\', $escape = false) {
|
||||
$buffer = \'\';
|
||||
%s
|
||||
class %s extends Mustache_Template
|
||||
{
|
||||
public function renderInternal(Mustache_Context $context, $indent = \'\', $escape = false)
|
||||
{
|
||||
$buffer = \'\';
|
||||
%s
|
||||
|
||||
if ($escape) {
|
||||
return %s;
|
||||
} else {
|
||||
return $buffer;
|
||||
}
|
||||
}
|
||||
%s
|
||||
}';
|
||||
if ($escape) {
|
||||
return %s;
|
||||
} else {
|
||||
return $buffer;
|
||||
}
|
||||
}
|
||||
%s
|
||||
}';
|
||||
|
||||
/**
|
||||
* Generate Mustache Template class PHP source.
|
||||
*
|
||||
* @param array $tree Parse tree of Mustache tokens
|
||||
* @param string $name Mustache Template class name
|
||||
*
|
||||
* @return string Generated PHP source code
|
||||
*/
|
||||
private function writeCode($tree, $name) {
|
||||
$code = $this->walk($tree);
|
||||
$sections = implode("\n", $this->sections);
|
||||
/**
|
||||
* Generate Mustache Template class PHP source.
|
||||
*
|
||||
* @param array $tree Parse tree of Mustache tokens
|
||||
* @param string $name Mustache Template class name
|
||||
*
|
||||
* @return string Generated PHP source code
|
||||
*/
|
||||
private function writeCode($tree, $name)
|
||||
{
|
||||
$code = $this->walk($tree);
|
||||
$sections = implode("\n", $this->sections);
|
||||
|
||||
return sprintf($this->prepare(self::KLASS, 0, false), $name, $code, $this->getEscape('$buffer'), $sections);
|
||||
}
|
||||
return sprintf($this->prepare(self::KLASS, 0, false), $name, $code, $this->getEscape('$buffer'), $sections);
|
||||
}
|
||||
|
||||
const SECTION_CALL = '
|
||||
// %s section
|
||||
$buffer .= $this->section%s($context, $indent, $context->%s(%s));
|
||||
';
|
||||
const SECTION_CALL = '
|
||||
// %s section
|
||||
$buffer .= $this->section%s($context, $indent, $context->%s(%s));
|
||||
';
|
||||
|
||||
const SECTION = '
|
||||
private function section%s(Mustache_Context $context, $indent, $value) {
|
||||
$buffer = \'\';
|
||||
if (!is_string($value) && is_callable($value)) {
|
||||
$source = %s;
|
||||
$buffer .= $this->mustache
|
||||
->loadLambda((string) call_user_func($value, $source)%s)
|
||||
->renderInternal($context, $indent);
|
||||
} elseif (!empty($value)) {
|
||||
$values = $this->isIterable($value) ? $value : array($value);
|
||||
foreach ($values as $value) {
|
||||
$context->push($value);%s
|
||||
$context->pop();
|
||||
}
|
||||
}
|
||||
const SECTION = '
|
||||
private function section%s(Mustache_Context $context, $indent, $value) {
|
||||
$buffer = \'\';
|
||||
if (!is_string($value) && is_callable($value)) {
|
||||
$source = %s;
|
||||
$buffer .= $this->mustache
|
||||
->loadLambda((string) call_user_func($value, $source)%s)
|
||||
->renderInternal($context, $indent);
|
||||
} elseif (!empty($value)) {
|
||||
$values = $this->isIterable($value) ? $value : array($value);
|
||||
foreach ($values as $value) {
|
||||
$context->push($value);%s
|
||||
$context->pop();
|
||||
}
|
||||
}
|
||||
|
||||
return $buffer;
|
||||
}';
|
||||
return $buffer;
|
||||
}';
|
||||
|
||||
/**
|
||||
* Generate Mustache Template section PHP source.
|
||||
*
|
||||
* @param array $nodes Array of child tokens
|
||||
* @param string $id Section name
|
||||
* @param int $start Section start offset
|
||||
* @param int $end Section end offset
|
||||
* @param string $otag Current Mustache opening tag
|
||||
* @param string $ctag Current Mustache closing tag
|
||||
* @param int $level
|
||||
*
|
||||
* @return string Generated section PHP source code
|
||||
*/
|
||||
private function section($nodes, $id, $start, $end, $otag, $ctag, $level) {
|
||||
$method = $this->getFindMethod($id);
|
||||
$id = var_export($id, true);
|
||||
$source = var_export(substr($this->source, $start, $end - $start), true);
|
||||
/**
|
||||
* Generate Mustache Template section PHP source.
|
||||
*
|
||||
* @param array $nodes Array of child tokens
|
||||
* @param string $id Section name
|
||||
* @param int $start Section start offset
|
||||
* @param int $end Section end offset
|
||||
* @param string $otag Current Mustache opening tag
|
||||
* @param string $ctag Current Mustache closing tag
|
||||
* @param int $level
|
||||
*
|
||||
* @return string Generated section PHP source code
|
||||
*/
|
||||
private function section($nodes, $id, $start, $end, $otag, $ctag, $level)
|
||||
{
|
||||
$method = $this->getFindMethod($id);
|
||||
$id = var_export($id, true);
|
||||
$source = var_export(substr($this->source, $start, $end - $start), true);
|
||||
|
||||
if ($otag !== '{{' || $ctag !== '}}') {
|
||||
$delims = ', '.var_export(sprintf('{{= %s %s =}}', $otag, $ctag), true);
|
||||
} else {
|
||||
$delims = '';
|
||||
}
|
||||
if ($otag !== '{{' || $ctag !== '}}') {
|
||||
$delims = ', '.var_export(sprintf('{{= %s %s =}}', $otag, $ctag), true);
|
||||
} else {
|
||||
$delims = '';
|
||||
}
|
||||
|
||||
$key = ucfirst(md5($delims."\n".$source));
|
||||
$key = ucfirst(md5($delims."\n".$source));
|
||||
|
||||
if (!isset($this->sections[$key])) {
|
||||
$this->sections[$key] = sprintf($this->prepare(self::SECTION), $key, $source, $delims, $this->walk($nodes, 2));
|
||||
}
|
||||
if (!isset($this->sections[$key])) {
|
||||
$this->sections[$key] = sprintf($this->prepare(self::SECTION), $key, $source, $delims, $this->walk($nodes, 2));
|
||||
}
|
||||
|
||||
return sprintf($this->prepare(self::SECTION_CALL, $level), $id, $key, $method, $id);
|
||||
}
|
||||
return sprintf($this->prepare(self::SECTION_CALL, $level), $id, $key, $method, $id);
|
||||
}
|
||||
|
||||
const INVERTED_SECTION = '
|
||||
// %s inverted section
|
||||
$value = $context->%s(%s);
|
||||
if (empty($value)) {
|
||||
%s
|
||||
}';
|
||||
const INVERTED_SECTION = '
|
||||
// %s inverted section
|
||||
$value = $context->%s(%s);
|
||||
if (empty($value)) {
|
||||
%s
|
||||
}';
|
||||
|
||||
/**
|
||||
* Generate Mustache Template inverted section PHP source.
|
||||
*
|
||||
* @param array $nodes Array of child tokens
|
||||
* @param string $id Section name
|
||||
* @param int $level
|
||||
*
|
||||
* @return string Generated inverted section PHP source code
|
||||
*/
|
||||
private function invertedSection($nodes, $id, $level) {
|
||||
$method = $this->getFindMethod($id);
|
||||
$id = var_export($id, true);
|
||||
/**
|
||||
* Generate Mustache Template inverted section PHP source.
|
||||
*
|
||||
* @param array $nodes Array of child tokens
|
||||
* @param string $id Section name
|
||||
* @param int $level
|
||||
*
|
||||
* @return string Generated inverted section PHP source code
|
||||
*/
|
||||
private function invertedSection($nodes, $id, $level)
|
||||
{
|
||||
$method = $this->getFindMethod($id);
|
||||
$id = var_export($id, true);
|
||||
|
||||
return sprintf($this->prepare(self::INVERTED_SECTION, $level), $id, $method, $id, $this->walk($nodes, $level));
|
||||
}
|
||||
return sprintf($this->prepare(self::INVERTED_SECTION, $level), $id, $method, $id, $this->walk($nodes, $level));
|
||||
}
|
||||
|
||||
const PARTIAL = '
|
||||
if ($partial = $this->mustache->loadPartial(%s)) {
|
||||
$buffer .= $partial->renderInternal($context, %s);
|
||||
}
|
||||
';
|
||||
const PARTIAL = '
|
||||
if ($partial = $this->mustache->loadPartial(%s)) {
|
||||
$buffer .= $partial->renderInternal($context, %s);
|
||||
}
|
||||
';
|
||||
|
||||
/**
|
||||
* Generate Mustache Template partial call PHP source.
|
||||
*
|
||||
* @param string $id Partial name
|
||||
* @param string $indent Whitespace indent to apply to partial
|
||||
* @param int $level
|
||||
*
|
||||
* @return string Generated partial call PHP source code
|
||||
*/
|
||||
private function partial($id, $indent, $level) {
|
||||
return sprintf(
|
||||
$this->prepare(self::PARTIAL, $level),
|
||||
var_export($id, true),
|
||||
var_export($indent, true)
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Generate Mustache Template partial call PHP source.
|
||||
*
|
||||
* @param string $id Partial name
|
||||
* @param string $indent Whitespace indent to apply to partial
|
||||
* @param int $level
|
||||
*
|
||||
* @return string Generated partial call PHP source code
|
||||
*/
|
||||
private function partial($id, $indent, $level)
|
||||
{
|
||||
return sprintf(
|
||||
$this->prepare(self::PARTIAL, $level),
|
||||
var_export($id, true),
|
||||
var_export($indent, true)
|
||||
);
|
||||
}
|
||||
|
||||
const VARIABLE = '
|
||||
$value = $context->%s(%s);
|
||||
if (!is_string($value) && is_callable($value)) {
|
||||
$value = $this->mustache
|
||||
->loadLambda((string) call_user_func($value))
|
||||
->renderInternal($context, $indent);
|
||||
}
|
||||
$buffer .= %s%s;
|
||||
';
|
||||
const VARIABLE = '
|
||||
$value = $context->%s(%s);
|
||||
if (!is_string($value) && is_callable($value)) {
|
||||
$value = $this->mustache
|
||||
->loadLambda((string) call_user_func($value))
|
||||
->renderInternal($context, $indent);
|
||||
}
|
||||
$buffer .= %s%s;
|
||||
';
|
||||
|
||||
/**
|
||||
* Generate Mustache Template variable interpolation PHP source.
|
||||
*
|
||||
* @param string $id Variable name
|
||||
* @param boolean $escape Escape the variable value for output?
|
||||
* @param int $level
|
||||
*
|
||||
* @return string Generated variable interpolation PHP source
|
||||
*/
|
||||
private function variable($id, $escape, $level) {
|
||||
$method = $this->getFindMethod($id);
|
||||
$id = ($method !== 'last') ? var_export($id, true) : '';
|
||||
$value = $escape ? $this->getEscape() : '$value';
|
||||
/**
|
||||
* Generate Mustache Template variable interpolation PHP source.
|
||||
*
|
||||
* @param string $id Variable name
|
||||
* @param boolean $escape Escape the variable value for output?
|
||||
* @param int $level
|
||||
*
|
||||
* @return string Generated variable interpolation PHP source
|
||||
*/
|
||||
private function variable($id, $escape, $level)
|
||||
{
|
||||
$method = $this->getFindMethod($id);
|
||||
$id = ($method !== 'last') ? var_export($id, true) : '';
|
||||
$value = $escape ? $this->getEscape() : '$value';
|
||||
|
||||
return sprintf($this->prepare(self::VARIABLE, $level), $method, $id, $this->flushIndent(), $value);
|
||||
}
|
||||
return sprintf($this->prepare(self::VARIABLE, $level), $method, $id, $this->flushIndent(), $value);
|
||||
}
|
||||
|
||||
const LINE = '$buffer .= "\n";';
|
||||
const TEXT = '$buffer .= %s%s;';
|
||||
const LINE = '$buffer .= "\n";';
|
||||
const TEXT = '$buffer .= %s%s;';
|
||||
|
||||
/**
|
||||
* Generate Mustache Template output Buffer call PHP source.
|
||||
*
|
||||
* @param string $text
|
||||
* @param int $level
|
||||
*
|
||||
* @return string Generated output Buffer call PHP source
|
||||
*/
|
||||
private function text($text, $level) {
|
||||
if ($text === "\n") {
|
||||
$this->indentNextLine = true;
|
||||
/**
|
||||
* Generate Mustache Template output Buffer call PHP source.
|
||||
*
|
||||
* @param string $text
|
||||
* @param int $level
|
||||
*
|
||||
* @return string Generated output Buffer call PHP source
|
||||
*/
|
||||
private function text($text, $level)
|
||||
{
|
||||
if ($text === "\n") {
|
||||
$this->indentNextLine = true;
|
||||
|
||||
return $this->prepare(self::LINE, $level);
|
||||
} else {
|
||||
return sprintf($this->prepare(self::TEXT, $level), $this->flushIndent(), var_export($text, true));
|
||||
}
|
||||
}
|
||||
return $this->prepare(self::LINE, $level);
|
||||
} else {
|
||||
return sprintf($this->prepare(self::TEXT, $level), $this->flushIndent(), var_export($text, true));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare PHP source code snippet for output.
|
||||
*
|
||||
* @param string $text
|
||||
* @param int $bonus Additional indent level (default: 0)
|
||||
* @param boolean $prependNewline Prepend a newline to the snippet? (default: true)
|
||||
*
|
||||
* @return string PHP source code snippet
|
||||
*/
|
||||
private function prepare($text, $bonus = 0, $prependNewline = true) {
|
||||
$text = ($prependNewline ? "\n" : '').trim($text);
|
||||
if ($prependNewline) {
|
||||
$bonus++;
|
||||
}
|
||||
/**
|
||||
* Prepare PHP source code snippet for output.
|
||||
*
|
||||
* @param string $text
|
||||
* @param int $bonus Additional indent level (default: 0)
|
||||
* @param boolean $prependNewline Prepend a newline to the snippet? (default: true)
|
||||
*
|
||||
* @return string PHP source code snippet
|
||||
*/
|
||||
private function prepare($text, $bonus = 0, $prependNewline = true)
|
||||
{
|
||||
$text = ($prependNewline ? "\n" : '').trim($text);
|
||||
if ($prependNewline) {
|
||||
$bonus++;
|
||||
}
|
||||
|
||||
return preg_replace("/\n(\t\t)?/", "\n".str_repeat("\t", $bonus), $text);
|
||||
}
|
||||
return preg_replace("/\n( {8})?/", "\n".str_repeat(" ", $bonus * 4), $text);
|
||||
}
|
||||
|
||||
const DEFAULT_ESCAPE = 'htmlspecialchars(%s, ENT_COMPAT, %s)';
|
||||
const CUSTOM_ESCAPE = 'call_user_func($this->mustache->getEscape(), %s)';
|
||||
const DEFAULT_ESCAPE = 'htmlspecialchars(%s, ENT_COMPAT, %s)';
|
||||
const CUSTOM_ESCAPE = 'call_user_func($this->mustache->getEscape(), %s)';
|
||||
|
||||
/**
|
||||
* Get the current escaper.
|
||||
*
|
||||
* @return string Either a custom callback, or an inline call to `htmlspecialchars`
|
||||
*/
|
||||
private function getEscape($value = '$value') {
|
||||
if ($this->customEscape) {
|
||||
return sprintf(self::CUSTOM_ESCAPE, $value);
|
||||
} else {
|
||||
return sprintf(self::DEFAULT_ESCAPE, $value, var_export($this->charset, true));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get the current escaper.
|
||||
*
|
||||
* @return string Either a custom callback, or an inline call to `htmlspecialchars`
|
||||
*/
|
||||
private function getEscape($value = '$value')
|
||||
{
|
||||
if ($this->customEscape) {
|
||||
return sprintf(self::CUSTOM_ESCAPE, $value);
|
||||
} else {
|
||||
return sprintf(self::DEFAULT_ESCAPE, $value, var_export($this->charset, true));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the appropriate Context `find` method for a given $id.
|
||||
*
|
||||
* The return value will be one of `find`, `findDot` or `last`.
|
||||
*
|
||||
* @see Mustache_Context::find
|
||||
* @see Mustache_Context::findDot
|
||||
* @see Mustache_Context::last
|
||||
*
|
||||
* @param string $id Variable name
|
||||
*
|
||||
* @return string `find` method name
|
||||
*/
|
||||
private function getFindMethod($id) {
|
||||
if ($id === '.') {
|
||||
return 'last';
|
||||
} elseif (strpos($id, '.') === false) {
|
||||
return 'find';
|
||||
} else {
|
||||
return 'findDot';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Select the appropriate Context `find` method for a given $id.
|
||||
*
|
||||
* The return value will be one of `find`, `findDot` or `last`.
|
||||
*
|
||||
* @see Mustache_Context::find
|
||||
* @see Mustache_Context::findDot
|
||||
* @see Mustache_Context::last
|
||||
*
|
||||
* @param string $id Variable name
|
||||
*
|
||||
* @return string `find` method name
|
||||
*/
|
||||
private function getFindMethod($id)
|
||||
{
|
||||
if ($id === '.') {
|
||||
return 'last';
|
||||
} elseif (strpos($id, '.') === false) {
|
||||
return 'find';
|
||||
} else {
|
||||
return 'findDot';
|
||||
}
|
||||
}
|
||||
|
||||
const LINE_INDENT = '$indent . ';
|
||||
const LINE_INDENT = '$indent . ';
|
||||
|
||||
/**
|
||||
* Get the current $indent prefix to write to the buffer.
|
||||
*
|
||||
* @return string "$indent . " or ""
|
||||
*/
|
||||
private function flushIndent() {
|
||||
if ($this->indentNextLine) {
|
||||
$this->indentNextLine = false;
|
||||
/**
|
||||
* Get the current $indent prefix to write to the buffer.
|
||||
*
|
||||
* @return string "$indent . " or ""
|
||||
*/
|
||||
private function flushIndent()
|
||||
{
|
||||
if ($this->indentNextLine) {
|
||||
$this->indentNextLine = false;
|
||||
|
||||
return self::LINE_INDENT;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
return self::LINE_INDENT;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+123
-115
@@ -12,130 +12,138 @@
|
||||
/**
|
||||
* Mustache Template rendering Context.
|
||||
*/
|
||||
class Mustache_Context {
|
||||
private $stack = array();
|
||||
class Mustache_Context
|
||||
{
|
||||
private $stack = array();
|
||||
|
||||
/**
|
||||
* Mustache rendering Context constructor.
|
||||
*
|
||||
* @param mixed $context Default rendering context (default: null)
|
||||
*/
|
||||
public function __construct($context = null) {
|
||||
if ($context !== null) {
|
||||
$this->stack = array($context);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Mustache rendering Context constructor.
|
||||
*
|
||||
* @param mixed $context Default rendering context (default: null)
|
||||
*/
|
||||
public function __construct($context = null)
|
||||
{
|
||||
if ($context !== null) {
|
||||
$this->stack = array($context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a new Context frame onto the stack.
|
||||
*
|
||||
* @param mixed $value Object or array to use for context
|
||||
*/
|
||||
public function push($value) {
|
||||
array_push($this->stack, $value);
|
||||
}
|
||||
/**
|
||||
* Push a new Context frame onto the stack.
|
||||
*
|
||||
* @param mixed $value Object or array to use for context
|
||||
*/
|
||||
public function push($value)
|
||||
{
|
||||
array_push($this->stack, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop the last Context frame from the stack.
|
||||
*
|
||||
* @return mixed Last Context frame (object or array)
|
||||
*/
|
||||
public function pop() {
|
||||
return array_pop($this->stack);
|
||||
}
|
||||
/**
|
||||
* Pop the last Context frame from the stack.
|
||||
*
|
||||
* @return mixed Last Context frame (object or array)
|
||||
*/
|
||||
public function pop()
|
||||
{
|
||||
return array_pop($this->stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last Context frame.
|
||||
*
|
||||
* @return mixed Last Context frame (object or array)
|
||||
*/
|
||||
public function last() {
|
||||
return end($this->stack);
|
||||
}
|
||||
/**
|
||||
* Get the last Context frame.
|
||||
*
|
||||
* @return mixed Last Context frame (object or array)
|
||||
*/
|
||||
public function last()
|
||||
{
|
||||
return end($this->stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a variable in the Context stack.
|
||||
*
|
||||
* Starting with the last Context frame (the context of the innermost section), and working back to the top-level
|
||||
* rendering context, look for a variable with the given name:
|
||||
*
|
||||
* * If the Context frame is an associative array which contains the key $id, returns the value of that element.
|
||||
* * If the Context frame is an object, this will check first for a public method, then a public property named
|
||||
* $id. Failing both of these, it will try `__isset` and `__get` magic methods.
|
||||
* * If a value named $id is not found in any Context frame, returns an empty string.
|
||||
*
|
||||
* @param string $id Variable name
|
||||
*
|
||||
* @return mixed Variable value, or '' if not found
|
||||
*/
|
||||
public function find($id) {
|
||||
return $this->findVariableInStack($id, $this->stack);
|
||||
}
|
||||
/**
|
||||
* Find a variable in the Context stack.
|
||||
*
|
||||
* Starting with the last Context frame (the context of the innermost section), and working back to the top-level
|
||||
* rendering context, look for a variable with the given name:
|
||||
*
|
||||
* * If the Context frame is an associative array which contains the key $id, returns the value of that element.
|
||||
* * If the Context frame is an object, this will check first for a public method, then a public property named
|
||||
* $id. Failing both of these, it will try `__isset` and `__get` magic methods.
|
||||
* * If a value named $id is not found in any Context frame, returns an empty string.
|
||||
*
|
||||
* @param string $id Variable name
|
||||
*
|
||||
* @return mixed Variable value, or '' if not found
|
||||
*/
|
||||
public function find($id)
|
||||
{
|
||||
return $this->findVariableInStack($id, $this->stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a 'dot notation' variable in the Context stack.
|
||||
*
|
||||
* Note that dot notation traversal bubbles through scope differently than the regular find method. After finding
|
||||
* the initial chunk of the dotted name, each subsequent chunk is searched for only within the value of the previous
|
||||
* result. For example, given the following context stack:
|
||||
*
|
||||
* $data = array(
|
||||
* 'name' => 'Fred',
|
||||
* 'child' => array(
|
||||
* 'name' => 'Bob'
|
||||
* ),
|
||||
* );
|
||||
*
|
||||
* ... and the Mustache following template:
|
||||
*
|
||||
* {{ child.name }}
|
||||
*
|
||||
* ... the `name` value is only searched for within the `child` value of the global Context, not within parent
|
||||
* Context frames.
|
||||
*
|
||||
* @param string $id Dotted variable selector
|
||||
*
|
||||
* @return mixed Variable value, or '' if not found
|
||||
*/
|
||||
public function findDot($id) {
|
||||
$chunks = explode('.', $id);
|
||||
$first = array_shift($chunks);
|
||||
$value = $this->findVariableInStack($first, $this->stack);
|
||||
/**
|
||||
* Find a 'dot notation' variable in the Context stack.
|
||||
*
|
||||
* Note that dot notation traversal bubbles through scope differently than the regular find method. After finding
|
||||
* the initial chunk of the dotted name, each subsequent chunk is searched for only within the value of the previous
|
||||
* result. For example, given the following context stack:
|
||||
*
|
||||
* $data = array(
|
||||
* 'name' => 'Fred',
|
||||
* 'child' => array(
|
||||
* 'name' => 'Bob'
|
||||
* ),
|
||||
* );
|
||||
*
|
||||
* ... and the Mustache following template:
|
||||
*
|
||||
* {{ child.name }}
|
||||
*
|
||||
* ... the `name` value is only searched for within the `child` value of the global Context, not within parent
|
||||
* Context frames.
|
||||
*
|
||||
* @param string $id Dotted variable selector
|
||||
*
|
||||
* @return mixed Variable value, or '' if not found
|
||||
*/
|
||||
public function findDot($id)
|
||||
{
|
||||
$chunks = explode('.', $id);
|
||||
$first = array_shift($chunks);
|
||||
$value = $this->findVariableInStack($first, $this->stack);
|
||||
|
||||
foreach ($chunks as $chunk) {
|
||||
if ($value === '') {
|
||||
return $value;
|
||||
}
|
||||
foreach ($chunks as $chunk) {
|
||||
if ($value === '') {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$value = $this->findVariableInStack($chunk, array($value));
|
||||
}
|
||||
$value = $this->findVariableInStack($chunk, array($value));
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to find a variable in the Context stack.
|
||||
*
|
||||
* @see Mustache_Context::find
|
||||
*
|
||||
* @param string $id Variable name
|
||||
* @param array $stack Context stack
|
||||
*
|
||||
* @return mixed Variable value, or '' if not found
|
||||
*/
|
||||
private function findVariableInStack($id, array $stack) {
|
||||
for ($i = count($stack) - 1; $i >= 0; $i--) {
|
||||
if (is_object($stack[$i])) {
|
||||
if (method_exists($stack[$i], $id)) {
|
||||
return $stack[$i]->$id();
|
||||
} elseif (isset($stack[$i]->$id)) {
|
||||
return $stack[$i]->$id;
|
||||
}
|
||||
} elseif (is_array($stack[$i]) && array_key_exists($id, $stack[$i])) {
|
||||
return $stack[$i][$id];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Helper function to find a variable in the Context stack.
|
||||
*
|
||||
* @see Mustache_Context::find
|
||||
*
|
||||
* @param string $id Variable name
|
||||
* @param array $stack Context stack
|
||||
*
|
||||
* @return mixed Variable value, or '' if not found
|
||||
*/
|
||||
private function findVariableInStack($id, array $stack)
|
||||
{
|
||||
for ($i = count($stack) - 1; $i >= 0; $i--) {
|
||||
if (is_object($stack[$i])) {
|
||||
if (method_exists($stack[$i], $id)) {
|
||||
return $stack[$i]->$id();
|
||||
} elseif (isset($stack[$i]->$id)) {
|
||||
return $stack[$i]->$id;
|
||||
}
|
||||
} elseif (is_array($stack[$i]) && array_key_exists($id, $stack[$i])) {
|
||||
return $stack[$i][$id];
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
+504
-472
File diff suppressed because it is too large
Load Diff
+139
-127
@@ -12,145 +12,157 @@
|
||||
/**
|
||||
* A collection of helpers for a Mustache instance.
|
||||
*/
|
||||
class Mustache_HelperCollection {
|
||||
private $helpers = array();
|
||||
class Mustache_HelperCollection
|
||||
{
|
||||
private $helpers = array();
|
||||
|
||||
/**
|
||||
* Helper Collection constructor.
|
||||
*
|
||||
* Optionally accepts an array (or Traversable) of `$name => $helper` pairs.
|
||||
*
|
||||
* @throws InvalidArgumentException if the $helpers argument isn't an array or Traversable
|
||||
*
|
||||
* @param array|Traversable $helpers (default: null)
|
||||
*/
|
||||
public function __construct($helpers = null) {
|
||||
if ($helpers !== null) {
|
||||
if (!is_array($helpers) && !$helpers instanceof Traversable) {
|
||||
throw new InvalidArgumentException('HelperCollection constructor expects an array of helpers');
|
||||
}
|
||||
/**
|
||||
* Helper Collection constructor.
|
||||
*
|
||||
* Optionally accepts an array (or Traversable) of `$name => $helper` pairs.
|
||||
*
|
||||
* @throws InvalidArgumentException if the $helpers argument isn't an array or Traversable
|
||||
*
|
||||
* @param array|Traversable $helpers (default: null)
|
||||
*/
|
||||
public function __construct($helpers = null)
|
||||
{
|
||||
if ($helpers !== null) {
|
||||
if (!is_array($helpers) && !$helpers instanceof Traversable) {
|
||||
throw new InvalidArgumentException('HelperCollection constructor expects an array of helpers');
|
||||
}
|
||||
|
||||
foreach ($helpers as $name => $helper) {
|
||||
$this->add($name, $helper);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($helpers as $name => $helper) {
|
||||
$this->add($name, $helper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic mutator.
|
||||
*
|
||||
* @see Mustache_HelperCollection::add
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $helper
|
||||
*/
|
||||
public function __set($name, $helper) {
|
||||
$this->add($name, $helper);
|
||||
}
|
||||
/**
|
||||
* Magic mutator.
|
||||
*
|
||||
* @see Mustache_HelperCollection::add
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $helper
|
||||
*/
|
||||
public function __set($name, $helper)
|
||||
{
|
||||
$this->add($name, $helper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a helper to this collection.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $helper
|
||||
*/
|
||||
public function add($name, $helper) {
|
||||
$this->helpers[$name] = $helper;
|
||||
}
|
||||
/**
|
||||
* Add a helper to this collection.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $helper
|
||||
*/
|
||||
public function add($name, $helper)
|
||||
{
|
||||
$this->helpers[$name] = $helper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic accessor.
|
||||
*
|
||||
* @see Mustache_HelperCollection::get
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return mixed Helper
|
||||
*/
|
||||
public function __get($name) {
|
||||
return $this->get($name);
|
||||
}
|
||||
/**
|
||||
* Magic accessor.
|
||||
*
|
||||
* @see Mustache_HelperCollection::get
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return mixed Helper
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return $this->get($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a helper by name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return mixed Helper
|
||||
*/
|
||||
public function get($name) {
|
||||
if (!$this->has($name)) {
|
||||
throw new InvalidArgumentException('Unknown helper: '.$name);
|
||||
}
|
||||
/**
|
||||
* Get a helper by name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return mixed Helper
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
if (!$this->has($name)) {
|
||||
throw new InvalidArgumentException('Unknown helper: '.$name);
|
||||
}
|
||||
|
||||
return $this->helpers[$name];
|
||||
}
|
||||
return $this->helpers[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic isset().
|
||||
*
|
||||
* @see Mustache_HelperCollection::has
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return boolean True if helper is present
|
||||
*/
|
||||
public function __isset($name) {
|
||||
return $this->has($name);
|
||||
}
|
||||
/**
|
||||
* Magic isset().
|
||||
*
|
||||
* @see Mustache_HelperCollection::has
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return boolean True if helper is present
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
return $this->has($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a given helper is present in the collection.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return boolean True if helper is present
|
||||
*/
|
||||
public function has($name) {
|
||||
return array_key_exists($name, $this->helpers);
|
||||
}
|
||||
/**
|
||||
* Check whether a given helper is present in the collection.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return boolean True if helper is present
|
||||
*/
|
||||
public function has($name)
|
||||
{
|
||||
return array_key_exists($name, $this->helpers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic unset().
|
||||
*
|
||||
* @see Mustache_HelperCollection::remove
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function __unset($name) {
|
||||
$this->remove($name);
|
||||
}
|
||||
/**
|
||||
* Magic unset().
|
||||
*
|
||||
* @see Mustache_HelperCollection::remove
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function __unset($name)
|
||||
{
|
||||
$this->remove($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a given helper is present in the collection.
|
||||
*
|
||||
* @throws InvalidArgumentException if the requested helper is not present.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function remove($name) {
|
||||
if (!$this->has($name)) {
|
||||
throw new InvalidArgumentException('Unknown helper: '.$name);
|
||||
}
|
||||
/**
|
||||
* Check whether a given helper is present in the collection.
|
||||
*
|
||||
* @throws InvalidArgumentException if the requested helper is not present.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function remove($name)
|
||||
{
|
||||
if (!$this->has($name)) {
|
||||
throw new InvalidArgumentException('Unknown helper: '.$name);
|
||||
}
|
||||
|
||||
unset($this->helpers[$name]);
|
||||
}
|
||||
unset($this->helpers[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the helper collection.
|
||||
*
|
||||
* Removes all helpers from this collection
|
||||
*/
|
||||
public function clear() {
|
||||
$this->helpers = array();
|
||||
}
|
||||
/**
|
||||
* Clear the helper collection.
|
||||
*
|
||||
* Removes all helpers from this collection
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->helpers = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the helper collection is empty.
|
||||
*
|
||||
* @return boolean True if the collection is empty
|
||||
*/
|
||||
public function isEmpty() {
|
||||
return empty($this->helpers);
|
||||
}
|
||||
/**
|
||||
* Check whether the helper collection is empty.
|
||||
*
|
||||
* @return boolean True if the collection is empty
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return empty($this->helpers);
|
||||
}
|
||||
}
|
||||
|
||||
+10
-9
@@ -12,14 +12,15 @@
|
||||
/**
|
||||
* Mustache Template Loader interface.
|
||||
*/
|
||||
interface Mustache_Loader {
|
||||
interface Mustache_Loader
|
||||
{
|
||||
|
||||
/**
|
||||
* Load a Template by name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return string Mustache Template source
|
||||
*/
|
||||
function load($name);
|
||||
/**
|
||||
* Load a Template by name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return string Mustache Template source
|
||||
*/
|
||||
public function load($name);
|
||||
}
|
||||
|
||||
@@ -27,48 +27,53 @@
|
||||
* @implements Loader
|
||||
* @implements MutableLoader
|
||||
*/
|
||||
class Mustache_Loader_ArrayLoader implements Mustache_Loader, Mustache_Loader_MutableLoader {
|
||||
class Mustache_Loader_ArrayLoader implements Mustache_Loader, Mustache_Loader_MutableLoader
|
||||
{
|
||||
|
||||
/**
|
||||
* ArrayLoader constructor.
|
||||
*
|
||||
* @param array $templates Associative array of Template source (default: array())
|
||||
*/
|
||||
public function __construct(array $templates = array()) {
|
||||
$this->templates = $templates;
|
||||
}
|
||||
/**
|
||||
* ArrayLoader constructor.
|
||||
*
|
||||
* @param array $templates Associative array of Template source (default: array())
|
||||
*/
|
||||
public function __construct(array $templates = array())
|
||||
{
|
||||
$this->templates = $templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a Template.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return string Mustache Template source
|
||||
*/
|
||||
public function load($name) {
|
||||
if (!isset($this->templates[$name])) {
|
||||
throw new InvalidArgumentException('Template '.$name.' not found.');
|
||||
}
|
||||
/**
|
||||
* Load a Template.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return string Mustache Template source
|
||||
*/
|
||||
public function load($name)
|
||||
{
|
||||
if (!isset($this->templates[$name])) {
|
||||
throw new InvalidArgumentException('Template '.$name.' not found.');
|
||||
}
|
||||
|
||||
return $this->templates[$name];
|
||||
}
|
||||
return $this->templates[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an associative array of Template sources for this loader.
|
||||
*
|
||||
* @param array $templates
|
||||
*/
|
||||
public function setTemplates(array $templates) {
|
||||
$this->templates = $templates;
|
||||
}
|
||||
/**
|
||||
* Set an associative array of Template sources for this loader.
|
||||
*
|
||||
* @param array $templates
|
||||
*/
|
||||
public function setTemplates(array $templates)
|
||||
{
|
||||
$this->templates = $templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a Template source by name.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $template Mustache Template source
|
||||
*/
|
||||
public function setTemplate($name, $template) {
|
||||
$this->templates[$name] = $template;
|
||||
}
|
||||
/**
|
||||
* Set a Template source by name.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $template Mustache Template source
|
||||
*/
|
||||
public function setTemplate($name, $template)
|
||||
{
|
||||
$this->templates[$name] = $template;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,88 +26,93 @@
|
||||
*
|
||||
* @implements Loader
|
||||
*/
|
||||
class Mustache_Loader_FilesystemLoader implements Mustache_Loader {
|
||||
private $baseDir;
|
||||
private $extension = '.mustache';
|
||||
private $templates = array();
|
||||
class Mustache_Loader_FilesystemLoader implements Mustache_Loader
|
||||
{
|
||||
private $baseDir;
|
||||
private $extension = '.mustache';
|
||||
private $templates = array();
|
||||
|
||||
/**
|
||||
* Mustache filesystem Loader constructor.
|
||||
*
|
||||
* Passing an $options array allows overriding certain Loader options during instantiation:
|
||||
*
|
||||
* $options = array(
|
||||
* // The filename extension used for Mustache templates. Defaults to '.mustache'
|
||||
* 'extension' => '.ms',
|
||||
* );
|
||||
*
|
||||
* @throws RuntimeException if $baseDir does not exist.
|
||||
*
|
||||
* @param string $baseDir Base directory containing Mustache template files.
|
||||
* @param array $options Array of Loader options (default: array())
|
||||
*/
|
||||
public function __construct($baseDir, array $options = array()) {
|
||||
$this->baseDir = rtrim(realpath($baseDir), '/');
|
||||
/**
|
||||
* Mustache filesystem Loader constructor.
|
||||
*
|
||||
* Passing an $options array allows overriding certain Loader options during instantiation:
|
||||
*
|
||||
* $options = array(
|
||||
* // The filename extension used for Mustache templates. Defaults to '.mustache'
|
||||
* 'extension' => '.ms',
|
||||
* );
|
||||
*
|
||||
* @throws RuntimeException if $baseDir does not exist.
|
||||
*
|
||||
* @param string $baseDir Base directory containing Mustache template files.
|
||||
* @param array $options Array of Loader options (default: array())
|
||||
*/
|
||||
public function __construct($baseDir, array $options = array())
|
||||
{
|
||||
$this->baseDir = rtrim(realpath($baseDir), '/');
|
||||
|
||||
if (!is_dir($this->baseDir)) {
|
||||
throw new RuntimeException('FilesystemLoader baseDir must be a directory: '.$baseDir);
|
||||
}
|
||||
if (!is_dir($this->baseDir)) {
|
||||
throw new RuntimeException('FilesystemLoader baseDir must be a directory: '.$baseDir);
|
||||
}
|
||||
|
||||
if (isset($options['extension'])) {
|
||||
$this->extension = '.' . ltrim($options['extension'], '.');
|
||||
}
|
||||
}
|
||||
if (isset($options['extension'])) {
|
||||
$this->extension = '.' . ltrim($options['extension'], '.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a Template by name.
|
||||
*
|
||||
* $loader = new FilesystemLoader(dirname(__FILE__).'/views');
|
||||
* $loader->load('admin/dashboard'); // loads "./views/admin/dashboard.mustache";
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return string Mustache Template source
|
||||
*/
|
||||
public function load($name) {
|
||||
if (!isset($this->templates[$name])) {
|
||||
$this->templates[$name] = $this->loadFile($name);
|
||||
}
|
||||
/**
|
||||
* Load a Template by name.
|
||||
*
|
||||
* $loader = new FilesystemLoader(dirname(__FILE__).'/views');
|
||||
* $loader->load('admin/dashboard'); // loads "./views/admin/dashboard.mustache";
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return string Mustache Template source
|
||||
*/
|
||||
public function load($name)
|
||||
{
|
||||
if (!isset($this->templates[$name])) {
|
||||
$this->templates[$name] = $this->loadFile($name);
|
||||
}
|
||||
|
||||
return $this->templates[$name];
|
||||
}
|
||||
return $this->templates[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for loading a Mustache file by name.
|
||||
*
|
||||
* @throws InvalidArgumentException if a template file is not found.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return string Mustache Template source
|
||||
*/
|
||||
private function loadFile($name) {
|
||||
$fileName = $this->getFileName($name);
|
||||
/**
|
||||
* Helper function for loading a Mustache file by name.
|
||||
*
|
||||
* @throws InvalidArgumentException if a template file is not found.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return string Mustache Template source
|
||||
*/
|
||||
private function loadFile($name)
|
||||
{
|
||||
$fileName = $this->getFileName($name);
|
||||
|
||||
if (!file_exists($fileName)) {
|
||||
throw new InvalidArgumentException('Template '.$name.' not found.');
|
||||
}
|
||||
if (!file_exists($fileName)) {
|
||||
throw new InvalidArgumentException('Template '.$name.' not found.');
|
||||
}
|
||||
|
||||
return file_get_contents($fileName);
|
||||
}
|
||||
return file_get_contents($fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for getting a Mustache template file name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return string Template file name
|
||||
*/
|
||||
private function getFileName($name) {
|
||||
$fileName = $this->baseDir . '/' . $name;
|
||||
if (substr($fileName, 0 - strlen($this->extension)) !== $this->extension) {
|
||||
$fileName .= $this->extension;
|
||||
}
|
||||
/**
|
||||
* Helper function for getting a Mustache template file name.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return string Template file name
|
||||
*/
|
||||
private function getFileName($name)
|
||||
{
|
||||
$fileName = $this->baseDir . '/' . $name;
|
||||
if (substr($fileName, 0 - strlen($this->extension)) !== $this->extension) {
|
||||
$fileName .= $this->extension;
|
||||
}
|
||||
|
||||
return $fileName;
|
||||
}
|
||||
return $fileName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,20 +12,21 @@
|
||||
/**
|
||||
* Mustache Template mutable Loader interface.
|
||||
*/
|
||||
interface Mustache_Loader_MutableLoader {
|
||||
interface Mustache_Loader_MutableLoader
|
||||
{
|
||||
|
||||
/**
|
||||
* Set an associative array of Template sources for this loader.
|
||||
*
|
||||
* @param array $templates
|
||||
*/
|
||||
function setTemplates(array $templates);
|
||||
/**
|
||||
* Set an associative array of Template sources for this loader.
|
||||
*
|
||||
* @param array $templates
|
||||
*/
|
||||
public function setTemplates(array $templates);
|
||||
|
||||
/**
|
||||
* Set a Template source by name.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $template Mustache Template source
|
||||
*/
|
||||
function setTemplate($name, $template);
|
||||
/**
|
||||
* Set a Template source by name.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $template Mustache Template source
|
||||
*/
|
||||
public function setTemplate($name, $template);
|
||||
}
|
||||
|
||||
@@ -25,16 +25,18 @@
|
||||
*
|
||||
* @implements Loader
|
||||
*/
|
||||
class Mustache_Loader_StringLoader implements Mustache_Loader {
|
||||
class Mustache_Loader_StringLoader implements Mustache_Loader
|
||||
{
|
||||
|
||||
/**
|
||||
* Load a Template by source.
|
||||
*
|
||||
* @param string $name Mustache Template source
|
||||
*
|
||||
* @return string Mustache Template source
|
||||
*/
|
||||
public function load($name) {
|
||||
return $name;
|
||||
}
|
||||
/**
|
||||
* Load a Template by source.
|
||||
*
|
||||
* @param string $name Mustache Template source
|
||||
*
|
||||
* @return string Mustache Template source
|
||||
*/
|
||||
public function load($name)
|
||||
{
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
|
||||
+59
-56
@@ -14,72 +14,75 @@
|
||||
*
|
||||
* This class is responsible for turning a set of Mustache tokens into a parse tree.
|
||||
*/
|
||||
class Mustache_Parser {
|
||||
class Mustache_Parser
|
||||
{
|
||||
|
||||
/**
|
||||
* Process an array of Mustache tokens and convert them into a parse tree.
|
||||
*
|
||||
* @param array $tokens Set of Mustache tokens
|
||||
*
|
||||
* @return array Mustache token parse tree
|
||||
*/
|
||||
public function parse(array $tokens = array()) {
|
||||
return $this->buildTree(new ArrayIterator($tokens));
|
||||
}
|
||||
/**
|
||||
* Process an array of Mustache tokens and convert them into a parse tree.
|
||||
*
|
||||
* @param array $tokens Set of Mustache tokens
|
||||
*
|
||||
* @return array Mustache token parse tree
|
||||
*/
|
||||
public function parse(array $tokens = array())
|
||||
{
|
||||
return $this->buildTree(new ArrayIterator($tokens));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for recursively building a parse tree.
|
||||
*
|
||||
* @throws LogicException when nesting errors or mismatched section tags are encountered.
|
||||
*
|
||||
* @param ArrayIterator $tokens Stream of Mustache tokens
|
||||
* @param array $parent Parent token (default: null)
|
||||
*
|
||||
* @return array Mustache Token parse tree
|
||||
*/
|
||||
private function buildTree(ArrayIterator $tokens, array $parent = null) {
|
||||
$nodes = array();
|
||||
/**
|
||||
* Helper method for recursively building a parse tree.
|
||||
*
|
||||
* @throws LogicException when nesting errors or mismatched section tags are encountered.
|
||||
*
|
||||
* @param ArrayIterator $tokens Stream of Mustache tokens
|
||||
* @param array $parent Parent token (default: null)
|
||||
*
|
||||
* @return array Mustache Token parse tree
|
||||
*/
|
||||
private function buildTree(ArrayIterator $tokens, array $parent = null)
|
||||
{
|
||||
$nodes = array();
|
||||
|
||||
do {
|
||||
$token = $tokens->current();
|
||||
$tokens->next();
|
||||
do {
|
||||
$token = $tokens->current();
|
||||
$tokens->next();
|
||||
|
||||
if ($token === null) {
|
||||
continue;
|
||||
} else {
|
||||
switch ($token[Mustache_Tokenizer::TYPE]) {
|
||||
case Mustache_Tokenizer::T_SECTION:
|
||||
case Mustache_Tokenizer::T_INVERTED:
|
||||
$nodes[] = $this->buildTree($tokens, $token);
|
||||
break;
|
||||
if ($token === null) {
|
||||
continue;
|
||||
} else {
|
||||
switch ($token[Mustache_Tokenizer::TYPE]) {
|
||||
case Mustache_Tokenizer::T_SECTION:
|
||||
case Mustache_Tokenizer::T_INVERTED:
|
||||
$nodes[] = $this->buildTree($tokens, $token);
|
||||
break;
|
||||
|
||||
case Mustache_Tokenizer::T_END_SECTION:
|
||||
if (!isset($parent)) {
|
||||
throw new LogicException('Unexpected closing tag: /'. $token[Mustache_Tokenizer::NAME]);
|
||||
}
|
||||
case Mustache_Tokenizer::T_END_SECTION:
|
||||
if (!isset($parent)) {
|
||||
throw new LogicException('Unexpected closing tag: /'. $token[Mustache_Tokenizer::NAME]);
|
||||
}
|
||||
|
||||
if ($token[Mustache_Tokenizer::NAME] !== $parent[Mustache_Tokenizer::NAME]) {
|
||||
throw new LogicException('Nesting error: ' . $parent[Mustache_Tokenizer::NAME] . ' vs. ' . $token[Mustache_Tokenizer::NAME]);
|
||||
}
|
||||
if ($token[Mustache_Tokenizer::NAME] !== $parent[Mustache_Tokenizer::NAME]) {
|
||||
throw new LogicException('Nesting error: ' . $parent[Mustache_Tokenizer::NAME] . ' vs. ' . $token[Mustache_Tokenizer::NAME]);
|
||||
}
|
||||
|
||||
$parent[Mustache_Tokenizer::END] = $token[Mustache_Tokenizer::INDEX];
|
||||
$parent[Mustache_Tokenizer::NODES] = $nodes;
|
||||
$parent[Mustache_Tokenizer::END] = $token[Mustache_Tokenizer::INDEX];
|
||||
$parent[Mustache_Tokenizer::NODES] = $nodes;
|
||||
|
||||
return $parent;
|
||||
break;
|
||||
return $parent;
|
||||
break;
|
||||
|
||||
default:
|
||||
$nodes[] = $token;
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
$nodes[] = $token;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} while ($tokens->valid());
|
||||
} while ($tokens->valid());
|
||||
|
||||
if (isset($parent)) {
|
||||
throw new LogicException('Missing closing tag: ' . $parent[Mustache_Tokenizer::NAME]);
|
||||
}
|
||||
if (isset($parent)) {
|
||||
throw new LogicException('Missing closing tag: ' . $parent[Mustache_Tokenizer::NAME]);
|
||||
}
|
||||
|
||||
return $nodes;
|
||||
}
|
||||
return $nodes;
|
||||
}
|
||||
}
|
||||
|
||||
+121
-115
@@ -14,130 +14,136 @@
|
||||
*
|
||||
* @abstract
|
||||
*/
|
||||
abstract class Mustache_Template {
|
||||
abstract class Mustache_Template
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Mustache_Engine
|
||||
*/
|
||||
protected $mustache;
|
||||
/**
|
||||
* @var Mustache_Engine
|
||||
*/
|
||||
protected $mustache;
|
||||
|
||||
/**
|
||||
* Mustache Template constructor.
|
||||
*
|
||||
* @param Mustache_Engine $mustache
|
||||
*/
|
||||
public function __construct(Mustache_Engine $mustache) {
|
||||
$this->mustache = $mustache;
|
||||
}
|
||||
/**
|
||||
* Mustache Template constructor.
|
||||
*
|
||||
* @param Mustache_Engine $mustache
|
||||
*/
|
||||
public function __construct(Mustache_Engine $mustache)
|
||||
{
|
||||
$this->mustache = $mustache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mustache Template instances can be treated as a function and rendered by simply calling them:
|
||||
*
|
||||
* $m = new Mustache_Engine;
|
||||
* $tpl = $m->loadTemplate('Hello, {{ name }}!');
|
||||
* echo $tpl(array('name' => 'World')); // "Hello, World!"
|
||||
*
|
||||
* @see Mustache_Template::render
|
||||
*
|
||||
* @param mixed $context Array or object rendering context (default: array())
|
||||
*
|
||||
* @return string Rendered template
|
||||
*/
|
||||
public function __invoke($context = array()) {
|
||||
return $this->render($context);
|
||||
}
|
||||
/**
|
||||
* Mustache Template instances can be treated as a function and rendered by simply calling them:
|
||||
*
|
||||
* $m = new Mustache_Engine;
|
||||
* $tpl = $m->loadTemplate('Hello, {{ name }}!');
|
||||
* echo $tpl(array('name' => 'World')); // "Hello, World!"
|
||||
*
|
||||
* @see Mustache_Template::render
|
||||
*
|
||||
* @param mixed $context Array or object rendering context (default: array())
|
||||
*
|
||||
* @return string Rendered template
|
||||
*/
|
||||
public function __invoke($context = array())
|
||||
{
|
||||
return $this->render($context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render this template given the rendering context.
|
||||
*
|
||||
* @param mixed $context Array or object rendering context (default: array())
|
||||
*
|
||||
* @return string Rendered template
|
||||
*/
|
||||
public function render($context = array()) {
|
||||
return $this->renderInternal($this->prepareContextStack($context));
|
||||
}
|
||||
/**
|
||||
* Render this template given the rendering context.
|
||||
*
|
||||
* @param mixed $context Array or object rendering context (default: array())
|
||||
*
|
||||
* @return string Rendered template
|
||||
*/
|
||||
public function render($context = array())
|
||||
{
|
||||
return $this->renderInternal($this->prepareContextStack($context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal rendering method implemented by Mustache Template concrete subclasses.
|
||||
*
|
||||
* This is where the magic happens :)
|
||||
*
|
||||
* @abstract
|
||||
*
|
||||
* @param Mustache_Context $context
|
||||
*
|
||||
* @return string Rendered template
|
||||
*/
|
||||
abstract public function renderInternal(Mustache_Context $context, $indent = '', $escape = false);
|
||||
/**
|
||||
* Internal rendering method implemented by Mustache Template concrete subclasses.
|
||||
*
|
||||
* This is where the magic happens :)
|
||||
*
|
||||
* @abstract
|
||||
*
|
||||
* @param Mustache_Context $context
|
||||
*
|
||||
* @return string Rendered template
|
||||
*/
|
||||
abstract public function renderInternal(Mustache_Context $context, $indent = '', $escape = false);
|
||||
|
||||
/**
|
||||
* Tests whether a value should be iterated over (e.g. in a section context).
|
||||
*
|
||||
* In most languages there are two distinct array types: list and hash (or whatever you want to call them). Lists
|
||||
* should be iterated, hashes should be treated as objects. Mustache follows this paradigm for Ruby, Javascript,
|
||||
* Java, Python, etc.
|
||||
*
|
||||
* PHP, however, treats lists and hashes as one primitive type: array. So Mustache.php needs a way to distinguish
|
||||
* between between a list of things (numeric, normalized array) and a set of variables to be used as section context
|
||||
* (associative array). In other words, this will be iterated over:
|
||||
*
|
||||
* $items = array(
|
||||
* array('name' => 'foo'),
|
||||
* array('name' => 'bar'),
|
||||
* array('name' => 'baz'),
|
||||
* );
|
||||
*
|
||||
* ... but this will be used as a section context block:
|
||||
*
|
||||
* $items = array(
|
||||
* 1 => array('name' => 'foo'),
|
||||
* 'banana' => array('name' => 'bar'),
|
||||
* 42 => array('name' => 'baz'),
|
||||
* );
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return boolean True if the value is 'iterable'
|
||||
*/
|
||||
protected function isIterable($value) {
|
||||
if (is_object($value)) {
|
||||
return $value instanceof Traversable;
|
||||
} elseif (is_array($value)) {
|
||||
$i = 0;
|
||||
foreach ($value as $k => $v) {
|
||||
if ($k !== $i++) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Tests whether a value should be iterated over (e.g. in a section context).
|
||||
*
|
||||
* In most languages there are two distinct array types: list and hash (or whatever you want to call them). Lists
|
||||
* should be iterated, hashes should be treated as objects. Mustache follows this paradigm for Ruby, Javascript,
|
||||
* Java, Python, etc.
|
||||
*
|
||||
* PHP, however, treats lists and hashes as one primitive type: array. So Mustache.php needs a way to distinguish
|
||||
* between between a list of things (numeric, normalized array) and a set of variables to be used as section context
|
||||
* (associative array). In other words, this will be iterated over:
|
||||
*
|
||||
* $items = array(
|
||||
* array('name' => 'foo'),
|
||||
* array('name' => 'bar'),
|
||||
* array('name' => 'baz'),
|
||||
* );
|
||||
*
|
||||
* ... but this will be used as a section context block:
|
||||
*
|
||||
* $items = array(
|
||||
* 1 => array('name' => 'foo'),
|
||||
* 'banana' => array('name' => 'bar'),
|
||||
* 42 => array('name' => 'baz'),
|
||||
* );
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return boolean True if the value is 'iterable'
|
||||
*/
|
||||
protected function isIterable($value)
|
||||
{
|
||||
if (is_object($value)) {
|
||||
return $value instanceof Traversable;
|
||||
} elseif (is_array($value)) {
|
||||
$i = 0;
|
||||
foreach ($value as $k => $v) {
|
||||
if ($k !== $i++) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to prepare the Context stack.
|
||||
*
|
||||
* Adds the Mustache HelperCollection to the stack's top context frame if helpers are present.
|
||||
*
|
||||
* @param mixed $context Optional first context frame (default: null)
|
||||
*
|
||||
* @return Mustache_Context
|
||||
*/
|
||||
protected function prepareContextStack($context = null) {
|
||||
$stack = new Mustache_Context;
|
||||
/**
|
||||
* Helper method to prepare the Context stack.
|
||||
*
|
||||
* Adds the Mustache HelperCollection to the stack's top context frame if helpers are present.
|
||||
*
|
||||
* @param mixed $context Optional first context frame (default: null)
|
||||
*
|
||||
* @return Mustache_Context
|
||||
*/
|
||||
protected function prepareContextStack($context = null)
|
||||
{
|
||||
$stack = new Mustache_Context;
|
||||
|
||||
$helpers = $this->mustache->getHelpers();
|
||||
if (!$helpers->isEmpty()) {
|
||||
$stack->push($helpers);
|
||||
}
|
||||
$helpers = $this->mustache->getHelpers();
|
||||
if (!$helpers->isEmpty()) {
|
||||
$stack->push($helpers);
|
||||
}
|
||||
|
||||
if (!empty($context)) {
|
||||
$stack->push($context);
|
||||
}
|
||||
if (!empty($context)) {
|
||||
$stack->push($context);
|
||||
}
|
||||
|
||||
return $stack;
|
||||
}
|
||||
return $stack;
|
||||
}
|
||||
}
|
||||
|
||||
+240
-233
@@ -16,263 +16,270 @@
|
||||
*/
|
||||
class Mustache_Tokenizer {
|
||||
|
||||
// Finite state machine states
|
||||
const IN_TEXT = 0;
|
||||
const IN_TAG_TYPE = 1;
|
||||
const IN_TAG = 2;
|
||||
// Finite state machine states
|
||||
const IN_TEXT = 0;
|
||||
const IN_TAG_TYPE = 1;
|
||||
const IN_TAG = 2;
|
||||
|
||||
// Token types
|
||||
const T_SECTION = '#';
|
||||
const T_INVERTED = '^';
|
||||
const T_END_SECTION = '/';
|
||||
const T_COMMENT = '!';
|
||||
const T_PARTIAL = '>';
|
||||
const T_PARTIAL_2 = '<';
|
||||
const T_DELIM_CHANGE = '=';
|
||||
const T_ESCAPED = '_v';
|
||||
const T_UNESCAPED = '{';
|
||||
const T_UNESCAPED_2 = '&';
|
||||
const T_TEXT = '_t';
|
||||
// Token types
|
||||
const T_SECTION = '#';
|
||||
const T_INVERTED = '^';
|
||||
const T_END_SECTION = '/';
|
||||
const T_COMMENT = '!';
|
||||
const T_PARTIAL = '>';
|
||||
const T_PARTIAL_2 = '<';
|
||||
const T_DELIM_CHANGE = '=';
|
||||
const T_ESCAPED = '_v';
|
||||
const T_UNESCAPED = '{';
|
||||
const T_UNESCAPED_2 = '&';
|
||||
const T_TEXT = '_t';
|
||||
|
||||
// Valid token types
|
||||
private static $tagTypes = array(
|
||||
self::T_SECTION => true,
|
||||
self::T_INVERTED => true,
|
||||
self::T_END_SECTION => true,
|
||||
self::T_COMMENT => true,
|
||||
self::T_PARTIAL => true,
|
||||
self::T_PARTIAL_2 => true,
|
||||
self::T_DELIM_CHANGE => true,
|
||||
self::T_ESCAPED => true,
|
||||
self::T_UNESCAPED => true,
|
||||
self::T_UNESCAPED_2 => true,
|
||||
);
|
||||
// Valid token types
|
||||
private static $tagTypes = array(
|
||||
self::T_SECTION => true,
|
||||
self::T_INVERTED => true,
|
||||
self::T_END_SECTION => true,
|
||||
self::T_COMMENT => true,
|
||||
self::T_PARTIAL => true,
|
||||
self::T_PARTIAL_2 => true,
|
||||
self::T_DELIM_CHANGE => true,
|
||||
self::T_ESCAPED => true,
|
||||
self::T_UNESCAPED => true,
|
||||
self::T_UNESCAPED_2 => true,
|
||||
);
|
||||
|
||||
// Interpolated tags
|
||||
private static $interpolatedTags = array(
|
||||
self::T_ESCAPED => true,
|
||||
self::T_UNESCAPED => true,
|
||||
self::T_UNESCAPED_2 => true,
|
||||
);
|
||||
// Interpolated tags
|
||||
private static $interpolatedTags = array(
|
||||
self::T_ESCAPED => true,
|
||||
self::T_UNESCAPED => true,
|
||||
self::T_UNESCAPED_2 => true,
|
||||
);
|
||||
|
||||
// Token properties
|
||||
const TYPE = 'type';
|
||||
const NAME = 'name';
|
||||
const OTAG = 'otag';
|
||||
const CTAG = 'ctag';
|
||||
const INDEX = 'index';
|
||||
const END = 'end';
|
||||
const INDENT = 'indent';
|
||||
const NODES = 'nodes';
|
||||
const VALUE = 'value';
|
||||
// Token properties
|
||||
const TYPE = 'type';
|
||||
const NAME = 'name';
|
||||
const OTAG = 'otag';
|
||||
const CTAG = 'ctag';
|
||||
const INDEX = 'index';
|
||||
const END = 'end';
|
||||
const INDENT = 'indent';
|
||||
const NODES = 'nodes';
|
||||
const VALUE = 'value';
|
||||
|
||||
private $state;
|
||||
private $tagType;
|
||||
private $tag;
|
||||
private $buffer;
|
||||
private $tokens;
|
||||
private $seenTag;
|
||||
private $lineStart;
|
||||
private $otag;
|
||||
private $ctag;
|
||||
private $state;
|
||||
private $tagType;
|
||||
private $tag;
|
||||
private $buffer;
|
||||
private $tokens;
|
||||
private $seenTag;
|
||||
private $lineStart;
|
||||
private $otag;
|
||||
private $ctag;
|
||||
|
||||
/**
|
||||
* Scan and tokenize template source.
|
||||
*
|
||||
* @param string $text Mustache template source to tokenize
|
||||
* @param string $delimiters Optionally, pass initial opening and closing delimiters (default: null)
|
||||
*
|
||||
* @return array Set of Mustache tokens
|
||||
*/
|
||||
public function scan($text, $delimiters = null) {
|
||||
$this->reset();
|
||||
/**
|
||||
* Scan and tokenize template source.
|
||||
*
|
||||
* @param string $text Mustache template source to tokenize
|
||||
* @param string $delimiters Optionally, pass initial opening and closing delimiters (default: null)
|
||||
*
|
||||
* @return array Set of Mustache tokens
|
||||
*/
|
||||
public function scan($text, $delimiters = null)
|
||||
{
|
||||
$this->reset();
|
||||
|
||||
if ($delimiters = trim($delimiters)) {
|
||||
list($otag, $ctag) = explode(' ', $delimiters);
|
||||
$this->otag = $otag;
|
||||
$this->ctag = $ctag;
|
||||
}
|
||||
if ($delimiters = trim($delimiters)) {
|
||||
list($otag, $ctag) = explode(' ', $delimiters);
|
||||
$this->otag = $otag;
|
||||
$this->ctag = $ctag;
|
||||
}
|
||||
|
||||
$len = strlen($text);
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
switch ($this->state) {
|
||||
case self::IN_TEXT:
|
||||
if ($this->tagChange($this->otag, $text, $i)) {
|
||||
$i--;
|
||||
$this->flushBuffer();
|
||||
$this->state = self::IN_TAG_TYPE;
|
||||
} else {
|
||||
if ($text[$i] == "\n") {
|
||||
$this->filterLine();
|
||||
} else {
|
||||
$this->buffer .= $text[$i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
$len = strlen($text);
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
switch ($this->state) {
|
||||
case self::IN_TEXT:
|
||||
if ($this->tagChange($this->otag, $text, $i)) {
|
||||
$i--;
|
||||
$this->flushBuffer();
|
||||
$this->state = self::IN_TAG_TYPE;
|
||||
} else {
|
||||
if ($text[$i] == "\n") {
|
||||
$this->filterLine();
|
||||
} else {
|
||||
$this->buffer .= $text[$i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case self::IN_TAG_TYPE:
|
||||
case self::IN_TAG_TYPE:
|
||||
|
||||
$i += strlen($this->otag) - 1;
|
||||
if (isset(self::$tagTypes[$text[$i + 1]])) {
|
||||
$tag = $text[$i + 1];
|
||||
$this->tagType = $tag;
|
||||
} else {
|
||||
$tag = null;
|
||||
$this->tagType = self::T_ESCAPED;
|
||||
}
|
||||
$i += strlen($this->otag) - 1;
|
||||
if (isset(self::$tagTypes[$text[$i + 1]])) {
|
||||
$tag = $text[$i + 1];
|
||||
$this->tagType = $tag;
|
||||
} else {
|
||||
$tag = null;
|
||||
$this->tagType = self::T_ESCAPED;
|
||||
}
|
||||
|
||||
if ($this->tagType === self::T_DELIM_CHANGE) {
|
||||
$i = $this->changeDelimiters($text, $i);
|
||||
$this->state = self::IN_TEXT;
|
||||
} else {
|
||||
if ($tag !== null) {
|
||||
$i++;
|
||||
}
|
||||
$this->state = self::IN_TAG;
|
||||
}
|
||||
$this->seenTag = $i;
|
||||
break;
|
||||
if ($this->tagType === self::T_DELIM_CHANGE) {
|
||||
$i = $this->changeDelimiters($text, $i);
|
||||
$this->state = self::IN_TEXT;
|
||||
} else {
|
||||
if ($tag !== null) {
|
||||
$i++;
|
||||
}
|
||||
$this->state = self::IN_TAG;
|
||||
}
|
||||
$this->seenTag = $i;
|
||||
break;
|
||||
|
||||
default:
|
||||
if ($this->tagChange($this->ctag, $text, $i)) {
|
||||
$this->tokens[] = array(
|
||||
self::TYPE => $this->tagType,
|
||||
self::NAME => trim($this->buffer),
|
||||
self::OTAG => $this->otag,
|
||||
self::CTAG => $this->ctag,
|
||||
self::INDEX => ($this->tagType == self::T_END_SECTION) ? $this->seenTag - strlen($this->otag) : $i + strlen($this->ctag)
|
||||
);
|
||||
default:
|
||||
if ($this->tagChange($this->ctag, $text, $i)) {
|
||||
$this->tokens[] = array(
|
||||
self::TYPE => $this->tagType,
|
||||
self::NAME => trim($this->buffer),
|
||||
self::OTAG => $this->otag,
|
||||
self::CTAG => $this->ctag,
|
||||
self::INDEX => ($this->tagType == self::T_END_SECTION) ? $this->seenTag - strlen($this->otag) : $i + strlen($this->ctag)
|
||||
);
|
||||
|
||||
$this->buffer = '';
|
||||
$i += strlen($this->ctag) - 1;
|
||||
$this->state = self::IN_TEXT;
|
||||
if ($this->tagType == self::T_UNESCAPED) {
|
||||
if ($this->ctag == '}}') {
|
||||
$i++;
|
||||
} else {
|
||||
// Clean up `{{{ tripleStache }}}` style tokens.
|
||||
$lastName = $this->tokens[count($this->tokens) - 1][self::NAME];
|
||||
if (substr($lastName, -1) === '}') {
|
||||
$this->tokens[count($this->tokens) - 1][self::NAME] = trim(substr($lastName, 0, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->buffer .= $text[$i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->buffer = '';
|
||||
$i += strlen($this->ctag) - 1;
|
||||
$this->state = self::IN_TEXT;
|
||||
if ($this->tagType == self::T_UNESCAPED) {
|
||||
if ($this->ctag == '}}') {
|
||||
$i++;
|
||||
} else {
|
||||
// Clean up `{{{ tripleStache }}}` style tokens.
|
||||
$lastName = $this->tokens[count($this->tokens) - 1][self::NAME];
|
||||
if (substr($lastName, -1) === '}') {
|
||||
$this->tokens[count($this->tokens) - 1][self::NAME] = trim(substr($lastName, 0, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->buffer .= $text[$i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->filterLine(true);
|
||||
$this->filterLine(true);
|
||||
|
||||
return $this->tokens;
|
||||
}
|
||||
return $this->tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to reset tokenizer internal state.
|
||||
*/
|
||||
private function reset() {
|
||||
$this->state = self::IN_TEXT;
|
||||
$this->tagType = null;
|
||||
$this->tag = null;
|
||||
$this->buffer = '';
|
||||
$this->tokens = array();
|
||||
$this->seenTag = false;
|
||||
$this->lineStart = 0;
|
||||
$this->otag = '{{';
|
||||
$this->ctag = '}}';
|
||||
}
|
||||
/**
|
||||
* Helper function to reset tokenizer internal state.
|
||||
*/
|
||||
private function reset()
|
||||
{
|
||||
$this->state = self::IN_TEXT;
|
||||
$this->tagType = null;
|
||||
$this->tag = null;
|
||||
$this->buffer = '';
|
||||
$this->tokens = array();
|
||||
$this->seenTag = false;
|
||||
$this->lineStart = 0;
|
||||
$this->otag = '{{';
|
||||
$this->ctag = '}}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the current buffer to a token.
|
||||
*/
|
||||
private function flushBuffer() {
|
||||
if (!empty($this->buffer)) {
|
||||
$this->tokens[] = array(self::TYPE => self::T_TEXT, self::VALUE => $this->buffer);
|
||||
$this->buffer = '';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Flush the current buffer to a token.
|
||||
*/
|
||||
private function flushBuffer()
|
||||
{
|
||||
if (!empty($this->buffer)) {
|
||||
$this->tokens[] = array(self::TYPE => self::T_TEXT, self::VALUE => $this->buffer);
|
||||
$this->buffer = '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the current line is entirely made up of whitespace.
|
||||
*
|
||||
* @return boolean True if the current line is all whitespace
|
||||
*/
|
||||
private function lineIsWhitespace() {
|
||||
$tokensCount = count($this->tokens);
|
||||
for ($j = $this->lineStart; $j < $tokensCount; $j++) {
|
||||
$token = $this->tokens[$j];
|
||||
if (isset(self::$tagTypes[$token[self::TYPE]])) {
|
||||
if (isset(self::$interpolatedTags[$token[self::TYPE]])) {
|
||||
return false;
|
||||
}
|
||||
} elseif ($token[self::TYPE] == self::T_TEXT) {
|
||||
if (preg_match('/\S/', $token[self::VALUE])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Test whether the current line is entirely made up of whitespace.
|
||||
*
|
||||
* @return boolean True if the current line is all whitespace
|
||||
*/
|
||||
private function lineIsWhitespace()
|
||||
{
|
||||
$tokensCount = count($this->tokens);
|
||||
for ($j = $this->lineStart; $j < $tokensCount; $j++) {
|
||||
$token = $this->tokens[$j];
|
||||
if (isset(self::$tagTypes[$token[self::TYPE]])) {
|
||||
if (isset(self::$interpolatedTags[$token[self::TYPE]])) {
|
||||
return false;
|
||||
}
|
||||
} elseif ($token[self::TYPE] == self::T_TEXT) {
|
||||
if (preg_match('/\S/', $token[self::VALUE])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter out whitespace-only lines and store indent levels for partials.
|
||||
*
|
||||
* @param bool $noNewLine Suppress the newline? (default: false)
|
||||
*/
|
||||
private function filterLine($noNewLine = false) {
|
||||
$this->flushBuffer();
|
||||
if ($this->seenTag && $this->lineIsWhitespace()) {
|
||||
$tokensCount = count($this->tokens);
|
||||
for ($j = $this->lineStart; $j < $tokensCount; $j++) {
|
||||
if ($this->tokens[$j][self::TYPE] == self::T_TEXT) {
|
||||
if (isset($this->tokens[$j+1]) && $this->tokens[$j+1][self::TYPE] == self::T_PARTIAL) {
|
||||
$this->tokens[$j+1][self::INDENT] = $this->tokens[$j][self::VALUE];
|
||||
}
|
||||
/**
|
||||
* Filter out whitespace-only lines and store indent levels for partials.
|
||||
*
|
||||
* @param bool $noNewLine Suppress the newline? (default: false)
|
||||
*/
|
||||
private function filterLine($noNewLine = false)
|
||||
{
|
||||
$this->flushBuffer();
|
||||
if ($this->seenTag && $this->lineIsWhitespace()) {
|
||||
$tokensCount = count($this->tokens);
|
||||
for ($j = $this->lineStart; $j < $tokensCount; $j++) {
|
||||
if ($this->tokens[$j][self::TYPE] == self::T_TEXT) {
|
||||
if (isset($this->tokens[$j+1]) && $this->tokens[$j+1][self::TYPE] == self::T_PARTIAL) {
|
||||
$this->tokens[$j+1][self::INDENT] = $this->tokens[$j][self::VALUE];
|
||||
}
|
||||
|
||||
$this->tokens[$j] = null;
|
||||
}
|
||||
}
|
||||
} elseif (!$noNewLine) {
|
||||
$this->tokens[] = array(self::TYPE => self::T_TEXT, self::VALUE => "\n");
|
||||
}
|
||||
$this->tokens[$j] = null;
|
||||
}
|
||||
}
|
||||
} elseif (!$noNewLine) {
|
||||
$this->tokens[] = array(self::TYPE => self::T_TEXT, self::VALUE => "\n");
|
||||
}
|
||||
|
||||
$this->seenTag = false;
|
||||
$this->lineStart = count($this->tokens);
|
||||
}
|
||||
$this->seenTag = false;
|
||||
$this->lineStart = count($this->tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the current Mustache delimiters. Set new `otag` and `ctag` values.
|
||||
*
|
||||
* @param string $text Mustache template source
|
||||
* @param int $index Current tokenizer index
|
||||
*
|
||||
* @return int New index value
|
||||
*/
|
||||
private function changeDelimiters($text, $index) {
|
||||
$startIndex = strpos($text, '=', $index) + 1;
|
||||
$close = '='.$this->ctag;
|
||||
$closeIndex = strpos($text, $close, $index);
|
||||
/**
|
||||
* Change the current Mustache delimiters. Set new `otag` and `ctag` values.
|
||||
*
|
||||
* @param string $text Mustache template source
|
||||
* @param int $index Current tokenizer index
|
||||
*
|
||||
* @return int New index value
|
||||
*/
|
||||
private function changeDelimiters($text, $index)
|
||||
{
|
||||
$startIndex = strpos($text, '=', $index) + 1;
|
||||
$close = '='.$this->ctag;
|
||||
$closeIndex = strpos($text, $close, $index);
|
||||
|
||||
list($otag, $ctag) = explode(' ', trim(substr($text, $startIndex, $closeIndex - $startIndex)));
|
||||
$this->otag = $otag;
|
||||
$this->ctag = $ctag;
|
||||
list($otag, $ctag) = explode(' ', trim(substr($text, $startIndex, $closeIndex - $startIndex)));
|
||||
$this->otag = $otag;
|
||||
$this->ctag = $ctag;
|
||||
|
||||
return $closeIndex + strlen($close) - 1;
|
||||
}
|
||||
return $closeIndex + strlen($close) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether it's time to change tags.
|
||||
*
|
||||
* @param string $tag Current tag name
|
||||
* @param string $text Mustache template source
|
||||
* @param int $index Current tokenizer index
|
||||
*
|
||||
* @return boolean True if this is a closing section tag
|
||||
*/
|
||||
private function tagChange($tag, $text, $index) {
|
||||
return substr($text, $index, strlen($tag)) === $tag;
|
||||
}
|
||||
/**
|
||||
* Test whether it's time to change tags.
|
||||
*
|
||||
* @param string $tag Current tag name
|
||||
* @param string $text Mustache template source
|
||||
* @param int $index Current tokenizer index
|
||||
*
|
||||
* @return boolean True if this is a closing section tag
|
||||
*/
|
||||
private function tagChange($tag, $text, $index)
|
||||
{
|
||||
return substr($text, $index, strlen($tag)) === $tag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,22 +12,25 @@
|
||||
/**
|
||||
* @group unit
|
||||
*/
|
||||
class Mustache_Test_AutoloaderTest extends PHPUnit_Framework_TestCase {
|
||||
public function testRegister() {
|
||||
$loader = Mustache_Autoloader::register();
|
||||
$this->assertTrue(spl_autoload_unregister(array($loader, 'autoload')));
|
||||
}
|
||||
class Mustache_Test_AutoloaderTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testRegister()
|
||||
{
|
||||
$loader = Mustache_Autoloader::register();
|
||||
$this->assertTrue(spl_autoload_unregister(array($loader, 'autoload')));
|
||||
}
|
||||
|
||||
public function testAutoloader() {
|
||||
$loader = new Mustache_Autoloader(dirname(__FILE__).'/../../fixtures/autoloader');
|
||||
public function testAutoloader()
|
||||
{
|
||||
$loader = new Mustache_Autoloader(dirname(__FILE__).'/../../fixtures/autoloader');
|
||||
|
||||
$this->assertNull($loader->autoload('NonMustacheClass'));
|
||||
$this->assertFalse(class_exists('NonMustacheClass'));
|
||||
$this->assertNull($loader->autoload('NonMustacheClass'));
|
||||
$this->assertFalse(class_exists('NonMustacheClass'));
|
||||
|
||||
$loader->autoload('Mustache_Foo');
|
||||
$this->assertTrue(class_exists('Mustache_Foo'));
|
||||
$loader->autoload('Mustache_Foo');
|
||||
$this->assertTrue(class_exists('Mustache_Foo'));
|
||||
|
||||
$loader->autoload('\Mustache_Bar');
|
||||
$this->assertTrue(class_exists('Mustache_Bar'));
|
||||
}
|
||||
$loader->autoload('\Mustache_Bar');
|
||||
$this->assertTrue(class_exists('Mustache_Bar'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,87 +12,92 @@
|
||||
/**
|
||||
* @group unit
|
||||
*/
|
||||
class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase {
|
||||
class Mustache_Test_CompilerTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @dataProvider getCompileValues
|
||||
*/
|
||||
public function testCompile($source, array $tree, $name, $customEscaper, $charset, $expected) {
|
||||
$compiler = new Mustache_Compiler;
|
||||
/**
|
||||
* @dataProvider getCompileValues
|
||||
*/
|
||||
public function testCompile($source, array $tree, $name, $customEscaper, $charset, $expected)
|
||||
{
|
||||
$compiler = new Mustache_Compiler;
|
||||
|
||||
$compiled = $compiler->compile($source, $tree, $name, $customEscaper, $charset);
|
||||
foreach ($expected as $contains) {
|
||||
$this->assertContains($contains, $compiled);
|
||||
}
|
||||
}
|
||||
$compiled = $compiler->compile($source, $tree, $name, $customEscaper, $charset);
|
||||
foreach ($expected as $contains) {
|
||||
$this->assertContains($contains, $compiled);
|
||||
}
|
||||
}
|
||||
|
||||
public function getCompileValues() {
|
||||
return array(
|
||||
array('', array(), 'Banana', false, 'ISO-8859-1', array(
|
||||
"\nclass Banana extends Mustache_Template",
|
||||
'return htmlspecialchars($buffer, ENT_COMPAT, \'ISO-8859-1\');',
|
||||
'return $buffer;',
|
||||
)),
|
||||
public function getCompileValues()
|
||||
{
|
||||
return array(
|
||||
array('', array(), 'Banana', false, 'ISO-8859-1', array(
|
||||
"\nclass Banana extends Mustache_Template",
|
||||
'return htmlspecialchars($buffer, ENT_COMPAT, \'ISO-8859-1\');',
|
||||
'return $buffer;',
|
||||
)),
|
||||
|
||||
array('', array($this->createTextToken('TEXT')), 'Monkey', false, 'UTF-8', array(
|
||||
"\nclass Monkey extends Mustache_Template",
|
||||
'return htmlspecialchars($buffer, ENT_COMPAT, \'UTF-8\');',
|
||||
'$buffer .= $indent . \'TEXT\';',
|
||||
'return $buffer;',
|
||||
)),
|
||||
array('', array($this->createTextToken('TEXT')), 'Monkey', false, 'UTF-8', array(
|
||||
"\nclass Monkey extends Mustache_Template",
|
||||
'return htmlspecialchars($buffer, ENT_COMPAT, \'UTF-8\');',
|
||||
'$buffer .= $indent . \'TEXT\';',
|
||||
'return $buffer;',
|
||||
)),
|
||||
|
||||
array('', array($this->createTextToken('TEXT')), 'Monkey', true, 'ISO-8859-1', array(
|
||||
"\nclass Monkey extends Mustache_Template",
|
||||
'$buffer .= $indent . \'TEXT\';',
|
||||
'return call_user_func($this->mustache->getEscape(), $buffer);',
|
||||
'return $buffer;',
|
||||
)),
|
||||
array('', array($this->createTextToken('TEXT')), 'Monkey', true, 'ISO-8859-1', array(
|
||||
"\nclass Monkey extends Mustache_Template",
|
||||
'$buffer .= $indent . \'TEXT\';',
|
||||
'return call_user_func($this->mustache->getEscape(), $buffer);',
|
||||
'return $buffer;',
|
||||
)),
|
||||
|
||||
array(
|
||||
'',
|
||||
array(
|
||||
$this->createTextToken('foo'),
|
||||
$this->createTextToken("\n"),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'name',
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => '.',
|
||||
),
|
||||
$this->createTextToken("'bar'"),
|
||||
),
|
||||
'Monkey',
|
||||
false,
|
||||
'UTF-8',
|
||||
array(
|
||||
"\nclass Monkey extends Mustache_Template",
|
||||
'$buffer .= $indent . \'foo\'',
|
||||
'$buffer .= "\n"',
|
||||
'$value = $context->find(\'name\');',
|
||||
'$buffer .= htmlspecialchars($value, ENT_COMPAT, \'UTF-8\');',
|
||||
'$value = $context->last();',
|
||||
'$buffer .= \'\\\'bar\\\'\';',
|
||||
'return htmlspecialchars($buffer, ENT_COMPAT, \'UTF-8\');',
|
||||
'return $buffer;',
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
array(
|
||||
'',
|
||||
array(
|
||||
$this->createTextToken('foo'),
|
||||
$this->createTextToken("\n"),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'name',
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => '.',
|
||||
),
|
||||
$this->createTextToken("'bar'"),
|
||||
),
|
||||
'Monkey',
|
||||
false,
|
||||
'UTF-8',
|
||||
array(
|
||||
"\nclass Monkey extends Mustache_Template",
|
||||
'$buffer .= $indent . \'foo\'',
|
||||
'$buffer .= "\n"',
|
||||
'$value = $context->find(\'name\');',
|
||||
'$buffer .= htmlspecialchars($value, ENT_COMPAT, \'UTF-8\');',
|
||||
'$value = $context->last();',
|
||||
'$buffer .= \'\\\'bar\\\'\';',
|
||||
'return htmlspecialchars($buffer, ENT_COMPAT, \'UTF-8\');',
|
||||
'return $buffer;',
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
public function testCompilerThrowsUnknownNodeTypeException() {
|
||||
$compiler = new Mustache_Compiler;
|
||||
$compiler->compile('', array(array(Mustache_Tokenizer::TYPE => 'invalid')), 'SomeClass');
|
||||
}
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
public function testCompilerThrowsUnknownNodeTypeException()
|
||||
{
|
||||
$compiler = new Mustache_Compiler;
|
||||
$compiler->compile('', array(array(Mustache_Tokenizer::TYPE => 'invalid')), 'SomeClass');
|
||||
}
|
||||
|
||||
private function createTextToken($value) {
|
||||
return array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => $value,
|
||||
);
|
||||
}
|
||||
private function createTextToken($value)
|
||||
{
|
||||
return array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => $value,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,100 +12,108 @@
|
||||
/**
|
||||
* @group unit
|
||||
*/
|
||||
class Mustache_Test_ContextTest extends PHPUnit_Framework_TestCase {
|
||||
public function testConstructor() {
|
||||
$one = new Mustache_Context;
|
||||
$this->assertSame('', $one->find('foo'));
|
||||
$this->assertSame('', $one->find('bar'));
|
||||
class Mustache_Test_ContextTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testConstructor()
|
||||
{
|
||||
$one = new Mustache_Context;
|
||||
$this->assertSame('', $one->find('foo'));
|
||||
$this->assertSame('', $one->find('bar'));
|
||||
|
||||
$two = new Mustache_Context(array(
|
||||
'foo' => 'FOO',
|
||||
'bar' => '<BAR>'
|
||||
));
|
||||
$this->assertEquals('FOO', $two->find('foo'));
|
||||
$this->assertEquals('<BAR>', $two->find('bar'));
|
||||
$two = new Mustache_Context(array(
|
||||
'foo' => 'FOO',
|
||||
'bar' => '<BAR>'
|
||||
));
|
||||
$this->assertEquals('FOO', $two->find('foo'));
|
||||
$this->assertEquals('<BAR>', $two->find('bar'));
|
||||
|
||||
$obj = new StdClass;
|
||||
$obj->name = 'NAME';
|
||||
$three = new Mustache_Context($obj);
|
||||
$this->assertSame($obj, $three->last());
|
||||
$this->assertEquals('NAME', $three->find('name'));
|
||||
}
|
||||
$obj = new StdClass;
|
||||
$obj->name = 'NAME';
|
||||
$three = new Mustache_Context($obj);
|
||||
$this->assertSame($obj, $three->last());
|
||||
$this->assertEquals('NAME', $three->find('name'));
|
||||
}
|
||||
|
||||
public function testPushPopAndLast() {
|
||||
$context = new Mustache_Context;
|
||||
$this->assertFalse($context->last());
|
||||
public function testPushPopAndLast()
|
||||
{
|
||||
$context = new Mustache_Context;
|
||||
$this->assertFalse($context->last());
|
||||
|
||||
$dummy = new Mustache_Test_TestDummy;
|
||||
$context->push($dummy);
|
||||
$this->assertSame($dummy, $context->last());
|
||||
$this->assertSame($dummy, $context->pop());
|
||||
$this->assertFalse($context->last());
|
||||
$dummy = new Mustache_Test_TestDummy;
|
||||
$context->push($dummy);
|
||||
$this->assertSame($dummy, $context->last());
|
||||
$this->assertSame($dummy, $context->pop());
|
||||
$this->assertFalse($context->last());
|
||||
|
||||
$obj = new StdClass;
|
||||
$context->push($dummy);
|
||||
$this->assertSame($dummy, $context->last());
|
||||
$context->push($obj);
|
||||
$this->assertSame($obj, $context->last());
|
||||
$this->assertSame($obj, $context->pop());
|
||||
$this->assertSame($dummy, $context->pop());
|
||||
$this->assertFalse($context->last());
|
||||
}
|
||||
$obj = new StdClass;
|
||||
$context->push($dummy);
|
||||
$this->assertSame($dummy, $context->last());
|
||||
$context->push($obj);
|
||||
$this->assertSame($obj, $context->last());
|
||||
$this->assertSame($obj, $context->pop());
|
||||
$this->assertSame($dummy, $context->pop());
|
||||
$this->assertFalse($context->last());
|
||||
}
|
||||
|
||||
public function testFind() {
|
||||
$context = new Mustache_Context;
|
||||
public function testFind()
|
||||
{
|
||||
$context = new Mustache_Context;
|
||||
|
||||
$dummy = new Mustache_Test_TestDummy;
|
||||
$dummy = new Mustache_Test_TestDummy;
|
||||
|
||||
$obj = new StdClass;
|
||||
$obj->name = 'obj';
|
||||
$obj = new StdClass;
|
||||
$obj->name = 'obj';
|
||||
|
||||
$arr = array(
|
||||
'a' => array('b' => array('c' => 'see')),
|
||||
'b' => 'bee',
|
||||
);
|
||||
$arr = array(
|
||||
'a' => array('b' => array('c' => 'see')),
|
||||
'b' => 'bee',
|
||||
);
|
||||
|
||||
$string = 'some arbitrary string';
|
||||
$string = 'some arbitrary string';
|
||||
|
||||
$context->push($dummy);
|
||||
$this->assertEquals('dummy', $context->find('name'));
|
||||
$context->push($dummy);
|
||||
$this->assertEquals('dummy', $context->find('name'));
|
||||
|
||||
$context->push($obj);
|
||||
$this->assertEquals('obj', $context->find('name'));
|
||||
$context->push($obj);
|
||||
$this->assertEquals('obj', $context->find('name'));
|
||||
|
||||
$context->pop();
|
||||
$this->assertEquals('dummy', $context->find('name'));
|
||||
$context->pop();
|
||||
$this->assertEquals('dummy', $context->find('name'));
|
||||
|
||||
$dummy->name = 'dummyer';
|
||||
$this->assertEquals('dummyer', $context->find('name'));
|
||||
$dummy->name = 'dummyer';
|
||||
$this->assertEquals('dummyer', $context->find('name'));
|
||||
|
||||
$context->push($arr);
|
||||
$this->assertEquals('bee', $context->find('b'));
|
||||
$this->assertEquals('see', $context->findDot('a.b.c'));
|
||||
$context->push($arr);
|
||||
$this->assertEquals('bee', $context->find('b'));
|
||||
$this->assertEquals('see', $context->findDot('a.b.c'));
|
||||
|
||||
$dummy->name = 'dummy';
|
||||
$dummy->name = 'dummy';
|
||||
|
||||
$context->push($string);
|
||||
$this->assertSame($string, $context->last());
|
||||
$this->assertEquals('dummy', $context->find('name'));
|
||||
$this->assertEquals('see', $context->findDot('a.b.c'));
|
||||
$this->assertEquals('<foo>', $context->find('foo'));
|
||||
$this->assertEquals('<bar>', $context->findDot('bar'));
|
||||
}
|
||||
$context->push($string);
|
||||
$this->assertSame($string, $context->last());
|
||||
$this->assertEquals('dummy', $context->find('name'));
|
||||
$this->assertEquals('see', $context->findDot('a.b.c'));
|
||||
$this->assertEquals('<foo>', $context->find('foo'));
|
||||
$this->assertEquals('<bar>', $context->findDot('bar'));
|
||||
}
|
||||
}
|
||||
|
||||
class Mustache_Test_TestDummy {
|
||||
public $name = 'dummy';
|
||||
class Mustache_Test_TestDummy
|
||||
{
|
||||
public $name = 'dummy';
|
||||
|
||||
public function __invoke() {
|
||||
// nothing
|
||||
}
|
||||
public function __invoke()
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
|
||||
public static function foo() {
|
||||
return '<foo>';
|
||||
}
|
||||
public static function foo()
|
||||
{
|
||||
return '<foo>';
|
||||
}
|
||||
|
||||
public function bar() {
|
||||
return '<bar>';
|
||||
}
|
||||
public function bar()
|
||||
{
|
||||
return '<bar>';
|
||||
}
|
||||
}
|
||||
|
||||
+202
-186
@@ -12,229 +12,245 @@
|
||||
/**
|
||||
* @group unit
|
||||
*/
|
||||
class Mustache_Test_EngineTest extends PHPUnit_Framework_TestCase {
|
||||
class Mustache_Test_EngineTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
private static $tempDir;
|
||||
private static $tempDir;
|
||||
|
||||
public static function setUpBeforeClass() {
|
||||
self::$tempDir = sys_get_temp_dir() . '/mustache_test';
|
||||
if (file_exists(self::$tempDir)) {
|
||||
self::rmdir(self::$tempDir);
|
||||
}
|
||||
}
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
self::$tempDir = sys_get_temp_dir() . '/mustache_test';
|
||||
if (file_exists(self::$tempDir)) {
|
||||
self::rmdir(self::$tempDir);
|
||||
}
|
||||
}
|
||||
|
||||
public function testConstructor() {
|
||||
$loader = new Mustache_Loader_StringLoader;
|
||||
$partialsLoader = new Mustache_Loader_ArrayLoader;
|
||||
$mustache = new Mustache_Engine(array(
|
||||
'template_class_prefix' => '__whot__',
|
||||
'cache' => self::$tempDir,
|
||||
'loader' => $loader,
|
||||
'partials_loader' => $partialsLoader,
|
||||
'partials' => array(
|
||||
'foo' => '{{ foo }}',
|
||||
),
|
||||
'helpers' => array(
|
||||
'foo' => array($this, 'getFoo'),
|
||||
'bar' => 'BAR',
|
||||
),
|
||||
'escape' => 'strtoupper',
|
||||
'charset' => 'ISO-8859-1',
|
||||
));
|
||||
public function testConstructor()
|
||||
{
|
||||
$loader = new Mustache_Loader_StringLoader;
|
||||
$partialsLoader = new Mustache_Loader_ArrayLoader;
|
||||
$mustache = new Mustache_Engine(array(
|
||||
'template_class_prefix' => '__whot__',
|
||||
'cache' => self::$tempDir,
|
||||
'loader' => $loader,
|
||||
'partials_loader' => $partialsLoader,
|
||||
'partials' => array(
|
||||
'foo' => '{{ foo }}',
|
||||
),
|
||||
'helpers' => array(
|
||||
'foo' => array($this, 'getFoo'),
|
||||
'bar' => 'BAR',
|
||||
),
|
||||
'escape' => 'strtoupper',
|
||||
'charset' => 'ISO-8859-1',
|
||||
));
|
||||
|
||||
$this->assertSame($loader, $mustache->getLoader());
|
||||
$this->assertSame($partialsLoader, $mustache->getPartialsLoader());
|
||||
$this->assertEquals('{{ foo }}', $partialsLoader->load('foo'));
|
||||
$this->assertContains('__whot__', $mustache->getTemplateClassName('{{ foo }}'));
|
||||
$this->assertEquals('strtoupper', $mustache->getEscape());
|
||||
$this->assertEquals('ISO-8859-1', $mustache->getCharset());
|
||||
$this->assertTrue($mustache->hasHelper('foo'));
|
||||
$this->assertTrue($mustache->hasHelper('bar'));
|
||||
$this->assertFalse($mustache->hasHelper('baz'));
|
||||
}
|
||||
$this->assertSame($loader, $mustache->getLoader());
|
||||
$this->assertSame($partialsLoader, $mustache->getPartialsLoader());
|
||||
$this->assertEquals('{{ foo }}', $partialsLoader->load('foo'));
|
||||
$this->assertContains('__whot__', $mustache->getTemplateClassName('{{ foo }}'));
|
||||
$this->assertEquals('strtoupper', $mustache->getEscape());
|
||||
$this->assertEquals('ISO-8859-1', $mustache->getCharset());
|
||||
$this->assertTrue($mustache->hasHelper('foo'));
|
||||
$this->assertTrue($mustache->hasHelper('bar'));
|
||||
$this->assertFalse($mustache->hasHelper('baz'));
|
||||
}
|
||||
|
||||
public static function getFoo() {
|
||||
return 'foo';
|
||||
}
|
||||
public static function getFoo()
|
||||
{
|
||||
return 'foo';
|
||||
}
|
||||
|
||||
public function testRender() {
|
||||
$source = '{{ foo }}';
|
||||
$data = array('bar' => 'baz');
|
||||
$output = 'TEH OUTPUT';
|
||||
public function testRender()
|
||||
{
|
||||
$source = '{{ foo }}';
|
||||
$data = array('bar' => 'baz');
|
||||
$output = 'TEH OUTPUT';
|
||||
|
||||
$template = $this->getMockBuilder('Mustache_Template')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$template = $this->getMockBuilder('Mustache_Template')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$mustache = new MustacheStub;
|
||||
$mustache->template = $template;
|
||||
$mustache = new MustacheStub;
|
||||
$mustache->template = $template;
|
||||
|
||||
$template->expects($this->once())
|
||||
->method('render')
|
||||
->with($data)
|
||||
->will($this->returnValue($output));
|
||||
$template->expects($this->once())
|
||||
->method('render')
|
||||
->with($data)
|
||||
->will($this->returnValue($output));
|
||||
|
||||
$this->assertEquals($output, $mustache->render($source, $data));
|
||||
$this->assertEquals($source, $mustache->source);
|
||||
}
|
||||
$this->assertEquals($output, $mustache->render($source, $data));
|
||||
$this->assertEquals($source, $mustache->source);
|
||||
}
|
||||
|
||||
public function testSettingServices() {
|
||||
$loader = new Mustache_Loader_StringLoader;
|
||||
$tokenizer = new Mustache_Tokenizer;
|
||||
$parser = new Mustache_Parser;
|
||||
$compiler = new Mustache_Compiler;
|
||||
$mustache = new Mustache_Engine;
|
||||
public function testSettingServices()
|
||||
{
|
||||
$loader = new Mustache_Loader_StringLoader;
|
||||
$tokenizer = new Mustache_Tokenizer;
|
||||
$parser = new Mustache_Parser;
|
||||
$compiler = new Mustache_Compiler;
|
||||
$mustache = new Mustache_Engine;
|
||||
|
||||
$this->assertNotSame($loader, $mustache->getLoader());
|
||||
$mustache->setLoader($loader);
|
||||
$this->assertSame($loader, $mustache->getLoader());
|
||||
$this->assertNotSame($loader, $mustache->getLoader());
|
||||
$mustache->setLoader($loader);
|
||||
$this->assertSame($loader, $mustache->getLoader());
|
||||
|
||||
$this->assertNotSame($loader, $mustache->getPartialsLoader());
|
||||
$mustache->setPartialsLoader($loader);
|
||||
$this->assertSame($loader, $mustache->getPartialsLoader());
|
||||
$this->assertNotSame($loader, $mustache->getPartialsLoader());
|
||||
$mustache->setPartialsLoader($loader);
|
||||
$this->assertSame($loader, $mustache->getPartialsLoader());
|
||||
|
||||
$this->assertNotSame($tokenizer, $mustache->getTokenizer());
|
||||
$mustache->setTokenizer($tokenizer);
|
||||
$this->assertSame($tokenizer, $mustache->getTokenizer());
|
||||
$this->assertNotSame($tokenizer, $mustache->getTokenizer());
|
||||
$mustache->setTokenizer($tokenizer);
|
||||
$this->assertSame($tokenizer, $mustache->getTokenizer());
|
||||
|
||||
$this->assertNotSame($parser, $mustache->getParser());
|
||||
$mustache->setParser($parser);
|
||||
$this->assertSame($parser, $mustache->getParser());
|
||||
$this->assertNotSame($parser, $mustache->getParser());
|
||||
$mustache->setParser($parser);
|
||||
$this->assertSame($parser, $mustache->getParser());
|
||||
|
||||
$this->assertNotSame($compiler, $mustache->getCompiler());
|
||||
$mustache->setCompiler($compiler);
|
||||
$this->assertSame($compiler, $mustache->getCompiler());
|
||||
}
|
||||
$this->assertNotSame($compiler, $mustache->getCompiler());
|
||||
$mustache->setCompiler($compiler);
|
||||
$this->assertSame($compiler, $mustache->getCompiler());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group functional
|
||||
*/
|
||||
public function testCache() {
|
||||
$mustache = new Mustache_Engine(array(
|
||||
'template_class_prefix' => '__whot__',
|
||||
'cache' => self::$tempDir,
|
||||
));
|
||||
/**
|
||||
* @group functional
|
||||
*/
|
||||
public function testCache()
|
||||
{
|
||||
$mustache = new Mustache_Engine(array(
|
||||
'template_class_prefix' => '__whot__',
|
||||
'cache' => self::$tempDir,
|
||||
));
|
||||
|
||||
$source = '{{ foo }}';
|
||||
$template = $mustache->loadTemplate($source);
|
||||
$className = $mustache->getTemplateClassName($source);
|
||||
$fileName = self::$tempDir . '/' . $className . '.php';
|
||||
$this->assertInstanceOf($className, $template);
|
||||
$this->assertFileExists($fileName);
|
||||
$this->assertContains("\nclass $className extends Mustache_Template", file_get_contents($fileName));
|
||||
}
|
||||
$source = '{{ foo }}';
|
||||
$template = $mustache->loadTemplate($source);
|
||||
$className = $mustache->getTemplateClassName($source);
|
||||
$fileName = self::$tempDir . '/' . $className . '.php';
|
||||
$this->assertInstanceOf($className, $template);
|
||||
$this->assertFileExists($fileName);
|
||||
$this->assertContains("\nclass $className extends Mustache_Template", file_get_contents($fileName));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
* @dataProvider getBadEscapers
|
||||
*/
|
||||
public function testNonCallableEscapeThrowsException($escape) {
|
||||
new Mustache_Engine(array('escape' => $escape));
|
||||
}
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
* @dataProvider getBadEscapers
|
||||
*/
|
||||
public function testNonCallableEscapeThrowsException($escape)
|
||||
{
|
||||
new Mustache_Engine(array('escape' => $escape));
|
||||
}
|
||||
|
||||
public function getBadEscapers() {
|
||||
return array(
|
||||
array('nothing'),
|
||||
array('foo', 'bar'),
|
||||
);
|
||||
}
|
||||
public function getBadEscapers()
|
||||
{
|
||||
return array(
|
||||
array('nothing'),
|
||||
array('foo', 'bar'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException RuntimeException
|
||||
*/
|
||||
public function testImmutablePartialsLoadersThrowException() {
|
||||
$mustache = new Mustache_Engine(array(
|
||||
'partials_loader' => new Mustache_Loader_StringLoader,
|
||||
));
|
||||
/**
|
||||
* @expectedException RuntimeException
|
||||
*/
|
||||
public function testImmutablePartialsLoadersThrowException()
|
||||
{
|
||||
$mustache = new Mustache_Engine(array(
|
||||
'partials_loader' => new Mustache_Loader_StringLoader,
|
||||
));
|
||||
|
||||
$mustache->setPartials(array('foo' => '{{ foo }}'));
|
||||
}
|
||||
$mustache->setPartials(array('foo' => '{{ foo }}'));
|
||||
}
|
||||
|
||||
public function testMissingPartialsTreatedAsEmptyString() {
|
||||
$mustache = new Mustache_Engine(array(
|
||||
'partials_loader' => new Mustache_Loader_ArrayLoader(array(
|
||||
'foo' => 'FOO',
|
||||
'baz' => 'BAZ',
|
||||
))
|
||||
));
|
||||
public function testMissingPartialsTreatedAsEmptyString()
|
||||
{
|
||||
$mustache = new Mustache_Engine(array(
|
||||
'partials_loader' => new Mustache_Loader_ArrayLoader(array(
|
||||
'foo' => 'FOO',
|
||||
'baz' => 'BAZ',
|
||||
))
|
||||
));
|
||||
|
||||
$this->assertEquals('FOOBAZ', $mustache->render('{{>foo}}{{>bar}}{{>baz}}', array()));
|
||||
}
|
||||
$this->assertEquals('FOOBAZ', $mustache->render('{{>foo}}{{>bar}}{{>baz}}', array()));
|
||||
}
|
||||
|
||||
public function testHelpers() {
|
||||
$foo = array($this, 'getFoo');
|
||||
$bar = 'BAR';
|
||||
$mustache = new Mustache_Engine(array('helpers' => array(
|
||||
'foo' => $foo,
|
||||
'bar' => $bar,
|
||||
)));
|
||||
public function testHelpers()
|
||||
{
|
||||
$foo = array($this, 'getFoo');
|
||||
$bar = 'BAR';
|
||||
$mustache = new Mustache_Engine(array('helpers' => array(
|
||||
'foo' => $foo,
|
||||
'bar' => $bar,
|
||||
)));
|
||||
|
||||
$helpers = $mustache->getHelpers();
|
||||
$this->assertTrue($mustache->hasHelper('foo'));
|
||||
$this->assertTrue($mustache->hasHelper('bar'));
|
||||
$this->assertTrue($helpers->has('foo'));
|
||||
$this->assertTrue($helpers->has('bar'));
|
||||
$this->assertSame($foo, $mustache->getHelper('foo'));
|
||||
$this->assertSame($bar, $mustache->getHelper('bar'));
|
||||
$helpers = $mustache->getHelpers();
|
||||
$this->assertTrue($mustache->hasHelper('foo'));
|
||||
$this->assertTrue($mustache->hasHelper('bar'));
|
||||
$this->assertTrue($helpers->has('foo'));
|
||||
$this->assertTrue($helpers->has('bar'));
|
||||
$this->assertSame($foo, $mustache->getHelper('foo'));
|
||||
$this->assertSame($bar, $mustache->getHelper('bar'));
|
||||
|
||||
$mustache->removeHelper('bar');
|
||||
$this->assertFalse($mustache->hasHelper('bar'));
|
||||
$mustache->addHelper('bar', $bar);
|
||||
$this->assertSame($bar, $mustache->getHelper('bar'));
|
||||
$mustache->removeHelper('bar');
|
||||
$this->assertFalse($mustache->hasHelper('bar'));
|
||||
$mustache->addHelper('bar', $bar);
|
||||
$this->assertSame($bar, $mustache->getHelper('bar'));
|
||||
|
||||
$baz = array($this, 'wrapWithUnderscores');
|
||||
$this->assertFalse($mustache->hasHelper('baz'));
|
||||
$this->assertFalse($helpers->has('baz'));
|
||||
$baz = array($this, 'wrapWithUnderscores');
|
||||
$this->assertFalse($mustache->hasHelper('baz'));
|
||||
$this->assertFalse($helpers->has('baz'));
|
||||
|
||||
$mustache->addHelper('baz', $baz);
|
||||
$this->assertTrue($mustache->hasHelper('baz'));
|
||||
$this->assertTrue($helpers->has('baz'));
|
||||
$mustache->addHelper('baz', $baz);
|
||||
$this->assertTrue($mustache->hasHelper('baz'));
|
||||
$this->assertTrue($helpers->has('baz'));
|
||||
|
||||
// ... and a functional test
|
||||
$tpl = $mustache->loadTemplate('{{foo}} - {{bar}} - {{#baz}}qux{{/baz}}');
|
||||
$this->assertEquals('foo - BAR - __qux__', $tpl->render());
|
||||
$this->assertEquals('foo - BAR - __qux__', $tpl->render(array('qux' => "won't mess things up")));
|
||||
}
|
||||
// ... and a functional test
|
||||
$tpl = $mustache->loadTemplate('{{foo}} - {{bar}} - {{#baz}}qux{{/baz}}');
|
||||
$this->assertEquals('foo - BAR - __qux__', $tpl->render());
|
||||
$this->assertEquals('foo - BAR - __qux__', $tpl->render(array('qux' => "won't mess things up")));
|
||||
}
|
||||
|
||||
public static function wrapWithUnderscores($text) {
|
||||
return '__'.$text.'__';
|
||||
}
|
||||
public static function wrapWithUnderscores($text)
|
||||
{
|
||||
return '__'.$text.'__';
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
public function testSetHelpersThrowsExceptions() {
|
||||
$mustache = new Mustache_Engine;
|
||||
$mustache->setHelpers('monkeymonkeymonkey');
|
||||
}
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
public function testSetHelpersThrowsExceptions()
|
||||
{
|
||||
$mustache = new Mustache_Engine;
|
||||
$mustache->setHelpers('monkeymonkeymonkey');
|
||||
}
|
||||
|
||||
private static function rmdir($path) {
|
||||
$path = rtrim($path, '/').'/';
|
||||
$handle = opendir($path);
|
||||
while (($file = readdir($handle)) !== false) {
|
||||
if ($file == '.' || $file == '..') {
|
||||
continue;
|
||||
}
|
||||
private static function rmdir($path)
|
||||
{
|
||||
$path = rtrim($path, '/').'/';
|
||||
$handle = opendir($path);
|
||||
while (($file = readdir($handle)) !== false) {
|
||||
if ($file == '.' || $file == '..') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fullpath = $path.$file;
|
||||
if (is_dir($fullpath)) {
|
||||
self::rmdir($fullpath);
|
||||
} else {
|
||||
unlink($fullpath);
|
||||
}
|
||||
}
|
||||
$fullpath = $path.$file;
|
||||
if (is_dir($fullpath)) {
|
||||
self::rmdir($fullpath);
|
||||
} else {
|
||||
unlink($fullpath);
|
||||
}
|
||||
}
|
||||
|
||||
closedir($handle);
|
||||
rmdir($path);
|
||||
}
|
||||
closedir($handle);
|
||||
rmdir($path);
|
||||
}
|
||||
}
|
||||
|
||||
class MustacheStub extends Mustache_Engine {
|
||||
public $source;
|
||||
public $template;
|
||||
public function loadTemplate($source) {
|
||||
$this->source = $source;
|
||||
public $source;
|
||||
public $template;
|
||||
public function loadTemplate($source)
|
||||
{
|
||||
$this->source = $source;
|
||||
|
||||
return $this->template;
|
||||
}
|
||||
return $this->template;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,24 +13,28 @@
|
||||
* @group magic_methods
|
||||
* @group functional
|
||||
*/
|
||||
class Mustache_Test_Functional_CallTest extends PHPUnit_Framework_TestCase {
|
||||
class Mustache_Test_Functional_CallTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
public function testCallEatsContext() {
|
||||
$m = new Mustache_Engine;
|
||||
$tpl = $m->loadTemplate('{{# foo }}{{ label }}: {{ name }}{{/ foo }}');
|
||||
public function testCallEatsContext()
|
||||
{
|
||||
$m = new Mustache_Engine;
|
||||
$tpl = $m->loadTemplate('{{# foo }}{{ label }}: {{ name }}{{/ foo }}');
|
||||
|
||||
$foo = new Mustache_Test_Functional_ClassWithCall();
|
||||
$foo->name = 'Bob';
|
||||
$foo = new Mustache_Test_Functional_ClassWithCall();
|
||||
$foo->name = 'Bob';
|
||||
|
||||
$data = array('label' => 'name', 'foo' => $foo);
|
||||
$data = array('label' => 'name', 'foo' => $foo);
|
||||
|
||||
$this->assertEquals('name: Bob', $tpl->render($data));
|
||||
}
|
||||
$this->assertEquals('name: Bob', $tpl->render($data));
|
||||
}
|
||||
}
|
||||
|
||||
class Mustache_Test_Functional_ClassWithCall {
|
||||
public $name;
|
||||
public function __call($method, $args) {
|
||||
return 'unknown value';
|
||||
}
|
||||
class Mustache_Test_Functional_ClassWithCall
|
||||
{
|
||||
public $name;
|
||||
public function __call($method, $args)
|
||||
{
|
||||
return 'unknown value';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,125 +13,130 @@
|
||||
* @group examples
|
||||
* @group functional
|
||||
*/
|
||||
class Mustache_Test_Functional_ExamplesTest extends PHPUnit_Framework_TestCase {
|
||||
class Mustache_Test_Functional_ExamplesTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* Test everything in the `examples` directory.
|
||||
*
|
||||
* @dataProvider getExamples
|
||||
*
|
||||
* @param string $context
|
||||
* @param string $source
|
||||
* @param array $partials
|
||||
* @param string $expected
|
||||
*/
|
||||
public function testExamples($context, $source, $partials, $expected) {
|
||||
$mustache = new Mustache_Engine(array(
|
||||
'partials' => $partials
|
||||
));
|
||||
$this->assertEquals($expected, $mustache->loadTemplate($source)->render($context));
|
||||
}
|
||||
/**
|
||||
* Test everything in the `examples` directory.
|
||||
*
|
||||
* @dataProvider getExamples
|
||||
*
|
||||
* @param string $context
|
||||
* @param string $source
|
||||
* @param array $partials
|
||||
* @param string $expected
|
||||
*/
|
||||
public function testExamples($context, $source, $partials, $expected)
|
||||
{
|
||||
$mustache = new Mustache_Engine(array(
|
||||
'partials' => $partials
|
||||
));
|
||||
$this->assertEquals($expected, $mustache->loadTemplate($source)->render($context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testExamples method.
|
||||
*
|
||||
* Loads examples from the test fixtures directory.
|
||||
*
|
||||
* This examples directory should contain any number of subdirectories, each of which contains
|
||||
* three files: one Mustache class (.php), one Mustache template (.mustache), and one output file
|
||||
* (.txt). Optionally, the directory may contain a folder full of partials.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getExamples() {
|
||||
$path = realpath(dirname(__FILE__).'/../../../fixtures/examples');
|
||||
$examples = array();
|
||||
/**
|
||||
* Data provider for testExamples method.
|
||||
*
|
||||
* Loads examples from the test fixtures directory.
|
||||
*
|
||||
* This examples directory should contain any number of subdirectories, each of which contains
|
||||
* three files: one Mustache class (.php), one Mustache template (.mustache), and one output file
|
||||
* (.txt). Optionally, the directory may contain a folder full of partials.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getExamples()
|
||||
{
|
||||
$path = realpath(dirname(__FILE__).'/../../../fixtures/examples');
|
||||
$examples = array();
|
||||
|
||||
$handle = opendir($path);
|
||||
while (($file = readdir($handle)) !== false) {
|
||||
if ($file == '.' || $file == '..') {
|
||||
continue;
|
||||
}
|
||||
$handle = opendir($path);
|
||||
while (($file = readdir($handle)) !== false) {
|
||||
if ($file == '.' || $file == '..') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fullpath = $path.'/'.$file;
|
||||
if (is_dir($fullpath)) {
|
||||
$examples[$file] = $this->loadExample($fullpath);
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
$fullpath = $path.'/'.$file;
|
||||
if (is_dir($fullpath)) {
|
||||
$examples[$file] = $this->loadExample($fullpath);
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
|
||||
return $examples;
|
||||
}
|
||||
return $examples;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to load an example given the full path.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return array arguments for testExamples
|
||||
*/
|
||||
private function loadExample($path) {
|
||||
$context = null;
|
||||
$source = null;
|
||||
$partials = array();
|
||||
$expected = null;
|
||||
/**
|
||||
* Helper method to load an example given the full path.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return array arguments for testExamples
|
||||
*/
|
||||
private function loadExample($path)
|
||||
{
|
||||
$context = null;
|
||||
$source = null;
|
||||
$partials = array();
|
||||
$expected = null;
|
||||
|
||||
$handle = opendir($path);
|
||||
while (($file = readdir($handle)) !== false) {
|
||||
$fullpath = $path.'/'.$file;
|
||||
$info = pathinfo($fullpath);
|
||||
$handle = opendir($path);
|
||||
while (($file = readdir($handle)) !== false) {
|
||||
$fullpath = $path.'/'.$file;
|
||||
$info = pathinfo($fullpath);
|
||||
|
||||
if (is_dir($fullpath) && $info['basename'] == 'partials') {
|
||||
// load partials
|
||||
$partials = $this->loadPartials($fullpath);
|
||||
} elseif (is_file($fullpath)) {
|
||||
// load other files
|
||||
switch ($info['extension']) {
|
||||
case 'php':
|
||||
require_once($fullpath);
|
||||
$context = new $info['filename'];
|
||||
break;
|
||||
if (is_dir($fullpath) && $info['basename'] == 'partials') {
|
||||
// load partials
|
||||
$partials = $this->loadPartials($fullpath);
|
||||
} elseif (is_file($fullpath)) {
|
||||
// load other files
|
||||
switch ($info['extension']) {
|
||||
case 'php':
|
||||
require_once($fullpath);
|
||||
$context = new $info['filename'];
|
||||
break;
|
||||
|
||||
case 'mustache':
|
||||
$source = file_get_contents($fullpath);
|
||||
break;
|
||||
case 'mustache':
|
||||
$source = file_get_contents($fullpath);
|
||||
break;
|
||||
|
||||
case 'txt':
|
||||
$expected = file_get_contents($fullpath);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
case 'txt':
|
||||
$expected = file_get_contents($fullpath);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
|
||||
return array($context, $source, $partials, $expected);
|
||||
}
|
||||
return array($context, $source, $partials, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to load partials given an example directory.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return array $partials
|
||||
*/
|
||||
private function loadPartials($path) {
|
||||
$partials = array();
|
||||
/**
|
||||
* Helper method to load partials given an example directory.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return array $partials
|
||||
*/
|
||||
private function loadPartials($path)
|
||||
{
|
||||
$partials = array();
|
||||
|
||||
$handle = opendir($path);
|
||||
while (($file = readdir($handle)) !== false) {
|
||||
if ($file == '.' || $file == '..') {
|
||||
continue;
|
||||
}
|
||||
$handle = opendir($path);
|
||||
while (($file = readdir($handle)) !== false) {
|
||||
if ($file == '.' || $file == '..') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fullpath = $path.'/'.$file;
|
||||
$info = pathinfo($fullpath);
|
||||
$fullpath = $path.'/'.$file;
|
||||
$info = pathinfo($fullpath);
|
||||
|
||||
if ($info['extension'] === 'mustache') {
|
||||
$partials[$info['filename']] = file_get_contents($fullpath);
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
if ($info['extension'] === 'mustache') {
|
||||
$partials[$info['filename']] = file_get_contents($fullpath);
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
|
||||
return $partials;
|
||||
}
|
||||
return $partials;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,82 +13,94 @@
|
||||
* @group lambdas
|
||||
* @group functional
|
||||
*/
|
||||
class Mustache_Test_Functional_HigherOrderSectionsTest extends PHPUnit_Framework_TestCase {
|
||||
class Mustache_Test_Functional_HigherOrderSectionsTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
private $mustache;
|
||||
private $mustache;
|
||||
|
||||
public function setUp() {
|
||||
$this->mustache = new Mustache_Engine;
|
||||
}
|
||||
public function setUp()
|
||||
{
|
||||
$this->mustache = new Mustache_Engine;
|
||||
}
|
||||
|
||||
public function testRuntimeSectionCallback() {
|
||||
$tpl = $this->mustache->loadTemplate('{{#doublewrap}}{{name}}{{/doublewrap}}');
|
||||
public function testRuntimeSectionCallback()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{#doublewrap}}{{name}}{{/doublewrap}}');
|
||||
|
||||
$foo = new Mustache_Test_Functional_Foo;
|
||||
$foo->doublewrap = array($foo, 'wrapWithBoth');
|
||||
$foo = new Mustache_Test_Functional_Foo;
|
||||
$foo->doublewrap = array($foo, 'wrapWithBoth');
|
||||
|
||||
$this->assertEquals(sprintf('<strong><em>%s</em></strong>', $foo->name), $tpl->render($foo));
|
||||
}
|
||||
$this->assertEquals(sprintf('<strong><em>%s</em></strong>', $foo->name), $tpl->render($foo));
|
||||
}
|
||||
|
||||
public function testStaticSectionCallback() {
|
||||
$tpl = $this->mustache->loadTemplate('{{#trimmer}} {{name}} {{/trimmer}}');
|
||||
public function testStaticSectionCallback()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{#trimmer}} {{name}} {{/trimmer}}');
|
||||
|
||||
$foo = new Mustache_Test_Functional_Foo;
|
||||
$foo->trimmer = array(get_class($foo), 'staticTrim');
|
||||
$foo = new Mustache_Test_Functional_Foo;
|
||||
$foo->trimmer = array(get_class($foo), 'staticTrim');
|
||||
|
||||
$this->assertEquals($foo->name, $tpl->render($foo));
|
||||
}
|
||||
$this->assertEquals($foo->name, $tpl->render($foo));
|
||||
}
|
||||
|
||||
public function testViewArraySectionCallback() {
|
||||
$tpl = $this->mustache->loadTemplate('{{#trim}} {{name}} {{/trim}}');
|
||||
public function testViewArraySectionCallback()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{#trim}} {{name}} {{/trim}}');
|
||||
|
||||
$foo = new Mustache_Test_Functional_Foo;
|
||||
$foo = new Mustache_Test_Functional_Foo;
|
||||
|
||||
$data = array(
|
||||
'name' => 'Bob',
|
||||
'trim' => array(get_class($foo), 'staticTrim'),
|
||||
);
|
||||
$data = array(
|
||||
'name' => 'Bob',
|
||||
'trim' => array(get_class($foo), 'staticTrim'),
|
||||
);
|
||||
|
||||
$this->assertEquals($data['name'], $tpl->render($data));
|
||||
}
|
||||
$this->assertEquals($data['name'], $tpl->render($data));
|
||||
}
|
||||
|
||||
public function testMonsters() {
|
||||
$tpl = $this->mustache->loadTemplate('{{#title}}{{title}} {{/title}}{{name}}');
|
||||
public function testMonsters()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{#title}}{{title}} {{/title}}{{name}}');
|
||||
|
||||
$frank = new Mustache_Test_Functional_Monster();
|
||||
$frank->title = 'Dr.';
|
||||
$frank->name = 'Frankenstein';
|
||||
$this->assertEquals('Dr. Frankenstein', $tpl->render($frank));
|
||||
$frank = new Mustache_Test_Functional_Monster();
|
||||
$frank->title = 'Dr.';
|
||||
$frank->name = 'Frankenstein';
|
||||
$this->assertEquals('Dr. Frankenstein', $tpl->render($frank));
|
||||
|
||||
$dracula = new Mustache_Test_Functional_Monster();
|
||||
$dracula->title = 'Count';
|
||||
$dracula->name = 'Dracula';
|
||||
$this->assertEquals('Count Dracula', $tpl->render($dracula));
|
||||
}
|
||||
$dracula = new Mustache_Test_Functional_Monster();
|
||||
$dracula->title = 'Count';
|
||||
$dracula->name = 'Dracula';
|
||||
$this->assertEquals('Count Dracula', $tpl->render($dracula));
|
||||
}
|
||||
}
|
||||
|
||||
class Mustache_Test_Functional_Foo {
|
||||
public $name = 'Justin';
|
||||
public $lorem = 'Lorem ipsum dolor sit amet,';
|
||||
class Mustache_Test_Functional_Foo
|
||||
{
|
||||
public $name = 'Justin';
|
||||
public $lorem = 'Lorem ipsum dolor sit amet,';
|
||||
|
||||
public function wrapWithEm($text) {
|
||||
return sprintf('<em>%s</em>', $text);
|
||||
}
|
||||
public function wrapWithEm($text)
|
||||
{
|
||||
return sprintf('<em>%s</em>', $text);
|
||||
}
|
||||
|
||||
public function wrapWithStrong($text) {
|
||||
return sprintf('<strong>%s</strong>', $text);
|
||||
}
|
||||
public function wrapWithStrong($text)
|
||||
{
|
||||
return sprintf('<strong>%s</strong>', $text);
|
||||
}
|
||||
|
||||
public function wrapWithBoth($text) {
|
||||
return self::wrapWithStrong(self::wrapWithEm($text));
|
||||
}
|
||||
public function wrapWithBoth($text)
|
||||
{
|
||||
return self::wrapWithStrong(self::wrapWithEm($text));
|
||||
}
|
||||
|
||||
public static function staticTrim($text) {
|
||||
return trim($text);
|
||||
}
|
||||
public static function staticTrim($text)
|
||||
{
|
||||
return trim($text);
|
||||
}
|
||||
}
|
||||
|
||||
class Mustache_Test_Functional_Monster {
|
||||
public $title;
|
||||
public $name;
|
||||
class Mustache_Test_Functional_Monster
|
||||
{
|
||||
public $title;
|
||||
public $name;
|
||||
}
|
||||
|
||||
@@ -13,128 +13,140 @@
|
||||
* @group mustache_injection
|
||||
* @group functional
|
||||
*/
|
||||
class Mustache_Test_Functional_MustacheInjectionTest extends PHPUnit_Framework_TestCase {
|
||||
class Mustache_Test_Functional_MustacheInjectionTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
private $mustache;
|
||||
private $mustache;
|
||||
|
||||
public function setUp() {
|
||||
$this->mustache = new Mustache_Engine;
|
||||
}
|
||||
public function setUp()
|
||||
{
|
||||
$this->mustache = new Mustache_Engine;
|
||||
}
|
||||
|
||||
// interpolation
|
||||
// interpolation
|
||||
|
||||
public function testInterpolationInjection() {
|
||||
$tpl = $this->mustache->loadTemplate('{{ a }}');
|
||||
public function testInterpolationInjection()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{ a }}');
|
||||
|
||||
$data = array(
|
||||
'a' => '{{ b }}',
|
||||
'b' => 'FAIL'
|
||||
);
|
||||
$data = array(
|
||||
'a' => '{{ b }}',
|
||||
'b' => 'FAIL'
|
||||
);
|
||||
|
||||
$this->assertEquals('{{ b }}', $tpl->render($data));
|
||||
}
|
||||
$this->assertEquals('{{ b }}', $tpl->render($data));
|
||||
}
|
||||
|
||||
public function testUnescapedInterpolationInjection() {
|
||||
$tpl = $this->mustache->loadTemplate('{{{ a }}}');
|
||||
public function testUnescapedInterpolationInjection()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{{ a }}}');
|
||||
|
||||
$data = array(
|
||||
'a' => '{{ b }}',
|
||||
'b' => 'FAIL'
|
||||
);
|
||||
$data = array(
|
||||
'a' => '{{ b }}',
|
||||
'b' => 'FAIL'
|
||||
);
|
||||
|
||||
$this->assertEquals('{{ b }}', $tpl->render($data));
|
||||
}
|
||||
$this->assertEquals('{{ b }}', $tpl->render($data));
|
||||
}
|
||||
|
||||
|
||||
// sections
|
||||
// sections
|
||||
|
||||
public function testSectionInjection() {
|
||||
$tpl = $this->mustache->loadTemplate('{{# a }}{{ b }}{{/ a }}');
|
||||
public function testSectionInjection()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{# a }}{{ b }}{{/ a }}');
|
||||
|
||||
$data = array(
|
||||
'a' => true,
|
||||
'b' => '{{ c }}',
|
||||
'c' => 'FAIL'
|
||||
);
|
||||
$data = array(
|
||||
'a' => true,
|
||||
'b' => '{{ c }}',
|
||||
'c' => 'FAIL'
|
||||
);
|
||||
|
||||
$this->assertEquals('{{ c }}', $tpl->render($data));
|
||||
}
|
||||
$this->assertEquals('{{ c }}', $tpl->render($data));
|
||||
}
|
||||
|
||||
public function testUnescapedSectionInjection() {
|
||||
$tpl = $this->mustache->loadTemplate('{{# a }}{{{ b }}}{{/ a }}');
|
||||
public function testUnescapedSectionInjection()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{# a }}{{{ b }}}{{/ a }}');
|
||||
|
||||
$data = array(
|
||||
'a' => true,
|
||||
'b' => '{{ c }}',
|
||||
'c' => 'FAIL'
|
||||
);
|
||||
$data = array(
|
||||
'a' => true,
|
||||
'b' => '{{ c }}',
|
||||
'c' => 'FAIL'
|
||||
);
|
||||
|
||||
$this->assertEquals('{{ c }}', $tpl->render($data));
|
||||
}
|
||||
$this->assertEquals('{{ c }}', $tpl->render($data));
|
||||
}
|
||||
|
||||
|
||||
// partials
|
||||
// partials
|
||||
|
||||
public function testPartialInjection() {
|
||||
$tpl = $this->mustache->loadTemplate('{{> partial }}');
|
||||
$this->mustache->setPartials(array(
|
||||
'partial' => '{{ a }}',
|
||||
));
|
||||
public function testPartialInjection()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{> partial }}');
|
||||
$this->mustache->setPartials(array(
|
||||
'partial' => '{{ a }}',
|
||||
));
|
||||
|
||||
$data = array(
|
||||
'a' => '{{ b }}',
|
||||
'b' => 'FAIL'
|
||||
);
|
||||
$data = array(
|
||||
'a' => '{{ b }}',
|
||||
'b' => 'FAIL'
|
||||
);
|
||||
|
||||
$this->assertEquals('{{ b }}', $tpl->render($data));
|
||||
}
|
||||
$this->assertEquals('{{ b }}', $tpl->render($data));
|
||||
}
|
||||
|
||||
public function testPartialUnescapedInjection() {
|
||||
$tpl = $this->mustache->loadTemplate('{{> partial }}');
|
||||
$this->mustache->setPartials(array(
|
||||
'partial' => '{{{ a }}}',
|
||||
));
|
||||
public function testPartialUnescapedInjection()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{> partial }}');
|
||||
$this->mustache->setPartials(array(
|
||||
'partial' => '{{{ a }}}',
|
||||
));
|
||||
|
||||
$data = array(
|
||||
'a' => '{{ b }}',
|
||||
'b' => 'FAIL'
|
||||
);
|
||||
$data = array(
|
||||
'a' => '{{ b }}',
|
||||
'b' => 'FAIL'
|
||||
);
|
||||
|
||||
$this->assertEquals('{{ b }}', $tpl->render($data));
|
||||
}
|
||||
$this->assertEquals('{{ b }}', $tpl->render($data));
|
||||
}
|
||||
|
||||
|
||||
// lambdas
|
||||
// lambdas
|
||||
|
||||
public function testLambdaInterpolationInjection() {
|
||||
$tpl = $this->mustache->loadTemplate('{{ a }}');
|
||||
public function testLambdaInterpolationInjection()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{ a }}');
|
||||
|
||||
$data = array(
|
||||
'a' => array($this, 'lambdaInterpolationCallback'),
|
||||
'b' => '{{ c }}',
|
||||
'c' => 'FAIL'
|
||||
);
|
||||
$data = array(
|
||||
'a' => array($this, 'lambdaInterpolationCallback'),
|
||||
'b' => '{{ c }}',
|
||||
'c' => 'FAIL'
|
||||
);
|
||||
|
||||
$this->assertEquals('{{ c }}', $tpl->render($data));
|
||||
}
|
||||
$this->assertEquals('{{ c }}', $tpl->render($data));
|
||||
}
|
||||
|
||||
public static function lambdaInterpolationCallback() {
|
||||
return '{{ b }}';
|
||||
}
|
||||
public static function lambdaInterpolationCallback()
|
||||
{
|
||||
return '{{ b }}';
|
||||
}
|
||||
|
||||
public function testLambdaSectionInjection() {
|
||||
$tpl = $this->mustache->loadTemplate('{{# a }}b{{/ a }}');
|
||||
public function testLambdaSectionInjection()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{# a }}b{{/ a }}');
|
||||
|
||||
$data = array(
|
||||
'a' => array($this, 'lambdaSectionCallback'),
|
||||
'b' => '{{ c }}',
|
||||
'c' => 'FAIL'
|
||||
);
|
||||
$data = array(
|
||||
'a' => array($this, 'lambdaSectionCallback'),
|
||||
'b' => '{{ c }}',
|
||||
'c' => 'FAIL'
|
||||
);
|
||||
|
||||
$this->assertEquals('{{ c }}', $tpl->render($data));
|
||||
}
|
||||
$this->assertEquals('{{ c }}', $tpl->render($data));
|
||||
}
|
||||
|
||||
public static function lambdaSectionCallback($text) {
|
||||
return '{{ ' . $text . ' }}';
|
||||
}
|
||||
public static function lambdaSectionCallback($text)
|
||||
{
|
||||
return '{{ ' . $text . ' }}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,144 +15,161 @@
|
||||
* @group mustache-spec
|
||||
* @group functional
|
||||
*/
|
||||
class Mustache_Test_Functional_MustacheSpecTest extends PHPUnit_Framework_TestCase {
|
||||
class Mustache_Test_Functional_MustacheSpecTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
private static $mustache;
|
||||
private static $mustache;
|
||||
|
||||
public static function setUpBeforeClass() {
|
||||
self::$mustache = new Mustache_Engine;
|
||||
}
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
self::$mustache = new Mustache_Engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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"');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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 comments
|
||||
* @dataProvider loadCommentSpec
|
||||
*/
|
||||
public function testCommentSpec($desc, $source, $partials, $data, $expected) {
|
||||
$template = self::loadTemplate($source, $partials);
|
||||
$this->assertEquals($expected, $template->render($data), $desc);
|
||||
}
|
||||
/**
|
||||
* @group comments
|
||||
* @dataProvider loadCommentSpec
|
||||
*/
|
||||
public function testCommentSpec($desc, $source, $partials, $data, $expected)
|
||||
{
|
||||
$template = self::loadTemplate($source, $partials);
|
||||
$this->assertEquals($expected, $template->render($data), $desc);
|
||||
}
|
||||
|
||||
public function loadCommentSpec() {
|
||||
return $this->loadSpec('comments');
|
||||
}
|
||||
public function loadCommentSpec()
|
||||
{
|
||||
return $this->loadSpec('comments');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group delimiters
|
||||
* @dataProvider loadDelimitersSpec
|
||||
*/
|
||||
public function testDelimitersSpec($desc, $source, $partials, $data, $expected) {
|
||||
$template = self::loadTemplate($source, $partials);
|
||||
$this->assertEquals($expected, $template->render($data), $desc);
|
||||
}
|
||||
/**
|
||||
* @group delimiters
|
||||
* @dataProvider loadDelimitersSpec
|
||||
*/
|
||||
public function testDelimitersSpec($desc, $source, $partials, $data, $expected)
|
||||
{
|
||||
$template = self::loadTemplate($source, $partials);
|
||||
$this->assertEquals($expected, $template->render($data), $desc);
|
||||
}
|
||||
|
||||
public function loadDelimitersSpec() {
|
||||
return $this->loadSpec('delimiters');
|
||||
}
|
||||
public function loadDelimitersSpec()
|
||||
{
|
||||
return $this->loadSpec('delimiters');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group interpolation
|
||||
* @dataProvider loadInterpolationSpec
|
||||
*/
|
||||
public function testInterpolationSpec($desc, $source, $partials, $data, $expected) {
|
||||
$template = self::loadTemplate($source, $partials);
|
||||
$this->assertEquals($expected, $template->render($data), $desc);
|
||||
}
|
||||
/**
|
||||
* @group interpolation
|
||||
* @dataProvider loadInterpolationSpec
|
||||
*/
|
||||
public function testInterpolationSpec($desc, $source, $partials, $data, $expected)
|
||||
{
|
||||
$template = self::loadTemplate($source, $partials);
|
||||
$this->assertEquals($expected, $template->render($data), $desc);
|
||||
}
|
||||
|
||||
public function loadInterpolationSpec() {
|
||||
return $this->loadSpec('interpolation');
|
||||
}
|
||||
public function loadInterpolationSpec()
|
||||
{
|
||||
return $this->loadSpec('interpolation');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group inverted
|
||||
* @group inverted-sections
|
||||
* @dataProvider loadInvertedSpec
|
||||
*/
|
||||
public function testInvertedSpec($desc, $source, $partials, $data, $expected) {
|
||||
$template = self::loadTemplate($source, $partials);
|
||||
$this->assertEquals($expected, $template->render($data), $desc);
|
||||
}
|
||||
/**
|
||||
* @group inverted
|
||||
* @group inverted-sections
|
||||
* @dataProvider loadInvertedSpec
|
||||
*/
|
||||
public function testInvertedSpec($desc, $source, $partials, $data, $expected)
|
||||
{
|
||||
$template = self::loadTemplate($source, $partials);
|
||||
$this->assertEquals($expected, $template->render($data), $desc);
|
||||
}
|
||||
|
||||
public function loadInvertedSpec() {
|
||||
return $this->loadSpec('inverted');
|
||||
}
|
||||
public function loadInvertedSpec()
|
||||
{
|
||||
return $this->loadSpec('inverted');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group partials
|
||||
* @dataProvider loadPartialsSpec
|
||||
*/
|
||||
public function testPartialsSpec($desc, $source, $partials, $data, $expected) {
|
||||
$template = self::loadTemplate($source, $partials);
|
||||
$this->assertEquals($expected, $template->render($data), $desc);
|
||||
}
|
||||
/**
|
||||
* @group partials
|
||||
* @dataProvider loadPartialsSpec
|
||||
*/
|
||||
public function testPartialsSpec($desc, $source, $partials, $data, $expected)
|
||||
{
|
||||
$template = self::loadTemplate($source, $partials);
|
||||
$this->assertEquals($expected, $template->render($data), $desc);
|
||||
}
|
||||
|
||||
public function loadPartialsSpec() {
|
||||
return $this->loadSpec('partials');
|
||||
}
|
||||
public function loadPartialsSpec()
|
||||
{
|
||||
return $this->loadSpec('partials');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group sections
|
||||
* @dataProvider loadSectionsSpec
|
||||
*/
|
||||
public function testSectionsSpec($desc, $source, $partials, $data, $expected) {
|
||||
$template = self::loadTemplate($source, $partials);
|
||||
$this->assertEquals($expected, $template->render($data), $desc);
|
||||
}
|
||||
/**
|
||||
* @group sections
|
||||
* @dataProvider loadSectionsSpec
|
||||
*/
|
||||
public function testSectionsSpec($desc, $source, $partials, $data, $expected)
|
||||
{
|
||||
$template = self::loadTemplate($source, $partials);
|
||||
$this->assertEquals($expected, $template->render($data), $desc);
|
||||
}
|
||||
|
||||
public function loadSectionsSpec() {
|
||||
return $this->loadSpec('sections');
|
||||
}
|
||||
public function loadSectionsSpec()
|
||||
{
|
||||
return $this->loadSpec('sections');
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for the mustache spec test.
|
||||
*
|
||||
* Loads YAML files from the spec and converts them to PHPisms.
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
private function loadSpec($name) {
|
||||
$filename = dirname(__FILE__) . '/../../../../vendor/spec/specs/' . $name . '.yml';
|
||||
if (!file_exists($filename)) {
|
||||
return array();
|
||||
}
|
||||
/**
|
||||
* Data provider for the mustache spec test.
|
||||
*
|
||||
* Loads YAML files from the spec and converts them to PHPisms.
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
private function loadSpec($name)
|
||||
{
|
||||
$filename = dirname(__FILE__) . '/../../../../vendor/spec/specs/' . $name . '.yml';
|
||||
if (!file_exists($filename)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$data = array();
|
||||
$yaml = new sfYamlParser;
|
||||
$file = file_get_contents($filename);
|
||||
$data = array();
|
||||
$yaml = new sfYamlParser;
|
||||
$file = file_get_contents($filename);
|
||||
|
||||
// @hack: pre-process the 'lambdas' spec so the Symfony YAML parser doesn't complain.
|
||||
if ($name === '~lambdas') {
|
||||
$file = str_replace(" !code\n", "\n", $file);
|
||||
}
|
||||
// @hack: pre-process the 'lambdas' spec so the Symfony YAML parser doesn't complain.
|
||||
if ($name === '~lambdas') {
|
||||
$file = str_replace(" !code\n", "\n", $file);
|
||||
}
|
||||
|
||||
$spec = $yaml->parse($file);
|
||||
$spec = $yaml->parse($file);
|
||||
|
||||
foreach ($spec['tests'] as $test) {
|
||||
$data[] = array(
|
||||
$test['name'] . ': ' . $test['desc'],
|
||||
$test['template'],
|
||||
isset($test['partials']) ? $test['partials'] : array(),
|
||||
$test['data'],
|
||||
$test['expected'],
|
||||
);
|
||||
}
|
||||
foreach ($spec['tests'] as $test) {
|
||||
$data[] = array(
|
||||
$test['name'] . ': ' . $test['desc'],
|
||||
$test['template'],
|
||||
isset($test['partials']) ? $test['partials'] : array(),
|
||||
$test['data'],
|
||||
$test['expected'],
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
private static function loadTemplate($source, $partials) {
|
||||
self::$mustache->setPartials($partials);
|
||||
private static function loadTemplate($source, $partials)
|
||||
{
|
||||
self::$mustache->setPartials($partials);
|
||||
|
||||
return self::$mustache->loadTemplate($source);
|
||||
}
|
||||
return self::$mustache->loadTemplate($source);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,82 +13,98 @@
|
||||
* @group sections
|
||||
* @group functional
|
||||
*/
|
||||
class Mustache_Test_Functional_ObjectSectionTest extends PHPUnit_Framework_TestCase {
|
||||
private $mustache;
|
||||
class Mustache_Test_Functional_ObjectSectionTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
private $mustache;
|
||||
|
||||
public function setUp() {
|
||||
$this->mustache = new Mustache_Engine;
|
||||
}
|
||||
public function setUp()
|
||||
{
|
||||
$this->mustache = new Mustache_Engine;
|
||||
}
|
||||
|
||||
public function testBasicObject() {
|
||||
$tpl = $this->mustache->loadTemplate('{{#foo}}{{name}}{{/foo}}');
|
||||
$this->assertEquals('Foo', $tpl->render(new Mustache_Test_Functional_Alpha));
|
||||
}
|
||||
public function testBasicObject()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{#foo}}{{name}}{{/foo}}');
|
||||
$this->assertEquals('Foo', $tpl->render(new Mustache_Test_Functional_Alpha));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group magic_methods
|
||||
*/
|
||||
public function testObjectWithGet() {
|
||||
$tpl = $this->mustache->loadTemplate('{{#foo}}{{name}}{{/foo}}');
|
||||
$this->assertEquals('Foo', $tpl->render(new Mustache_Test_Functional_Beta));
|
||||
}
|
||||
/**
|
||||
* @group magic_methods
|
||||
*/
|
||||
public function testObjectWithGet()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{#foo}}{{name}}{{/foo}}');
|
||||
$this->assertEquals('Foo', $tpl->render(new Mustache_Test_Functional_Beta));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group magic_methods
|
||||
*/
|
||||
public function testSectionObjectWithGet() {
|
||||
$tpl = $this->mustache->loadTemplate('{{#bar}}{{#foo}}{{name}}{{/foo}}{{/bar}}');
|
||||
$this->assertEquals('Foo', $tpl->render(new Mustache_Test_Functional_Gamma));
|
||||
}
|
||||
/**
|
||||
* @group magic_methods
|
||||
*/
|
||||
public function testSectionObjectWithGet()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{#bar}}{{#foo}}{{name}}{{/foo}}{{/bar}}');
|
||||
$this->assertEquals('Foo', $tpl->render(new Mustache_Test_Functional_Gamma));
|
||||
}
|
||||
|
||||
public function testSectionObjectWithFunction() {
|
||||
$tpl = $this->mustache->loadTemplate('{{#foo}}{{name}}{{/foo}}');
|
||||
$alpha = new Mustache_Test_Functional_Alpha;
|
||||
$alpha->foo = new Mustache_Test_Functional_Delta;
|
||||
$this->assertEquals('Foo', $tpl->render($alpha));
|
||||
}
|
||||
public function testSectionObjectWithFunction()
|
||||
{
|
||||
$tpl = $this->mustache->loadTemplate('{{#foo}}{{name}}{{/foo}}');
|
||||
$alpha = new Mustache_Test_Functional_Alpha;
|
||||
$alpha->foo = new Mustache_Test_Functional_Delta;
|
||||
$this->assertEquals('Foo', $tpl->render($alpha));
|
||||
}
|
||||
}
|
||||
|
||||
class Mustache_Test_Functional_Alpha {
|
||||
public $foo;
|
||||
class Mustache_Test_Functional_Alpha
|
||||
{
|
||||
public $foo;
|
||||
|
||||
public function __construct() {
|
||||
$this->foo = new StdClass();
|
||||
$this->foo->name = 'Foo';
|
||||
$this->foo->number = 1;
|
||||
}
|
||||
public function __construct()
|
||||
{
|
||||
$this->foo = new StdClass();
|
||||
$this->foo->name = 'Foo';
|
||||
$this->foo->number = 1;
|
||||
}
|
||||
}
|
||||
|
||||
class Mustache_Test_Functional_Beta {
|
||||
protected $_data = array();
|
||||
class Mustache_Test_Functional_Beta
|
||||
{
|
||||
protected $_data = array();
|
||||
|
||||
public function __construct() {
|
||||
$this->_data['foo'] = new StdClass();
|
||||
$this->_data['foo']->name = 'Foo';
|
||||
$this->_data['foo']->number = 1;
|
||||
}
|
||||
public function __construct()
|
||||
{
|
||||
$this->_data['foo'] = new StdClass();
|
||||
$this->_data['foo']->name = 'Foo';
|
||||
$this->_data['foo']->number = 1;
|
||||
}
|
||||
|
||||
public function __isset($name) {
|
||||
return array_key_exists($name, $this->_data);
|
||||
}
|
||||
public function __isset($name)
|
||||
{
|
||||
return array_key_exists($name, $this->_data);
|
||||
}
|
||||
|
||||
public function __get($name) {
|
||||
return $this->_data[$name];
|
||||
}
|
||||
public function __get($name)
|
||||
{
|
||||
return $this->_data[$name];
|
||||
}
|
||||
}
|
||||
|
||||
class Mustache_Test_Functional_Gamma {
|
||||
public $bar;
|
||||
class Mustache_Test_Functional_Gamma
|
||||
{
|
||||
public $bar;
|
||||
|
||||
public function __construct() {
|
||||
$this->bar = new Mustache_Test_Functional_Beta;
|
||||
}
|
||||
public function __construct()
|
||||
{
|
||||
$this->bar = new Mustache_Test_Functional_Beta;
|
||||
}
|
||||
}
|
||||
|
||||
class Mustache_Test_Functional_Delta {
|
||||
protected $_name = 'Foo';
|
||||
class Mustache_Test_Functional_Delta
|
||||
{
|
||||
protected $_name = 'Foo';
|
||||
|
||||
public function name() {
|
||||
return $this->_name;
|
||||
}
|
||||
public function name()
|
||||
{
|
||||
return $this->_name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,27 +9,31 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
class Mustache_Test_HelperCollectionTest extends PHPUnit_Framework_TestCase {
|
||||
public function testConstructor() {
|
||||
$foo = array($this, 'getFoo');
|
||||
$bar = 'BAR';
|
||||
class Mustache_Test_HelperCollectionTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testConstructor()
|
||||
{
|
||||
$foo = array($this, 'getFoo');
|
||||
$bar = 'BAR';
|
||||
|
||||
$helpers = new Mustache_HelperCollection(array(
|
||||
'foo' => $foo,
|
||||
'bar' => $bar,
|
||||
));
|
||||
$helpers = new Mustache_HelperCollection(array(
|
||||
'foo' => $foo,
|
||||
'bar' => $bar,
|
||||
));
|
||||
|
||||
$this->assertSame($foo, $helpers->get('foo'));
|
||||
$this->assertSame($bar, $helpers->get('bar'));
|
||||
}
|
||||
$this->assertSame($foo, $helpers->get('foo'));
|
||||
$this->assertSame($bar, $helpers->get('bar'));
|
||||
}
|
||||
|
||||
public static function getFoo() {
|
||||
public static function getFoo()
|
||||
{
|
||||
echo 'foo';
|
||||
}
|
||||
|
||||
public function testAccessorsAndMutators() {
|
||||
$foo = array($this, 'getFoo');
|
||||
$bar = 'BAR';
|
||||
public function testAccessorsAndMutators()
|
||||
{
|
||||
$foo = array($this, 'getFoo');
|
||||
$bar = 'BAR';
|
||||
|
||||
$helpers = new Mustache_HelperCollection;
|
||||
$this->assertTrue($helpers->isEmpty());
|
||||
@@ -52,7 +56,8 @@ class Mustache_Test_HelperCollectionTest extends PHPUnit_Framework_TestCase {
|
||||
$this->assertTrue($helpers->has('bar'));
|
||||
}
|
||||
|
||||
public function testMagicMethods() {
|
||||
public function testMagicMethods()
|
||||
{
|
||||
$foo = array($this, 'getFoo');
|
||||
$bar = 'BAR';
|
||||
|
||||
@@ -88,7 +93,8 @@ class Mustache_Test_HelperCollectionTest extends PHPUnit_Framework_TestCase {
|
||||
/**
|
||||
* @dataProvider getInvalidHelperArguments
|
||||
*/
|
||||
public function testHelperCollectionIsntAfraidToThrowExceptions($helpers = array(), $actions = array(), $exception = null) {
|
||||
public function testHelperCollectionIsntAfraidToThrowExceptions($helpers = array(), $actions = array(), $exception = null)
|
||||
{
|
||||
if ($exception) {
|
||||
$this->setExpectedException($exception);
|
||||
}
|
||||
@@ -100,7 +106,8 @@ class Mustache_Test_HelperCollectionTest extends PHPUnit_Framework_TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public function getInvalidHelperArguments() {
|
||||
public function getInvalidHelperArguments()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'not helpers',
|
||||
|
||||
@@ -12,37 +12,41 @@
|
||||
/**
|
||||
* @group unit
|
||||
*/
|
||||
class Mustache_Test_Loader_ArrayLoaderTest extends PHPUnit_Framework_TestCase {
|
||||
public function testConstructor() {
|
||||
$loader = new Mustache_Loader_ArrayLoader(array(
|
||||
'foo' => 'bar'
|
||||
));
|
||||
class Mustache_Test_Loader_ArrayLoaderTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testConstructor()
|
||||
{
|
||||
$loader = new Mustache_Loader_ArrayLoader(array(
|
||||
'foo' => 'bar'
|
||||
));
|
||||
|
||||
$this->assertEquals('bar', $loader->load('foo'));
|
||||
}
|
||||
$this->assertEquals('bar', $loader->load('foo'));
|
||||
}
|
||||
|
||||
public function testSetAndLoadTemplates() {
|
||||
$loader = new Mustache_Loader_ArrayLoader(array(
|
||||
'foo' => 'bar'
|
||||
));
|
||||
$this->assertEquals('bar', $loader->load('foo'));
|
||||
public function testSetAndLoadTemplates()
|
||||
{
|
||||
$loader = new Mustache_Loader_ArrayLoader(array(
|
||||
'foo' => 'bar'
|
||||
));
|
||||
$this->assertEquals('bar', $loader->load('foo'));
|
||||
|
||||
$loader->setTemplate('baz', 'qux');
|
||||
$this->assertEquals('qux', $loader->load('baz'));
|
||||
$loader->setTemplate('baz', 'qux');
|
||||
$this->assertEquals('qux', $loader->load('baz'));
|
||||
|
||||
$loader->setTemplates(array(
|
||||
'foo' => 'FOO',
|
||||
'baz' => 'BAZ',
|
||||
));
|
||||
$this->assertEquals('FOO', $loader->load('foo'));
|
||||
$this->assertEquals('BAZ', $loader->load('baz'));
|
||||
}
|
||||
$loader->setTemplates(array(
|
||||
'foo' => 'FOO',
|
||||
'baz' => 'BAZ',
|
||||
));
|
||||
$this->assertEquals('FOO', $loader->load('foo'));
|
||||
$this->assertEquals('BAZ', $loader->load('baz'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
public function testMissingTemplatesThrowExceptions() {
|
||||
$loader = new Mustache_Loader_ArrayLoader;
|
||||
$loader->load('not_a_real_template');
|
||||
}
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
public function testMissingTemplatesThrowExceptions()
|
||||
{
|
||||
$loader = new Mustache_Loader_ArrayLoader;
|
||||
$loader->load('not_a_real_template');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,35 +12,40 @@
|
||||
/**
|
||||
* @group unit
|
||||
*/
|
||||
class Mustache_Test_Loader_FilesystemLoaderTest extends PHPUnit_Framework_TestCase {
|
||||
public function testConstructor() {
|
||||
$baseDir = realpath(dirname(__FILE__).'/../../../fixtures/templates');
|
||||
$loader = new Mustache_Loader_FilesystemLoader($baseDir, array('extension' => '.ms'));
|
||||
$this->assertEquals('alpha contents', $loader->load('alpha'));
|
||||
$this->assertEquals('beta contents', $loader->load('beta.ms'));
|
||||
}
|
||||
class Mustache_Test_Loader_FilesystemLoaderTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testConstructor()
|
||||
{
|
||||
$baseDir = realpath(dirname(__FILE__).'/../../../fixtures/templates');
|
||||
$loader = new Mustache_Loader_FilesystemLoader($baseDir, array('extension' => '.ms'));
|
||||
$this->assertEquals('alpha contents', $loader->load('alpha'));
|
||||
$this->assertEquals('beta contents', $loader->load('beta.ms'));
|
||||
}
|
||||
|
||||
public function testLoadTemplates() {
|
||||
$baseDir = realpath(dirname(__FILE__).'/../../../fixtures/templates');
|
||||
$loader = new Mustache_Loader_FilesystemLoader($baseDir);
|
||||
$this->assertEquals('one contents', $loader->load('one'));
|
||||
$this->assertEquals('two contents', $loader->load('two.mustache'));
|
||||
}
|
||||
public function testLoadTemplates()
|
||||
{
|
||||
$baseDir = realpath(dirname(__FILE__).'/../../../fixtures/templates');
|
||||
$loader = new Mustache_Loader_FilesystemLoader($baseDir);
|
||||
$this->assertEquals('one contents', $loader->load('one'));
|
||||
$this->assertEquals('two contents', $loader->load('two.mustache'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException RuntimeException
|
||||
*/
|
||||
public function testMissingBaseDirThrowsException() {
|
||||
$loader = new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/not_a_directory');
|
||||
}
|
||||
/**
|
||||
* @expectedException RuntimeException
|
||||
*/
|
||||
public function testMissingBaseDirThrowsException()
|
||||
{
|
||||
$loader = new Mustache_Loader_FilesystemLoader(dirname(__FILE__).'/not_a_directory');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
public function testMissingTemplateThrowsException() {
|
||||
$baseDir = realpath(dirname(__FILE__).'/../../../fixtures/templates');
|
||||
$loader = new Mustache_Loader_FilesystemLoader($baseDir);
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
public function testMissingTemplateThrowsException()
|
||||
{
|
||||
$baseDir = realpath(dirname(__FILE__).'/../../../fixtures/templates');
|
||||
$loader = new Mustache_Loader_FilesystemLoader($baseDir);
|
||||
|
||||
$loader->load('fake');
|
||||
}
|
||||
$loader->load('fake');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,12 +12,14 @@
|
||||
/**
|
||||
* @group unit
|
||||
*/
|
||||
class Mustache_Test_Loader_StringLoaderTest extends PHPUnit_Framework_TestCase {
|
||||
public function testLoadTemplates() {
|
||||
$loader = new Mustache_Loader_StringLoader;
|
||||
class Mustache_Test_Loader_StringLoaderTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testLoadTemplates()
|
||||
{
|
||||
$loader = new Mustache_Loader_StringLoader;
|
||||
|
||||
$this->assertEquals('foo', $loader->load('foo'));
|
||||
$this->assertEquals('{{ bar }}', $loader->load('{{ bar }}'));
|
||||
$this->assertEquals("\n{{! comment }}\n", $loader->load("\n{{! comment }}\n"));
|
||||
}
|
||||
$this->assertEquals('foo', $loader->load('foo'));
|
||||
$this->assertEquals('{{ bar }}', $loader->load('{{ bar }}'));
|
||||
$this->assertEquals("\n{{! comment }}\n", $loader->load("\n{{! comment }}\n"));
|
||||
}
|
||||
}
|
||||
|
||||
+156
-153
@@ -12,168 +12,171 @@
|
||||
/**
|
||||
* @group unit
|
||||
*/
|
||||
class Mustache_Test_ParserTest extends PHPUnit_Framework_TestCase {
|
||||
class Mustache_Test_ParserTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @dataProvider getTokenSets
|
||||
*/
|
||||
public function testParse($tokens, $expected)
|
||||
{
|
||||
$parser = new Mustache_Parser;
|
||||
$this->assertEquals($expected, $parser->parse($tokens));
|
||||
}
|
||||
/**
|
||||
* @dataProvider getTokenSets
|
||||
*/
|
||||
public function testParse($tokens, $expected)
|
||||
{
|
||||
$parser = new Mustache_Parser;
|
||||
$this->assertEquals($expected, $parser->parse($tokens));
|
||||
}
|
||||
|
||||
public function getTokenSets()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
array(),
|
||||
array()
|
||||
),
|
||||
public function getTokenSets()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
array(),
|
||||
array()
|
||||
),
|
||||
|
||||
array(
|
||||
array(array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => 'text'
|
||||
)),
|
||||
array(array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => 'text'
|
||||
)),
|
||||
),
|
||||
array(
|
||||
array(array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => 'text'
|
||||
)),
|
||||
array(array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => 'text'
|
||||
)),
|
||||
),
|
||||
|
||||
array(
|
||||
array(array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'name'
|
||||
)),
|
||||
array(array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'name'
|
||||
)),
|
||||
),
|
||||
array(
|
||||
array(array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'name'
|
||||
)),
|
||||
array(array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'name'
|
||||
)),
|
||||
),
|
||||
|
||||
array(
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => 'foo'
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_INVERTED,
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
Mustache_Tokenizer::NAME => 'parent'
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'name'
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
|
||||
Mustache_Tokenizer::INDEX => 456,
|
||||
Mustache_Tokenizer::NAME => 'parent'
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => 'bar'
|
||||
),
|
||||
),
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => 'foo'
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_INVERTED,
|
||||
Mustache_Tokenizer::NAME => 'parent',
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
Mustache_Tokenizer::END => 456,
|
||||
Mustache_Tokenizer::NODES => array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'name'
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => 'bar'
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => 'foo'
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_INVERTED,
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
Mustache_Tokenizer::NAME => 'parent'
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'name'
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
|
||||
Mustache_Tokenizer::INDEX => 456,
|
||||
Mustache_Tokenizer::NAME => 'parent'
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => 'bar'
|
||||
),
|
||||
),
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => 'foo'
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_INVERTED,
|
||||
Mustache_Tokenizer::NAME => 'parent',
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
Mustache_Tokenizer::END => 456,
|
||||
Mustache_Tokenizer::NODES => array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'name'
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => 'bar'
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getBadParseTrees
|
||||
* @expectedException LogicException
|
||||
*/
|
||||
public function testParserThrowsExceptions($tokens) {
|
||||
$parser = new Mustache_Parser;
|
||||
$parser->parse($tokens);
|
||||
}
|
||||
/**
|
||||
* @dataProvider getBadParseTrees
|
||||
* @expectedException LogicException
|
||||
*/
|
||||
public function testParserThrowsExceptions($tokens)
|
||||
{
|
||||
$parser = new Mustache_Parser;
|
||||
$parser->parse($tokens);
|
||||
}
|
||||
|
||||
public function getBadParseTrees() {
|
||||
return array(
|
||||
// no close
|
||||
array(
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_SECTION,
|
||||
Mustache_Tokenizer::NAME => 'parent',
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
),
|
||||
),
|
||||
),
|
||||
public function getBadParseTrees()
|
||||
{
|
||||
return array(
|
||||
// no close
|
||||
array(
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_SECTION,
|
||||
Mustache_Tokenizer::NAME => 'parent',
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// no close inverted
|
||||
array(
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_INVERTED,
|
||||
Mustache_Tokenizer::NAME => 'parent',
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
),
|
||||
),
|
||||
),
|
||||
// no close inverted
|
||||
array(
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_INVERTED,
|
||||
Mustache_Tokenizer::NAME => 'parent',
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// no opening inverted
|
||||
array(
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
|
||||
Mustache_Tokenizer::NAME => 'parent',
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
),
|
||||
),
|
||||
),
|
||||
// no opening inverted
|
||||
array(
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
|
||||
Mustache_Tokenizer::NAME => 'parent',
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// weird nesting
|
||||
array(
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_SECTION,
|
||||
Mustache_Tokenizer::NAME => 'parent',
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_SECTION,
|
||||
Mustache_Tokenizer::NAME => 'child',
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
|
||||
Mustache_Tokenizer::NAME => 'parent',
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
|
||||
Mustache_Tokenizer::NAME => 'child',
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
// weird nesting
|
||||
array(
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_SECTION,
|
||||
Mustache_Tokenizer::NAME => 'parent',
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_SECTION,
|
||||
Mustache_Tokenizer::NAME => 'child',
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
|
||||
Mustache_Tokenizer::NAME => 'parent',
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
|
||||
Mustache_Tokenizer::NAME => 'child',
|
||||
Mustache_Tokenizer::INDEX => 123,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,38 +12,44 @@
|
||||
/**
|
||||
* @group unit
|
||||
*/
|
||||
class Mustache_Test_TemplateTest extends PHPUnit_Framework_TestCase {
|
||||
public function testConstructor() {
|
||||
$mustache = new Mustache_Engine;
|
||||
$template = new Mustache_Test_TemplateStub($mustache);
|
||||
$this->assertSame($mustache, $template->getMustache());
|
||||
}
|
||||
class Mustache_Test_TemplateTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testConstructor()
|
||||
{
|
||||
$mustache = new Mustache_Engine;
|
||||
$template = new Mustache_Test_TemplateStub($mustache);
|
||||
$this->assertSame($mustache, $template->getMustache());
|
||||
}
|
||||
|
||||
public function testRendering() {
|
||||
$rendered = '<< wheee >>';
|
||||
$mustache = new Mustache_Engine;
|
||||
$template = new Mustache_Test_TemplateStub($mustache);
|
||||
$template->rendered = $rendered;
|
||||
$context = new Mustache_Context;
|
||||
public function testRendering()
|
||||
{
|
||||
$rendered = '<< wheee >>';
|
||||
$mustache = new Mustache_Engine;
|
||||
$template = new Mustache_Test_TemplateStub($mustache);
|
||||
$template->rendered = $rendered;
|
||||
$context = new Mustache_Context;
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
|
||||
$this->assertEquals($rendered, $template());
|
||||
}
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
|
||||
$this->assertEquals($rendered, $template());
|
||||
}
|
||||
|
||||
$this->assertEquals($rendered, $template->render());
|
||||
$this->assertEquals($rendered, $template->renderInternal($context));
|
||||
$this->assertEquals($rendered, $template->render(array('foo' => 'bar')));
|
||||
}
|
||||
$this->assertEquals($rendered, $template->render());
|
||||
$this->assertEquals($rendered, $template->renderInternal($context));
|
||||
$this->assertEquals($rendered, $template->render(array('foo' => 'bar')));
|
||||
}
|
||||
}
|
||||
|
||||
class Mustache_Test_TemplateStub extends Mustache_Template {
|
||||
public $rendered;
|
||||
class Mustache_Test_TemplateStub extends Mustache_Template
|
||||
{
|
||||
public $rendered;
|
||||
|
||||
public function getMustache() {
|
||||
return $this->mustache;
|
||||
}
|
||||
public function getMustache()
|
||||
{
|
||||
return $this->mustache;
|
||||
}
|
||||
|
||||
public function renderInternal(Mustache_Context $context, $indent = '', $escape = false) {
|
||||
return $this->rendered;
|
||||
}
|
||||
public function renderInternal(Mustache_Context $context, $indent = '', $escape = false)
|
||||
{
|
||||
return $this->rendered;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,130 +12,133 @@
|
||||
/**
|
||||
* @group unit
|
||||
*/
|
||||
class Mustache_Test_TokenizerTest extends PHPUnit_Framework_TestCase {
|
||||
class Mustache_Test_TokenizerTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @dataProvider getTokens
|
||||
*/
|
||||
public function testScan($text, $delimiters, $expected) {
|
||||
$tokenizer = new Mustache_Tokenizer;
|
||||
$this->assertSame($expected, $tokenizer->scan($text, $delimiters));
|
||||
}
|
||||
/**
|
||||
* @dataProvider getTokens
|
||||
*/
|
||||
public function testScan($text, $delimiters, $expected)
|
||||
{
|
||||
$tokenizer = new Mustache_Tokenizer;
|
||||
$this->assertSame($expected, $tokenizer->scan($text, $delimiters));
|
||||
}
|
||||
|
||||
public function getTokens() {
|
||||
return array(
|
||||
array(
|
||||
'text',
|
||||
null,
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => 'text',
|
||||
),
|
||||
),
|
||||
),
|
||||
public function getTokens()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'text',
|
||||
null,
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => 'text',
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
array(
|
||||
'text',
|
||||
'<<< >>>',
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => 'text',
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'text',
|
||||
'<<< >>>',
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => 'text',
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
array(
|
||||
'{{ name }}',
|
||||
null,
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'name',
|
||||
Mustache_Tokenizer::OTAG => '{{',
|
||||
Mustache_Tokenizer::CTAG => '}}',
|
||||
Mustache_Tokenizer::INDEX => 10,
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'{{ name }}',
|
||||
null,
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'name',
|
||||
Mustache_Tokenizer::OTAG => '{{',
|
||||
Mustache_Tokenizer::CTAG => '}}',
|
||||
Mustache_Tokenizer::INDEX => 10,
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
array(
|
||||
'{{ name }}',
|
||||
'<<< >>>',
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => '{{ name }}',
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'{{ name }}',
|
||||
'<<< >>>',
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => '{{ name }}',
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
array(
|
||||
'<<< name >>>',
|
||||
'<<< >>>',
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'name',
|
||||
Mustache_Tokenizer::OTAG => '<<<',
|
||||
Mustache_Tokenizer::CTAG => '>>>',
|
||||
Mustache_Tokenizer::INDEX => 12,
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'<<< name >>>',
|
||||
'<<< >>>',
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'name',
|
||||
Mustache_Tokenizer::OTAG => '<<<',
|
||||
Mustache_Tokenizer::CTAG => '>>>',
|
||||
Mustache_Tokenizer::INDEX => 12,
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
array(
|
||||
"{{{ a }}}\n{{# b }} \n{{= | | =}}| c ||/ b |\n|{ d }|",
|
||||
null,
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_UNESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'a',
|
||||
Mustache_Tokenizer::OTAG => '{{',
|
||||
Mustache_Tokenizer::CTAG => '}}',
|
||||
Mustache_Tokenizer::INDEX => 8,
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => "\n",
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_SECTION,
|
||||
Mustache_Tokenizer::NAME => 'b',
|
||||
Mustache_Tokenizer::OTAG => '{{',
|
||||
Mustache_Tokenizer::CTAG => '}}',
|
||||
Mustache_Tokenizer::INDEX => 18,
|
||||
),
|
||||
null,
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'c',
|
||||
Mustache_Tokenizer::OTAG => '|',
|
||||
Mustache_Tokenizer::CTAG => '|',
|
||||
Mustache_Tokenizer::INDEX => 37,
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
|
||||
Mustache_Tokenizer::NAME => 'b',
|
||||
Mustache_Tokenizer::OTAG => '|',
|
||||
Mustache_Tokenizer::CTAG => '|',
|
||||
Mustache_Tokenizer::INDEX => 37,
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => "\n",
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_UNESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'd',
|
||||
Mustache_Tokenizer::OTAG => '|',
|
||||
Mustache_Tokenizer::CTAG => '|',
|
||||
Mustache_Tokenizer::INDEX => 51,
|
||||
),
|
||||
array(
|
||||
"{{{ a }}}\n{{# b }} \n{{= | | =}}| c ||/ b |\n|{ d }|",
|
||||
null,
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_UNESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'a',
|
||||
Mustache_Tokenizer::OTAG => '{{',
|
||||
Mustache_Tokenizer::CTAG => '}}',
|
||||
Mustache_Tokenizer::INDEX => 8,
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => "\n",
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_SECTION,
|
||||
Mustache_Tokenizer::NAME => 'b',
|
||||
Mustache_Tokenizer::OTAG => '{{',
|
||||
Mustache_Tokenizer::CTAG => '}}',
|
||||
Mustache_Tokenizer::INDEX => 18,
|
||||
),
|
||||
null,
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'c',
|
||||
Mustache_Tokenizer::OTAG => '|',
|
||||
Mustache_Tokenizer::CTAG => '|',
|
||||
Mustache_Tokenizer::INDEX => 37,
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_END_SECTION,
|
||||
Mustache_Tokenizer::NAME => 'b',
|
||||
Mustache_Tokenizer::OTAG => '|',
|
||||
Mustache_Tokenizer::CTAG => '|',
|
||||
Mustache_Tokenizer::INDEX => 37,
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::VALUE => "\n",
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_UNESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'd',
|
||||
Mustache_Tokenizer::OTAG => '|',
|
||||
Mustache_Tokenizer::CTAG => '|',
|
||||
Mustache_Tokenizer::INDEX => 51,
|
||||
),
|
||||
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -9,6 +9,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
class Mustache_Bar {
|
||||
// nada
|
||||
class Mustache_Bar
|
||||
{
|
||||
// nada
|
||||
}
|
||||
|
||||
+3
-2
@@ -9,6 +9,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
class Mustache_Foo {
|
||||
// nada
|
||||
class Mustache_Foo
|
||||
{
|
||||
// nada
|
||||
}
|
||||
|
||||
+3
-2
@@ -9,6 +9,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
class NonMustacheClass {
|
||||
// noop
|
||||
class NonMustacheClass
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
+10
-9
@@ -1,13 +1,14 @@
|
||||
<?php
|
||||
|
||||
class ChildContext {
|
||||
public $parent = array(
|
||||
'child' => 'child works',
|
||||
);
|
||||
class ChildContext
|
||||
{
|
||||
public $parent = array(
|
||||
'child' => 'child works',
|
||||
);
|
||||
|
||||
public $grandparent = array(
|
||||
'parent' => array(
|
||||
'child' => 'grandchild works',
|
||||
),
|
||||
);
|
||||
public $grandparent = array(
|
||||
'parent' => array(
|
||||
'child' => 'grandchild works',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
+6
-4
@@ -1,7 +1,9 @@
|
||||
<?php
|
||||
|
||||
class Comments {
|
||||
public function title() {
|
||||
return 'A Comedy of Errors';
|
||||
}
|
||||
class Comments
|
||||
{
|
||||
public function title()
|
||||
{
|
||||
return 'A Comedy of Errors';
|
||||
}
|
||||
}
|
||||
|
||||
+16
-13
@@ -1,19 +1,22 @@
|
||||
<?php
|
||||
|
||||
class Complex {
|
||||
public $header = 'Colors';
|
||||
class Complex
|
||||
{
|
||||
public $header = 'Colors';
|
||||
|
||||
public $item = array(
|
||||
array('name' => 'red', 'current' => true, 'url' => '#Red'),
|
||||
array('name' => 'green', 'current' => false, 'url' => '#Green'),
|
||||
array('name' => 'blue', 'current' => false, 'url' => '#Blue'),
|
||||
);
|
||||
public $item = array(
|
||||
array('name' => 'red', 'current' => true, 'url' => '#Red'),
|
||||
array('name' => 'green', 'current' => false, 'url' => '#Green'),
|
||||
array('name' => 'blue', 'current' => false, 'url' => '#Blue'),
|
||||
);
|
||||
|
||||
public function notEmpty() {
|
||||
return !($this->isEmpty());
|
||||
}
|
||||
public function notEmpty()
|
||||
{
|
||||
return !($this->isEmpty());
|
||||
}
|
||||
|
||||
public function isEmpty() {
|
||||
return count($this->item) === 0;
|
||||
}
|
||||
public function isEmpty()
|
||||
{
|
||||
return count($this->item) === 0;
|
||||
}
|
||||
}
|
||||
|
||||
+11
-9
@@ -1,14 +1,16 @@
|
||||
<?php
|
||||
|
||||
class Delimiters {
|
||||
public $start = "It worked the first time.";
|
||||
class Delimiters
|
||||
{
|
||||
public $start = "It worked the first time.";
|
||||
|
||||
public function middle() {
|
||||
return array(
|
||||
array('item' => "And it worked the second time."),
|
||||
array('item' => "As well as the third."),
|
||||
);
|
||||
}
|
||||
public function middle()
|
||||
{
|
||||
return array(
|
||||
array('item' => "And it worked the second time."),
|
||||
array('item' => "As well as the third."),
|
||||
);
|
||||
}
|
||||
|
||||
public $final = "Then, surprisingly, it worked the final time.";
|
||||
public $final = "Then, surprisingly, it worked the final time.";
|
||||
}
|
||||
|
||||
+11
-10
@@ -1,14 +1,15 @@
|
||||
<?php
|
||||
|
||||
class DotNotation {
|
||||
public $person = array(
|
||||
'name' => array('first' => 'Chris', 'last' => 'Firescythe'),
|
||||
'age' => 24,
|
||||
'hometown' => array(
|
||||
'city' => 'Cincinnati',
|
||||
'state' => 'OH',
|
||||
)
|
||||
);
|
||||
class DotNotation
|
||||
{
|
||||
public $person = array(
|
||||
'name' => array('first' => 'Chris', 'last' => 'Firescythe'),
|
||||
'age' => 24,
|
||||
'hometown' => array(
|
||||
'city' => 'Cincinnati',
|
||||
'state' => 'OH',
|
||||
)
|
||||
);
|
||||
|
||||
public $normal = 'Normal';
|
||||
public $normal = 'Normal';
|
||||
}
|
||||
|
||||
+7
-5
@@ -1,9 +1,11 @@
|
||||
<?php
|
||||
|
||||
class DoubleSection {
|
||||
public function t() {
|
||||
return true;
|
||||
}
|
||||
class DoubleSection
|
||||
{
|
||||
public function t()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public $two = "second";
|
||||
public $two = "second";
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
class Escaped {
|
||||
public $title = '"Bear" > "Shark"';
|
||||
class Escaped
|
||||
{
|
||||
public $title = '"Bear" > "Shark"';
|
||||
}
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
<?php
|
||||
|
||||
class GrandParentContext {
|
||||
public $grand_parent_id = 'grand_parent1';
|
||||
public $parent_contexts = array();
|
||||
class GrandParentContext
|
||||
{
|
||||
public $grand_parent_id = 'grand_parent1';
|
||||
public $parent_contexts = array();
|
||||
|
||||
public function __construct() {
|
||||
$this->parent_contexts[] = array('parent_id' => 'parent1', 'child_contexts' => array(
|
||||
array('child_id' => 'parent1-child1'),
|
||||
array('child_id' => 'parent1-child2')
|
||||
));
|
||||
public function __construct()
|
||||
{
|
||||
$this->parent_contexts[] = array('parent_id' => 'parent1', 'child_contexts' => array(
|
||||
array('child_id' => 'parent1-child1'),
|
||||
array('child_id' => 'parent1-child2')
|
||||
));
|
||||
|
||||
$parent2 = new stdClass();
|
||||
$parent2->parent_id = 'parent2';
|
||||
$parent2->child_contexts = array(
|
||||
array('child_id' => 'parent2-child1'),
|
||||
array('child_id' => 'parent2-child2')
|
||||
);
|
||||
$parent2 = new stdClass();
|
||||
$parent2->parent_id = 'parent2';
|
||||
$parent2->child_contexts = array(
|
||||
array('child_id' => 'parent2-child1'),
|
||||
array('child_id' => 'parent2-child2')
|
||||
);
|
||||
|
||||
$this->parent_contexts[] = $parent2;
|
||||
}
|
||||
$this->parent_contexts[] = $parent2;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+4
-2
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
class I18n {
|
||||
class I18n
|
||||
{
|
||||
|
||||
// Variable to be interpolated
|
||||
public $name = 'Bob';
|
||||
@@ -14,7 +15,8 @@ class I18n {
|
||||
'My name is {{ name }}.' => 'Me llamo {{ name }}.',
|
||||
);
|
||||
|
||||
public static function __trans($text) {
|
||||
public static function __trans($text)
|
||||
{
|
||||
return isset(self::$dictionary[$text]) ? self::$dictionary[$text] : $text;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
class ImplicitIterator {
|
||||
public $data = array('Donkey Kong', 'Luigi', 'Mario', 'Peach', 'Yoshi');
|
||||
class ImplicitIterator
|
||||
{
|
||||
public $data = array('Donkey Kong', 'Luigi', 'Mario', 'Peach', 'Yoshi');
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
class InvertedDoubleSection {
|
||||
public $t = false;
|
||||
public $two = 'second';
|
||||
class InvertedDoubleSection
|
||||
{
|
||||
public $t = false;
|
||||
public $two = 'second';
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
class InvertedSection {
|
||||
public $repo = array();
|
||||
class InvertedSection
|
||||
{
|
||||
public $repo = array();
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
<?php
|
||||
|
||||
class RecursivePartials {
|
||||
public $name = 'George';
|
||||
public $child = array(
|
||||
'name' => 'Dan',
|
||||
'child' => array(
|
||||
'name' => 'Justin',
|
||||
'child' => false,
|
||||
)
|
||||
);
|
||||
class RecursivePartials
|
||||
{
|
||||
public $name = 'George';
|
||||
public $child = array(
|
||||
'name' => 'Dan',
|
||||
'child' => array(
|
||||
'name' => 'Justin',
|
||||
'child' => false,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
+12
-10
@@ -1,16 +1,18 @@
|
||||
<?php
|
||||
|
||||
class SectionIteratorObjects {
|
||||
public $start = "It worked the first time.";
|
||||
class SectionIteratorObjects
|
||||
{
|
||||
public $start = "It worked the first time.";
|
||||
|
||||
protected $_data = array(
|
||||
array('item' => 'And it worked the second time.'),
|
||||
array('item' => 'As well as the third.'),
|
||||
);
|
||||
protected $_data = array(
|
||||
array('item' => 'And it worked the second time.'),
|
||||
array('item' => 'As well as the third.'),
|
||||
);
|
||||
|
||||
public function middle() {
|
||||
return new ArrayIterator($this->_data);
|
||||
}
|
||||
public function middle()
|
||||
{
|
||||
return new ArrayIterator($this->_data);
|
||||
}
|
||||
|
||||
public $final = "Then, surprisingly, it worked the final time.";
|
||||
public $final = "Then, surprisingly, it worked the final time.";
|
||||
}
|
||||
|
||||
@@ -1,26 +1,31 @@
|
||||
<?php
|
||||
|
||||
class SectionMagicObjects {
|
||||
public $start = "It worked the first time.";
|
||||
class SectionMagicObjects
|
||||
{
|
||||
public $start = "It worked the first time.";
|
||||
|
||||
public function middle() {
|
||||
return new MagicObject();
|
||||
}
|
||||
public function middle()
|
||||
{
|
||||
return new MagicObject();
|
||||
}
|
||||
|
||||
public $final = "Then, surprisingly, it worked the final time.";
|
||||
public $final = "Then, surprisingly, it worked the final time.";
|
||||
}
|
||||
|
||||
class MagicObject {
|
||||
protected $_data = array(
|
||||
'foo' => 'And it worked the second time.',
|
||||
'bar' => 'As well as the third.'
|
||||
);
|
||||
class MagicObject
|
||||
{
|
||||
protected $_data = array(
|
||||
'foo' => 'And it worked the second time.',
|
||||
'bar' => 'As well as the third.'
|
||||
);
|
||||
|
||||
public function __get($key) {
|
||||
return isset($this->_data[$key]) ? $this->_data[$key] : NULL;
|
||||
}
|
||||
public function __get($key)
|
||||
{
|
||||
return isset($this->_data[$key]) ? $this->_data[$key] : NULL;
|
||||
}
|
||||
|
||||
public function __isset($key) {
|
||||
return isset($this->_data[$key]);
|
||||
}
|
||||
public function __isset($key)
|
||||
{
|
||||
return isset($this->_data[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-9
@@ -1,16 +1,19 @@
|
||||
<?php
|
||||
|
||||
class SectionObjects {
|
||||
public $start = "It worked the first time.";
|
||||
class SectionObjects
|
||||
{
|
||||
public $start = "It worked the first time.";
|
||||
|
||||
public function middle() {
|
||||
return new SectionObject;
|
||||
}
|
||||
public function middle()
|
||||
{
|
||||
return new SectionObject;
|
||||
}
|
||||
|
||||
public $final = "Then, surprisingly, it worked the final time.";
|
||||
public $final = "Then, surprisingly, it worked the final time.";
|
||||
}
|
||||
|
||||
class SectionObject {
|
||||
public $foo = 'And it worked the second time.';
|
||||
public $bar = 'As well as the third.';
|
||||
class SectionObject
|
||||
{
|
||||
public $foo = 'And it worked the second time.';
|
||||
public $bar = 'As well as the third.';
|
||||
}
|
||||
|
||||
+11
-9
@@ -1,14 +1,16 @@
|
||||
<?php
|
||||
|
||||
class Sections {
|
||||
public $start = "It worked the first time.";
|
||||
class Sections
|
||||
{
|
||||
public $start = "It worked the first time.";
|
||||
|
||||
public function middle() {
|
||||
return array(
|
||||
array('item' => "And it worked the second time."),
|
||||
array('item' => "As well as the third."),
|
||||
);
|
||||
}
|
||||
public function middle()
|
||||
{
|
||||
return array(
|
||||
array('item' => "And it worked the second time."),
|
||||
array('item' => "As well as the third."),
|
||||
);
|
||||
}
|
||||
|
||||
public $final = "Then, surprisingly, it worked the final time.";
|
||||
public $final = "Then, surprisingly, it worked the final time.";
|
||||
}
|
||||
|
||||
+31
-29
@@ -1,33 +1,35 @@
|
||||
<?php
|
||||
|
||||
class SectionsNested {
|
||||
public $name = 'Little Mac';
|
||||
class SectionsNested
|
||||
{
|
||||
public $name = 'Little Mac';
|
||||
|
||||
public function enemies() {
|
||||
return array(
|
||||
array(
|
||||
'name' => 'Von Kaiser',
|
||||
'enemies' => array(
|
||||
array('name' => 'Super Macho Man'),
|
||||
array('name' => 'Piston Honda'),
|
||||
array('name' => 'Mr. Sandman'),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'name' => 'Mike Tyson',
|
||||
'enemies' => array(
|
||||
array('name' => 'Soda Popinski'),
|
||||
array('name' => 'King Hippo'),
|
||||
array('name' => 'Great Tiger'),
|
||||
array('name' => 'Glass Joe'),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'name' => 'Don Flamenco',
|
||||
'enemies' => array(
|
||||
array('name' => 'Bald Bull'),
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
public function enemies()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'name' => 'Von Kaiser',
|
||||
'enemies' => array(
|
||||
array('name' => 'Super Macho Man'),
|
||||
array('name' => 'Piston Honda'),
|
||||
array('name' => 'Mr. Sandman'),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'name' => 'Mike Tyson',
|
||||
'enemies' => array(
|
||||
array('name' => 'Soda Popinski'),
|
||||
array('name' => 'King Hippo'),
|
||||
array('name' => 'Great Tiger'),
|
||||
array('name' => 'Glass Joe'),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'name' => 'Don Flamenco',
|
||||
'enemies' => array(
|
||||
array('name' => 'Bald Bull'),
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-7
@@ -1,12 +1,14 @@
|
||||
<?php
|
||||
|
||||
class Simple {
|
||||
public $name = "Chris";
|
||||
public $value = 10000;
|
||||
class Simple
|
||||
{
|
||||
public $name = "Chris";
|
||||
public $value = 10000;
|
||||
|
||||
public function taxed_value() {
|
||||
return $this->value - ($this->value * 0.4);
|
||||
}
|
||||
public function taxed_value()
|
||||
{
|
||||
return $this->value - ($this->value * 0.4);
|
||||
}
|
||||
|
||||
public $in_ca = true;
|
||||
public $in_ca = true;
|
||||
};
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
class Unescaped {
|
||||
public $title = "Bear > Shark";
|
||||
class Unescaped
|
||||
{
|
||||
public $title = "Bear > Shark";
|
||||
}
|
||||
|
||||
Vendored
+3
-2
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
class UTF8 {
|
||||
public $test = '中文又来啦';
|
||||
class UTF8
|
||||
{
|
||||
public $test = '中文又来啦';
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
class UTF8Unescaped {
|
||||
public $test = '中文又来啦';
|
||||
class UTF8Unescaped
|
||||
{
|
||||
public $test = '中文又来啦';
|
||||
}
|
||||
|
||||
+20
-17
@@ -8,24 +8,27 @@
|
||||
*
|
||||
* `{{> tag }}` and `{{> tag}}` and `{{>tag}}` should all be equivalent.
|
||||
*/
|
||||
class Whitespace {
|
||||
public $foo = 'alpha';
|
||||
class Whitespace
|
||||
{
|
||||
public $foo = 'alpha';
|
||||
|
||||
public $bar = 'beta';
|
||||
public $bar = 'beta';
|
||||
|
||||
public function baz() {
|
||||
return 'gamma';
|
||||
}
|
||||
public function baz()
|
||||
{
|
||||
return 'gamma';
|
||||
}
|
||||
|
||||
public function qux() {
|
||||
return array(
|
||||
array('key with space' => 'A'),
|
||||
array('key with space' => 'B'),
|
||||
array('key with space' => 'C'),
|
||||
array('key with space' => 'D'),
|
||||
array('key with space' => 'E'),
|
||||
array('key with space' => 'F'),
|
||||
array('key with space' => 'G'),
|
||||
);
|
||||
}
|
||||
public function qux()
|
||||
{
|
||||
return array(
|
||||
array('key with space' => 'A'),
|
||||
array('key with space' => 'B'),
|
||||
array('key with space' => 'C'),
|
||||
array('key with space' => 'D'),
|
||||
array('key with space' => 'E'),
|
||||
array('key with space' => 'F'),
|
||||
array('key with space' => 'G'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user