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