Refactory template ctor

Dev extends
This commit is contained in:
bzick
2013-02-13 20:51:27 +04:00
parent 95daa95cd2
commit 8c618c2b34
8 changed files with 260 additions and 136 deletions

View File

@ -94,7 +94,7 @@ class Aspect {
protected $_on_post_cmp = array(); protected $_on_post_cmp = array();
/** /**
* @var Aspect\Provider * @var ProviderInterface
*/ */
private $_provider; private $_provider;
/** /**
@ -107,7 +107,9 @@ class Aspect {
*/ */
protected $_modifiers = array( protected $_modifiers = array(
"upper" => 'strtoupper', "upper" => 'strtoupper',
"up" => 'strtoupper',
"lower" => 'strtolower', "lower" => 'strtolower',
"low" => 'strtolower',
"date_format" => 'Aspect\Modifier::dateFormat', "date_format" => 'Aspect\Modifier::dateFormat',
"date" => 'Aspect\Modifier::date', "date" => 'Aspect\Modifier::date',
"truncate" => 'Aspect\Modifier::truncate', "truncate" => 'Aspect\Modifier::truncate',
@ -123,9 +125,9 @@ class Aspect {
* @var array of allowed PHP functions * @var array of allowed PHP functions
*/ */
protected $_allowed_funcs = array( protected $_allowed_funcs = array(
"empty" => 1, "isset" => 1, "count" => 1, "is_string" => 1, "is_array" => 1, "is_numeric" => 1, "is_int" => 1, "count" => 1, "is_string" => 1, "is_array" => 1, "is_numeric" => 1, "is_int" => 1,
"is_object" => 1, "strtotime" => 1, "gettype" => 1, "is_double" => 1, "json_encode" => 1, "json_decode" => 1, "is_object" => 1, "strtotime" => 1, "gettype" => 1, "is_double" => 1, "json_encode" => 1, "json_decode" => 1,
"ip2long" => 1, "long2ip" => 1, "strip_tags" => 1, "nl2br" => 1 "ip2long" => 1, "long2ip" => 1, "strip_tags" => 1, "nl2br" => 1, "explode" => 1, "implode" => 1
); );
/** /**
@ -216,17 +218,24 @@ class Aspect {
); );
/** /**
* Factory * Just factory
* @param string $template_dir path to templates *
* @param string|Aspect\ProviderInterface $source path to templates or custom provider
* @param string $compile_dir path to compiled files * @param string $compile_dir path to compiled files
* @param int $options * @param int $options
* @param \Aspect\Provider $provider * @throws InvalidArgumentException
* @return Aspect * @return Aspect
*/ */
public static function factory($template_dir, $compile_dir, $options = 0, Aspect\Provider $provider = null) { public static function factory($source, $compile_dir = '/tmp', $options = 0) {
if(is_string($source)) {
$provider = new \Aspect\Provider\FS($source);
} elseif($source instanceof Aspect\ProviderInterface) {
$provider = $source;
} else {
throw new InvalidArgumentException("Source must be a valid path or provider object");
}
$aspect = new static($provider); $aspect = new static($provider);
$aspect->setCompileDir($compile_dir); $aspect->setCompileDir($compile_dir);
$aspect->setTemplateDirs($template_dir);
if($options) { if($options) {
$aspect->setOptions($options); $aspect->setOptions($options);
} }
@ -234,10 +243,10 @@ class Aspect {
} }
/** /**
* @param Aspect\Provider $provider * @param Aspect\ProviderInterface $provider
*/ */
public function __construct(Aspect\Provider $provider = null) { public function __construct(Aspect\ProviderInterface $provider) {
$this->_provider = $provider ?: new Aspect\Provider(); $this->_provider = $provider;
} }
/** /**
@ -271,16 +280,6 @@ class Aspect {
return $this; return $this;
} }
/**
* Set template directory
* @param string|array $dirs directory(s) of template sources
* @return Aspect
*/
public function setTemplateDirs($dirs) {
$this->_provider->setTemplateDirs($dirs);
return $this;
}
/** /**
* *
* @param callable $cb * @param callable $cb
@ -446,19 +445,8 @@ class Aspect {
return $tags; return $tags;
} }
/**
* Add template directory
* @static
* @param string $dir
* @return \Aspect
* @throws \InvalidArgumentException
*/
public function addTemplateDir($dir) {
$this->_provider->addTemplateDir($dir);
return $this;
}
public function addProvider($scm, \Aspect\Provider $provider) { public function addProvider($scm, \Aspect\ProviderInterface $provider) {
$this->_providers[$scm] = $provider; $this->_providers[$scm] = $provider;
} }
@ -489,7 +477,7 @@ class Aspect {
/** /**
* @param bool|string $scm * @param bool|string $scm
* @return Aspect\Provider * @return Aspect\ProviderInterface
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
public function getProvider($scm = false) { public function getProvider($scm = false) {
@ -504,6 +492,10 @@ class Aspect {
} }
} }
public function getRawTemplate() {
return new \Aspect\Template($this);
}
/** /**
* Execute template and write result into stdout * Execute template and write result into stdout
* *
@ -556,7 +548,6 @@ class Aspect {
*/ */
public function addTemplate(Aspect\Render $template) { public function addTemplate(Aspect\Render $template) {
$this->_storage[ $template->getName() ] = $template; $this->_storage[ $template->getName() ] = $template;
$template->setStorage($this);
} }
/** /**
@ -572,9 +563,7 @@ class Aspect {
return $this->compile($tpl); return $this->compile($tpl);
} else { } else {
/** @var Aspect\Render $tpl */ /** @var Aspect\Render $tpl */
$tpl = include($this->_compile_dir."/".$file_name); return include($this->_compile_dir."/".$file_name);
$tpl->setStorage($this);
return $tpl;
} }
} }
@ -593,24 +582,23 @@ class Aspect {
* Compile and save template * Compile and save template
* *
* @param string $tpl * @param string $tpl
* @param bool $store * @param bool $store store template on disk
* @throws RuntimeException * @throws RuntimeException
* @return \Aspect\Template * @return \Aspect\Template
*/ */
public function compile($tpl, $store = true) { public function compile($tpl, $store = true) {
$provider = $this->getProvider(strstr($tpl, ":", true)); $template = Template::factory($this)->load($tpl);
$template = new Template($this, $provider->loadCode($tpl), $tpl);
if($store) { if($store) {
$tpl_tmp = tempnam($this->_compile_dir, basename($tpl)); $tpl_tmp = tempnam($this->_compile_dir, basename($tpl));
$tpl_fp = fopen($tpl_tmp, "w"); $tpl_fp = fopen($tpl_tmp, "w");
if(!$tpl_fp) { if(!$tpl_fp) {
throw new \RuntimeException("Can not open temporary file $tpl_tmp. Directory ".$this->_compile_dir." is writable?"); throw new \RuntimeException("Can't to open temporary file $tpl_tmp. Directory ".$this->_compile_dir." is writable?");
} }
fwrite($tpl_fp, $template->getTemplateCode()); fwrite($tpl_fp, $template->getTemplateCode());
fclose($tpl_fp); fclose($tpl_fp);
$file_name = $this->_compile_dir."/".$this->_getHash($tpl); $file_name = $this->_compile_dir."/".$this->_getHash($tpl);
if(!rename($tpl_tmp, $file_name)) { if(!rename($tpl_tmp, $file_name)) {
throw new \RuntimeException("Can not to move $tpl_tmp to $tpl"); throw new \RuntimeException("Can't to move $tpl_tmp to $tpl");
} }
} }
return $template; return $template;
@ -654,7 +642,7 @@ class Aspect {
* @return Aspect\Template * @return Aspect\Template
*/ */
public function compileCode($code, $name = 'Runtime compile') { public function compileCode($code, $name = 'Runtime compile') {
return new Template($this, $code, $name); return Template::factory($this)->source($name, $code);
} }
} }

View File

@ -357,16 +357,6 @@ class Compiler {
} }
} }
/**
* check if value is scalar, like "string", 2, 2.2, true, false, null
* @param string $value
* @return bool
* @todo add 'string' support
*/
public static function isScalar($value) {
return json_decode($value);
}
/** /**
* Dispatch {extends} tag * Dispatch {extends} tag
* @param Tokenizer $tokens * @param Tokenizer $tokens
@ -378,18 +368,11 @@ class Compiler {
if(!empty($tpl->_extends)) { if(!empty($tpl->_extends)) {
throw new ImproperUseException("Only one {extends} allowed"); throw new ImproperUseException("Only one {extends} allowed");
} }
$p = $tpl->parseParams($tokens); $tpl_name = $tpl->parseFirstArg($tokens, $name);
if(isset($p[0])) {
$tpl_name = $p[0];
} elseif (isset($p["file"])) {
$tpl_name = $p["file"];
} else {
throw new ImproperUseException("{extends} require 'file' parameter");
}
$tpl->addPostCompile(__CLASS__."::extendBody"); $tpl->addPostCompile(__CLASS__."::extendBody");
if($name = self::isScalar($tpl_name)) { // static extends if($name) { // static extends
$tpl->_extends = $tpl->getStorage()->compile($name, false); $tpl->_extends = $tpl->getStorage()->getRawTemplate()->load($name, false);
$tpl->addDepend($tpl->getStorage()->getTemplate($name)); // for valid compile-time need take template from storage $tpl->addDepend($tpl->_extends); // for valid compile-time need take template from storage
return "/* Static extends */"; return "/* Static extends */";
} else { // dynamic extends } else { // dynamic extends
$tpl->_extends = $tpl_name; $tpl->_extends = $tpl_name;
@ -443,9 +426,7 @@ class Compiler {
*/ */
public static function tagBlockOpen(Tokenizer $tokens, Scope $scope) { public static function tagBlockOpen(Tokenizer $tokens, Scope $scope) {
$p = $scope->tpl->parseParams($tokens); $p = $scope->tpl->parseParams($tokens);
if(isset($p["name"])) { if (isset($p[0])) {
$scope["name"] = $p["name"];
} elseif (isset($p[0])) {
$scope["name"] = $p[0]; $scope["name"] = $p[0];
} else { } else {
throw new ImproperUseException("{block} must be named"); throw new ImproperUseException("{block} must be named");
@ -476,7 +457,7 @@ class Compiler {
* @return string * @return string
*/ */
public static function tagBlockClose($tokens, Scope $scope) { public static function tagBlockClose($tokens, Scope $scope) {
$scope->tpl->_blocks[ self::isScalar($scope["name"]) ] = substr($scope->tpl->getBody(), $scope["offset"]); $scope->tpl->_blocks[ $scope["name"] ] = substr($scope->tpl->getBody(), $scope["offset"]);
if(isset($scope->tpl->_extends)) { // is child if(isset($scope->tpl->_extends)) { // is child
if(is_object($scope->tpl->_extends)) { // static extends if(is_object($scope->tpl->_extends)) { // static extends
return ""; return "";

View File

@ -6,6 +6,13 @@ use Aspect;
* Primitive template * Primitive template
*/ */
class Render extends \ArrayObject { class Render extends \ArrayObject {
private static $_props = array(
"name" => "runtime",
"base_name" => "",
"scm" => false,
"time" => 0,
"depends" => array()
);
/** /**
* @var \Closure * @var \Closure
*/ */
@ -14,7 +21,9 @@ class Render extends \ArrayObject {
* Template name * Template name
* @var string * @var string
*/ */
protected $_name = 'runtime template'; protected $_name = 'runtime';
protected $_scm = false;
protected $_base_name = 'runtime';
/** /**
* @var Aspect * @var Aspect
*/ */
@ -28,23 +37,25 @@ class Render extends \ArrayObject {
protected $_depends = array(); protected $_depends = array();
/** /**
* @param string $name template name * Template provider
* @param callable $code template body * @var ProviderInterface
* @param mixed $props signature
*/ */
public function __construct($name, \Closure $code, $props = array()) { protected $_provider;
$this->_name = $name;
$this->_code = $code;
$this->_time = isset($props["time"]) ? $props["time"] : microtime(true);
$this->_depends = isset($props["depends"]) ? $props["depends"] : array();
}
/** /**
* Set template storage
* @param Aspect $aspect * @param Aspect $aspect
* @param callable $code template body
* @param array $props
*/ */
public function setStorage(Aspect $aspect) { public function __construct(Aspect $aspect, \Closure $code, $props = array()) {
$this->_aspect = $aspect; $this->_aspect = $aspect;
$props += self::$_props;
$this->_name = $props["name"];
$this->_provider = $this->_aspect->getProvider($props["scm"]);
$this->_scm = $props["scm"];
$this->_time = $props["time"];
$this->_depends = $props["depends"];
$this->_code = $code;
} }
/** /**
@ -55,11 +66,23 @@ class Render extends \ArrayObject {
return $this->_aspect; return $this->_aspect;
} }
public function getScm() {
return $this->_scm;
}
public function getProvider() {
return $this->_provider;
}
public function getBaseName() {
return $this->_base_name;
}
/** /**
* @return string * @return string
*/ */
public function __toString() { public function __toString() {
return "Template({$this->_name})"; return $this->_name;
} }
/** /**

View File

@ -53,27 +53,65 @@ class Template extends Render {
*/ */
public static $sysvar = array('$aspect' => 1, '$smarty' => 1); public static $sysvar = array('$aspect' => 1, '$smarty' => 1);
/** public static function factory(Aspect $aspect) {
* @param Aspect $aspect Template storage return new static($aspect);
* @param string $code template source
* @param string $name template name
* @param bool $auto_compile
*/
public function __construct(Aspect $aspect, $code, $name = "runtime template", $auto_compile = true) {
$this->_src = $code;
$this->_name = $name;
$this->_aspect = $aspect;
$this->_options = $aspect->getOptions();
if($auto_compile) {
$this->compile();
}
} }
/**
* @param Aspect $aspect Template storage
*/
public function __construct(Aspect $aspect) {
$this->_aspect = $aspect;
$this->_options = $this->_aspect->getOptions();
}
/**
* Load source from provider
* @param string $name
* @param bool $compile
* @return \Aspect\Template
*/
public function load($name, $compile = true) {
$this->_name = $name;
if($provider = strstr($name, ":", true)) {
$this->_scm = $provider;
$this->_base_name = substr($name, strlen($provider));
} else {
$this->_base_name = $name;
}
$this->_provider = $this->_aspect->getProvider($provider);
$this->_src = $this->_provider->getSource($name, $this->_time);
if($compile) {
$this->compile();
}
return $this;
}
/**
* Load custom source
* @param string $name template name
* @param string $src template source
* @param bool $compile
* @return \Aspect\Template
*/
public function source($name, $src, $compile = true) {
$this->_name = $name;
$this->_src = $src;
if($compile) {
$this->compile();
}
return $this;
}
/**
* Convert template to PHP code
*
* @throws CompileException
*/
public function compile() { public function compile() {
if(!isset($this->_src)) { if(!isset($this->_src)) {
return; return;
} }
$this->_time = microtime(true);
$pos = 0; $pos = 0;
while(($start = strpos($this->_src, '{', $pos)) !== false) { // search open-char of tags while(($start = strpos($this->_src, '{', $pos)) !== false) { // search open-char of tags
switch($this->_src[$start + 1]) { // check next char switch($this->_src[$start + 1]) { // check next char
@ -95,19 +133,20 @@ class Template extends Render {
$tag = substr($this->_src, $start, $end - $start + 1); // variable $tag contains aspect tag '{...}' $tag = substr($this->_src, $start, $end - $start + 1); // variable $tag contains aspect tag '{...}'
$this->_line += substr_count($this->_src, "\n", $this->_pos, $end - $start + 1); // count lines in $frag and $tag (using original text $code) $this->_line += substr_count($this->_src, "\n", $this->_pos, $end - $start + 1); // count lines in $frag and $tag (using original text $code)
$pos = $this->_pos = $end + 1; // move search-pointer to end of the tag $pos = $this->_pos = $end + 1; // move search-pointer to end of the tag
if($this->_trim) { // if previous tag has trim flag //if($this->_trim) { // if previous tag has trim flag
$frag = ltrim($frag); // $frag = ltrim($frag);
} //}
$this->_body .= str_replace("<?", '<?php echo "<?" ?>', $frag);
$tag = $this->_tag($tag, $this->_trim); // dispatching tags $tag = $this->_tag($tag, $this->_trim); // dispatching tags
if($this->_trim) { // if current tag has trim flag //if($this->_trim) { // if current tag has trim flag
$frag = rtrim($frag); // $frag = rtrim($frag);
//}
$this->_body .= $tag;
} }
$this->_body .= str_replace("<?", '<?php echo "<?" ?>', $frag).$tag; $this->_body .= str_replace("<?", '<?php echo "<?" ?>', substr($this->_src, $this->_pos));
}
$this->_body .= substr($this->_src, $this->_pos);
if($this->_stack) { if($this->_stack) {
$_names = array(); $_names = array();
$_line = 0; $_line = 0;
@ -146,9 +185,11 @@ class Template extends Render {
public function getTemplateCode() { public function getTemplateCode() {
return "<?php \n". return "<?php \n".
"/** Aspect template '".$this->_name."' compiled at ".date('Y-m-d H:i:s')." */\n". "/** Aspect template '".$this->_name."' compiled at ".date('Y-m-d H:i:s')." */\n".
"return new Aspect\\Render('{$this->_name}', ".$this->_getClosureCode().", ".var_export(array( "return new Aspect\\Render(\$this, ".$this->_getClosureSource().", ".var_export(array(
"options" => $this->_options, //"options" => $this->_options,
//"provider" => "provider" => $this->_scm,
"name" => $this->_name,
"base_name" => $this->_base_name,
"time" => $this->_time, "time" => $this->_time,
"depends" => $this->_depends "depends" => $this->_depends
), true).");\n"; ), true).");\n";
@ -158,7 +199,7 @@ class Template extends Render {
* Return closure code * Return closure code
* @return string * @return string
*/ */
private function _getClosureCode() { private function _getClosureSource() {
return "function (\$tpl) {\n?>{$this->_body}<?php\n}"; return "function (\$tpl) {\n?>{$this->_body}<?php\n}";
} }
@ -172,7 +213,7 @@ class Template extends Render {
public function display(array $values) { public function display(array $values) {
if(!$this->_code) { if(!$this->_code) {
// evaluate template's code // evaluate template's code
eval("\$this->_code = ".$this->_getClosureCode().";"); eval("\$this->_code = ".$this->_getClosureSource().";");
if(!$this->_code) { if(!$this->_code) {
throw new CompileException("Fatal error while creating the template"); throw new CompileException("Fatal error while creating the template");
} }
@ -186,6 +227,7 @@ class Template extends Render {
* @param Render $tpl * @param Render $tpl
*/ */
public function addDepend(Render $tpl) { public function addDepend(Render $tpl) {
$this->_depends[$tpl->getName()] = $tpl->getCompileTime(); $this->_depends[$tpl->getName()] = $tpl->getCompileTime();
} }
@ -197,7 +239,7 @@ class Template extends Render {
*/ */
public function fetch(array $values) { public function fetch(array $values) {
if(!$this->_code) { if(!$this->_code) {
eval("\$this->_code = ".$this->_getClosureCode().";"); eval("\$this->_code = ".$this->_getClosureSource().";");
if(!$this->_code) { if(!$this->_code) {
throw new CompileException("Fatal error while creating the template"); throw new CompileException("Fatal error while creating the template");
} }
@ -245,9 +287,6 @@ class Template extends Render {
break; break;
default: default:
$code = $this->_parseAct($tokens); $code = $this->_parseAct($tokens);
if($code === null) {
}
break; break;
} }
@ -823,6 +862,18 @@ class Template extends Render {
throw new TokenizeException("Unexpected token '".$tokens->current()."' in argument list"); throw new TokenizeException("Unexpected token '".$tokens->current()."' in argument list");
} }
public function parseFirstArg(Tokenizer $tokens, &$static) {
if($tokens->is(T_CONSTANT_ENCAPSED_STRING)) {
$str = $tokens->getAndNext();
$static = stripslashes(substr($str, 1, -1));
return $str;
} elseif($tokens->is(Tokenizer::MACRO_STRING)) {
return $static = $tokens->getAndNext();
} else {
return $this->parseExp($tokens, true);
}
}
/** /**
* Parse parameters as $key=$value * Parse parameters as $key=$value
* param1=$var param2=3 ... * param1=$var param2=3 ...

View File

@ -11,15 +11,19 @@ class RenderTest extends \PHPUnit_Framework_TestCase {
public static $render; public static $render;
public static function setUpBeforeClass() { public static function setUpBeforeClass() {
self::$render = new Render("render.tpl", function ($tpl) { self::$render = new Render(Aspect::factory("."), function ($tpl) {
echo "It is render function ".$tpl["render"]; echo "It is render's function ".$tpl["render"];
}, array()); }, array(
"name" => "render.tpl"
));
} }
public function testCreate() { public function testCreate() {
$r = new Render("test.render.tpl", function () { $r = new Render(Aspect::factory("."), function () {
echo "Test render"; echo "Test render";
}, array()); }, array(
"name" => "test.render.tpl"
));
$this->assertSame("Test render", $r->fetch(array())); $this->assertSame("Test render", $r->fetch(array()));
} }
@ -27,22 +31,24 @@ class RenderTest extends \PHPUnit_Framework_TestCase {
ob_start(); ob_start();
self::$render->display(array("render" => "display")); self::$render->display(array("render" => "display"));
$out = ob_get_clean(); $out = ob_get_clean();
$this->assertSame("It is render function display", $out); $this->assertSame("It is render's function display", $out);
} }
public function testFetch() { public function testFetch() {
$this->assertSame("It is render function fetch", self::$render->fetch(array("render" => "fetch"))); $this->assertSame("It is render's function fetch", self::$render->fetch(array("render" => "fetch")));
} }
/** /**
* @expectedException RuntimeException * @expectedException \RuntimeException
* @expectedExceptionMessage template error * @expectedExceptionMessage template error
*/ */
public function testFetchException() { public function testFetchException() {
$render = new Render("render.tpl", function ($tpl) { $render = new Render(Aspect::factory("."), function () {
echo "error"; echo "error";
throw new \RuntimeException("template error"); throw new \RuntimeException("template error");
}); }, array(
"name" => "render.tpl"
));
$render->fetch(array()); $render->fetch(array());
} }

View File

@ -0,0 +1,72 @@
<?php
namespace Aspect\Template;
use Aspect, Aspect\Modifier;
class ExtendsTest extends \PHPUnit_Framework_TestCase {
/**
* @var Aspect
*/
public static $aspect;
public function setUp() {
if(!file_exists(ASPECT_RESOURCES.'/compile')) {
mkdir(ASPECT_RESOURCES.'/compile', 0777, true);
} else {
exec("rm -f ".ASPECT_RESOURCES.'/compile/*');
}
self::$aspect = Aspect::factory(ASPECT_RESOURCES.'/template', ASPECT_RESOURCES.'/compile');
}
public static function providerExtends() {
return array(
array('{extends "parent.tpl"}{block "bk1"} block1 {/block}', "Template extended by block1"),
array('{extends "parent.tpl"}{block "bk1"} block1 {/block}{block "bk2"} block2 {/block} garbage', "Template extended by block1"),
array('{extends "parent.tpl"}{block "bk1"} block1 {/block}{block "bk2"} block2 {/block} {block "bk3"} block3 {/block} garbage', "Template multi-extended by block1"),
array('{extends "parent.tpl"}{var $bk = "bk3"}{block "bk1"} block1 {/block}{block "bk2"} block2 {/block} {block "$bk"} block3 {/block} garbage', "Template multi-extended by block1"),
);
}
public function exec($code, $vars, $result, $dump = false) {
$tpl = self::$aspect->compileCode($code, "inline.tpl");
if($dump) {
echo "\n===========================\n".$code.": ".$tpl->getBody();
}
$this->assertSame(Modifier::strip($result), Modifier::strip($tpl->fetch($vars), true), "Test $code");
}
public function execError($code, $exception, $message, $options) {
self::$aspect->setOptions($options);
try {
self::$aspect->compileCode($code, "inline.tpl");
} catch(\Exception $e) {
$this->assertSame($exception, get_class($e), "Exception $code");
$this->assertStringStartsWith($message, $e->getMessage());
self::$aspect->setOptions(0);
return;
}
self::$aspect->setOptions(0);
$this->fail("Code $code must be invalid");
}
/**
* @group extends
*/
public function testParent() {
//echo(self::$aspect->getTemplate("parent.tpl")->getBody()); exit;
}
/**
* @group extends
*/
public function ___testChildLevel1() {
echo(self::$aspect->getTemplate("child1.tpl")->getBody()); exit;
}
/**
* @group extends
*/
public function __testExtends() {
echo(self::$aspect->fetch("child1.tpl", array("a" => "value", "z" => ""))."\n"); exit;
}
}

View File

@ -17,9 +17,11 @@ class TemplateTest extends \PHPUnit_Framework_TestCase {
exec("rm -f ".ASPECT_RESOURCES.'/compile/*'); exec("rm -f ".ASPECT_RESOURCES.'/compile/*');
} }
self::$aspect = Aspect::factory(ASPECT_RESOURCES.'/template', ASPECT_RESOURCES.'/compile'); self::$aspect = Aspect::factory(ASPECT_RESOURCES.'/template', ASPECT_RESOURCES.'/compile');
self::$aspect->addTemplate(new Render("welcome.tpl", function ($tpl) { self::$aspect->addTemplate(new Render(self::$aspect, function ($tpl) {
echo "<b>Welcome, ".$tpl["username"]." (".$tpl["email"].")</b>"; echo "<b>Welcome, ".$tpl["username"]." (".$tpl["email"].")</b>";
}, array())); }, array(
"name" => "welcome.tpl"
)));
} }

View File

@ -21,7 +21,6 @@ class AspectTest extends \PHPUnit_Framework_TestCase {
self::tearDownAfterClass(); self::tearDownAfterClass();
$this->aspect = $aspect = Aspect::factory(ASPECT_RESOURCES.'/template', ASPECT_RESOURCES.'/compile'); $this->aspect = $aspect = Aspect::factory(ASPECT_RESOURCES.'/template', ASPECT_RESOURCES.'/compile');
$aspect->setCompileDir(ASPECT_RESOURCES.'/compile'); $aspect->setCompileDir(ASPECT_RESOURCES.'/compile');
$aspect->addTemplateDir(ASPECT_RESOURCES.'/template');
$aspect->setForceCompile(false); $aspect->setForceCompile(false);
$aspect->setCompileCheck(false); $aspect->setCompileCheck(false);
} }
@ -36,11 +35,13 @@ class AspectTest extends \PHPUnit_Framework_TestCase {
public function testAddRender() { public function testAddRender() {
$test = $this; $test = $this;
$this->aspect->addTemplate(new Render('render.tpl', function($tpl) use ($test) { $this->aspect->addTemplate(new Render($this->aspect, function($tpl) use ($test) {
/** @var \PHPUnit_Framework_TestCase $test */ /** @var \PHPUnit_Framework_TestCase $test */
$test->assertInstanceOf('Aspect\Render', $tpl); $test->assertInstanceOf('Aspect\Render', $tpl);
echo "Inline render"; echo "Inline render";
}, array())); }, array(
"name" => 'render.tpl'
)));
$this->assertSame("Inline render", $this->aspect->fetch('render.tpl', array())); $this->assertSame("Inline render", $this->aspect->fetch('render.tpl', array()));
} }