mirror of
				https://github.com/Mibew/handlebars.php.git
				synced 2025-10-31 18:31:04 +03:00 
			
		
		
		
	Some test improvement and add an ArrayLoader
This commit is contained in:
		
							parent
							
								
									3514a2b151
								
							
						
					
					
						commit
						939c58bbee
					
				
							
								
								
									
										76
									
								
								src/Handlebars/Loader/ArrayLoader.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								src/Handlebars/Loader/ArrayLoader.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,76 @@ | ||||
| <?php | ||||
| /** | ||||
|  * This file is part of Handlebars-php | ||||
|  * Base on mustache-php https://github.com/bobthecow/mustache.php | ||||
|  * | ||||
|  * PHP version 5.3 | ||||
|  * | ||||
|  * @category  Xamin | ||||
|  * @package   Handlebars | ||||
|  * @author    fzerorubigd <fzerorubigd@gmail.com> | ||||
|  * @copyright 2014 (c) f0ruD | ||||
|  * @license   MIT <http://opensource.org/licenses/MIT> | ||||
|  * @version   GIT: $Id$ | ||||
|  * @link      http://xamin.ir | ||||
|  */ | ||||
| 
 | ||||
| namespace Handlebars\Loader; | ||||
| 
 | ||||
| use Handlebars\Loader; | ||||
| 
 | ||||
| /** | ||||
|  * Handlebars Template array Loader implementation. | ||||
|  * | ||||
|  * @category  Xamin | ||||
|  * @package   Handlebars | ||||
|  * @author    fzerorubigd <fzerorubigd@gmail.com> | ||||
|  * @copyright 2014 (c) f0ruD | ||||
|  * @license   MIT <http://opensource.org/licenses/MIT> | ||||
|  * @version   Release: @package_version@ | ||||
|  * @link      http://xamin.ir * | ||||
|  */ | ||||
| class ArrayLoader implements Loader | ||||
| { | ||||
|     private $_templates; | ||||
| 
 | ||||
|     /** | ||||
|      * Create a new loader with associative array style | ||||
|      * | ||||
|      * @param array $templates the templates to load | ||||
|      */ | ||||
|     public function __construct(array $templates = array()) | ||||
|     { | ||||
|         $this->_templates = $templates; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Add a template to list | ||||
|      * | ||||
|      * @param string $name     template name | ||||
|      * @param string $template the template | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function addTemplate($name, $template) | ||||
|     { | ||||
|         $this->_templates[$name] = $template; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Load a Template by name. | ||||
|      * | ||||
|      * @param string $name template name to load | ||||
|      * | ||||
|      * @throws \RuntimeException | ||||
|      * @return String | ||||
|      */ | ||||
|     public function load($name) | ||||
|     { | ||||
|         if (isset($this->_templates[$name])) { | ||||
|             return $this->_templates[$name]; | ||||
|         } | ||||
|         throw new \RuntimeException( | ||||
|             "Can not find the $name template" | ||||
|         ); | ||||
|     } | ||||
| } | ||||
| @ -243,6 +243,100 @@ class Template | ||||
|         array_push($this->_stack, $topStack); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Process handlebars section style | ||||
|      * | ||||
|      * @param Context $context current context | ||||
|      * @param array   $current section node data | ||||
|      * | ||||
|      * @return mixed|string | ||||
|      */ | ||||
|     private function _handlebarsStyleSection(Context $context, $current) | ||||
|     { | ||||
|         $helpers = $this->handlebars->getHelpers(); | ||||
|         $sectionName = $current[Tokenizer::NAME]; | ||||
| 
 | ||||
|         if (isset($current[Tokenizer::END])) { | ||||
|             $source = substr( | ||||
|                 $this->getSource(), | ||||
|                 $current[Tokenizer::INDEX], | ||||
|                 $current[Tokenizer::END] - $current[Tokenizer::INDEX] | ||||
|             ); | ||||
|         } else { | ||||
|             $source = ''; | ||||
|         } | ||||
|         $params = array( | ||||
|             $this, //First argument is this template
 | ||||
|             $context, //Second is current context
 | ||||
|             $current[Tokenizer::ARGS], //Arguments
 | ||||
|             $source | ||||
|         ); | ||||
| 
 | ||||
|         $return = call_user_func_array($helpers->$sectionName, $params); | ||||
|         if ($return instanceof String) { | ||||
|             return $this->handlebars->loadString($return)->render($context); | ||||
|         } else { | ||||
|             return $return; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Process Mustache section style | ||||
|      * | ||||
|      * @param Context $context current context | ||||
|      * @param array   $current section node data | ||||
|      * | ||||
|      * @throws \RuntimeException | ||||
|      * @return mixed|string | ||||
|      */ | ||||
|     private function _mustacheStyleSection(Context $context, $current) | ||||
|     { | ||||
|         $sectionName = $current[Tokenizer::NAME]; | ||||
| 
 | ||||
|         // fallback to mustache style each/with/for just if there is
 | ||||
|         // no argument at all.
 | ||||
|         try { | ||||
|             $sectionVar = $context->get($sectionName, true); | ||||
|         } catch (\InvalidArgumentException $e) { | ||||
|             throw new \RuntimeException( | ||||
|                 $sectionName . ' is not registered as a helper' | ||||
|             ); | ||||
|         } | ||||
|         $buffer = ''; | ||||
|         if (is_array($sectionVar) || $sectionVar instanceof \Traversable) { | ||||
|             $isList = is_array($sectionVar) && | ||||
|                 (array_keys($sectionVar) == range(0, count($sectionVar) - 1)); | ||||
|             $index = 0; | ||||
|             $lastIndex = $isList ? (count($sectionVar) - 1) : false; | ||||
| 
 | ||||
|             foreach ($sectionVar as $key => $d) { | ||||
|                 $specialVariables = array( | ||||
|                     '@index' => $index, | ||||
|                     '@first' => ($index === 0), | ||||
|                     '@last' => ($index === $lastIndex), | ||||
|                 ); | ||||
|                 if (!$isList) { | ||||
|                     $specialVariables['@key'] = $key; | ||||
|                 } | ||||
|                 $context->pushSpecialVariables($specialVariables); | ||||
|                 $context->push($d); | ||||
|                 $buffer .= $this->render($context); | ||||
|                 $context->pop(); | ||||
|                 $context->popSpecialVariables(); | ||||
|                 $index++; | ||||
|             } | ||||
|         } elseif (is_object($sectionVar)) { | ||||
|             //Act like with
 | ||||
|             $context->push($sectionVar); | ||||
|             $buffer = $this->render($context); | ||||
|             $context->pop(); | ||||
|         } elseif ($sectionVar) { | ||||
|             $buffer = $this->render($context); | ||||
|         } | ||||
| 
 | ||||
|         return $buffer; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Process section nodes | ||||
|      * | ||||
| @ -257,70 +351,9 @@ class Template | ||||
|         $helpers = $this->handlebars->getHelpers(); | ||||
|         $sectionName = $current[Tokenizer::NAME]; | ||||
|         if ($helpers->has($sectionName)) { | ||||
|             if (isset($current[Tokenizer::END])) { | ||||
|                 $source = substr( | ||||
|                     $this->getSource(), | ||||
|                     $current[Tokenizer::INDEX], | ||||
|                     $current[Tokenizer::END] - $current[Tokenizer::INDEX] | ||||
|                 ); | ||||
|             } else { | ||||
|                 $source = ''; | ||||
|             } | ||||
|             $params = array( | ||||
|                 $this, //First argument is this template
 | ||||
|                 $context, //Second is current context
 | ||||
|                 $current[Tokenizer::ARGS], //Arguments
 | ||||
|                 $source | ||||
|             ); | ||||
| 
 | ||||
|             $return = call_user_func_array($helpers->$sectionName, $params); | ||||
|             if ($return instanceof String) { | ||||
|                 return $this->handlebars->loadString($return)->render($context); | ||||
|             } else { | ||||
|                 return $return; | ||||
|             } | ||||
|             return $this->_handlebarsStyleSection($context, $current); | ||||
|         } elseif (trim($current[Tokenizer::ARGS]) == '') { | ||||
|             // fallback to mustache style each/with/for just if there is
 | ||||
|             // no argument at all.
 | ||||
|             try { | ||||
|                 $sectionVar = $context->get($sectionName, true); | ||||
|             } catch (\InvalidArgumentException $e) { | ||||
|                 throw new \RuntimeException( | ||||
|                     $sectionName . ' is not registered as a helper' | ||||
|                 ); | ||||
|             } | ||||
|             $buffer = ''; | ||||
|             if (is_array($sectionVar) || $sectionVar instanceof \Traversable) { | ||||
|                 $isList = is_array($sectionVar) && (array_keys($sectionVar) == range(0, count($sectionVar) - 1)); | ||||
|                 $index = 0; | ||||
|                 $lastIndex = $isList ? (count($sectionVar) - 1) : false; | ||||
| 
 | ||||
|                 foreach ($sectionVar as $key => $d) { | ||||
|                     $specialVariables = array( | ||||
|                         '@index' => $index, | ||||
|                         '@first' => ($index === 0), | ||||
|                         '@last' => ($index === $lastIndex), | ||||
|                     ); | ||||
|                     if (!$isList) { | ||||
|                         $specialVariables['@key'] = $key; | ||||
|                     } | ||||
|                     $context->pushSpecialVariables($specialVariables); | ||||
|                     $context->push($d); | ||||
|                     $buffer .= $this->render($context); | ||||
|                     $context->pop(); | ||||
|                     $context->popSpecialVariables(); | ||||
|                     $index++; | ||||
|                 } | ||||
|             } elseif (is_object($sectionVar)) { | ||||
|                 //Act like with
 | ||||
|                 $context->push($sectionVar); | ||||
|                 $buffer = $this->render($context); | ||||
|                 $context->pop(); | ||||
|             } elseif ($sectionVar) { | ||||
|                 $buffer = $this->render($context); | ||||
|             } | ||||
| 
 | ||||
|             return $buffer; | ||||
|             return $this->_mustacheStyleSection($context, $current); | ||||
|         } else { | ||||
|             throw new \RuntimeException( | ||||
|                 $sectionName . ' is not registered as a helper' | ||||
| @ -380,6 +413,7 @@ class Template | ||||
|         $helpers = $this->getEngine()->getHelpers(); | ||||
|         // Tokenizer doesn't process the args -if any- so be aware of that
 | ||||
|         $name = explode(' ', $current[Tokenizer::NAME], 2); | ||||
| 
 | ||||
|         return $helpers->has(reset($name)); | ||||
|     } | ||||
| 
 | ||||
| @ -457,32 +491,34 @@ class Template | ||||
| 
 | ||||
|         return $value; | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     /** | ||||
|      * Break an argument string into an array of strings | ||||
|      * | ||||
|      * @param string $string Argument String as passed to a helper | ||||
|      * | ||||
|      * @throws \RuntimeException | ||||
|      * @return array the argument list as an array | ||||
|      */ | ||||
|     public function parseArguments($string) | ||||
|     { | ||||
|         $args = array(); | ||||
|         preg_match_all('#(?:[^\'"\[\]\s]|\[.+?\])+|(?<!\\\\)("|\')(?:[^\\\\]|\\\\.)*?\1|\S+#s', $string, $args); | ||||
|         $args =  isset($args[0])?$args[0]:array(); | ||||
|          | ||||
|         for ($x=0, $argc = count($args); $x<$argc;$x++) { | ||||
|         $args = isset($args[0]) ? $args[0] : array(); | ||||
| 
 | ||||
|         for ($x = 0, $argc = count($args); $x < $argc; $x++) { | ||||
|             // check to see if argument is a quoted string literal
 | ||||
|             if ($args[$x][0] == "'" || $args[$x][0] == '"') { | ||||
|                 if ($args[$x][0] === substr($args[$x], -1)) { | ||||
|                     // remove enclosing quotes and unescape
 | ||||
|                     $args[$x] = new \Handlebars\String(stripcslashes(substr($args[$x], 1, strlen($args[$x]) -2))); | ||||
|                     $args[$x] = new \Handlebars\String(stripcslashes(substr($args[$x], 1, strlen($args[$x]) - 2))); | ||||
|                 } else { | ||||
|                     throw new \RuntimeException("Malformed string: ".$args); | ||||
|                     throw new \RuntimeException("Malformed string: " . $args); | ||||
|                 } | ||||
|             } | ||||
|              | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         return $args; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -283,6 +283,22 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase | ||||
|         $this->assertEquals('<strong>Test</strong>', $engine->render('{{safeStringTest}}', array())); | ||||
|     } | ||||
| 
 | ||||
|     public function testInvalidHelperMustacheStyle() | ||||
|     { | ||||
|         $this->setExpectedException('RuntimeException'); | ||||
|         $loader = new \Handlebars\Loader\StringLoader(); | ||||
|         $engine = new \Handlebars\Handlebars(array('loader' => $loader)); | ||||
|         $engine->render('{{#NOTVALID}}XXX{{/NOTVALID}}', array()); | ||||
|     } | ||||
| 
 | ||||
|     public function testInvalidHelper() | ||||
|     { | ||||
|         $this->setExpectedException('RuntimeException'); | ||||
|         $loader = new \Handlebars\Loader\StringLoader(); | ||||
|         $engine = new \Handlebars\Handlebars(array('loader' => $loader)); | ||||
|         $engine->render('{{#NOTVALID argument}}XXX{{/NOTVALID}}', array()); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Test mustache style loop and if | ||||
|      */ | ||||
| @ -412,6 +428,18 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase | ||||
|         $this->assertEquals(1, count(glob($path . '/*'))); | ||||
|     } | ||||
| 
 | ||||
|     public function testArrayLoader() | ||||
|     { | ||||
|         $loader = new \Handlebars\Loader\ArrayLoader(array('test' => 'HELLO')); | ||||
|         $loader->addTemplate('another', 'GOODBYE'); | ||||
|         $engine = new \Handlebars\Handlebars(array('loader' => $loader)); | ||||
|         $this->assertEquals($engine->render('test', array()), 'HELLO'); | ||||
|         $this->assertEquals($engine->render('another', array()), 'GOODBYE'); | ||||
| 
 | ||||
|         $this->setExpectedException('RuntimeException'); | ||||
|         $engine->render('invalid-template', array()); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Test file system loader | ||||
|      */ | ||||
| @ -477,6 +505,29 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase | ||||
|         $this->assertEquals('test', $engine->render('{{>loader}}', array())); | ||||
|     } | ||||
| 
 | ||||
|     public function testPartial() | ||||
|     { | ||||
|         $loader = new \Handlebars\Loader\StringLoader(); | ||||
|         $partialLoader = new \Handlebars\Loader\ArrayLoader(array('test' => '{{key}}', 'bar' => 'its foo')); | ||||
|         $partialAliasses = array('foo' => 'bar'); | ||||
|         $engine = new \Handlebars\Handlebars( | ||||
|             array( | ||||
|                 'loader' => $loader, | ||||
|                 'partials_loader' => $partialLoader, | ||||
|                 'partials_alias' => $partialAliasses | ||||
|             ) | ||||
|         ); | ||||
| 
 | ||||
|         $this->assertEquals('HELLO', $engine->render('{{>test parameter}}', array('parameter' => array('key' => 'HELLO')))); | ||||
|         $this->assertEquals('its foo', $engine->render('{{>foo}}', array())); | ||||
|         $engine->registerPartial('foo-again', 'bar'); | ||||
|         $this->assertEquals('its foo', $engine->render('{{>foo-again}}', array())); | ||||
|         $engine->unRegisterPartial('foo-again'); | ||||
| 
 | ||||
|         $this->setExpectedException('RuntimeException'); | ||||
|         $engine->render('{{>foo-again}}', array()); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * test variable access | ||||
|      */ | ||||
| @ -588,11 +639,12 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase | ||||
|                     array('"arg1.[value 1]" arg2', array("arg1.[value 1]", 'arg2')), | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Test Argument Parser | ||||
|      * | ||||
|      * @param string $arg_string argument text | ||||
|      * @param array  $arg_ array data | ||||
|      * @param        $expected_array | ||||
|      * | ||||
|      * @dataProvider argumentParserProvider | ||||
|      * | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user