Changed Internal representation of quoted string literals to be an instance of \Handlebars\String instead of strangely quoted string.

This commit is contained in:
Chris Gray 2014-01-20 09:04:31 -06:00
parent 054f2c75ee
commit 49dcbb2573
3 changed files with 76 additions and 11 deletions

View File

@ -225,12 +225,8 @@ class Context
$current = $this->lastIndex();
} elseif ($variableName == '@key') {
$current = $this->lastKey();
} elseif ($variableName[0] == "'" || $variableName[0] == '"') {
if ($variableName[0] == substr($variableName, -1) && strlen($variableName) > 2) {
$current = substr($variableName, 1, strlen($variableName) -2);
} else {
throw new \RuntimeException("Malformed string: ".$variableName);
}
} elseif ($variableName instanceof \Handlebars\String){
$current = (string)$variableName;
} else {
$chunks = explode('.', $variableName);
foreach ($chunks as $chunk) {

View File

@ -430,10 +430,23 @@ class Template
*/
public function parseArguments($string)
{
$parts = array();
preg_match_all('#(?<!\\\\)("|\')(?:[^\\\\]|\\\\.)*?\1|\S+#s', $string, $parts);
$parts = isset($parts[0])?$parts[0]:array();
$parts = array_map("stripcslashes", $parts);
return $parts;
$args = array();
preg_match_all('#(?<!\\\\)("|\')(?:[^\\\\]|\\\\.)*?\1|\S+#s', $string, $args);
$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)));
} else {
throw new \RuntimeException("Malformed string: ".$args);
}
}
}
return $args;
}
}

View File

@ -89,6 +89,11 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
'{{data.length}}',
array("data"=> (object)array(1,2,3,4)),
''
),
array(
'{{data.length}}',
array("data"=>array("length"=>"15 inches", "test","test","test")),
"15 inches"
)
);
}
@ -472,5 +477,56 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
array('data.key.key'),
);
}
/**
* Test for proper handling of the length property
**/
public function testArrayLengthEmulation(){
$data = array("numbers"=>array(1,2,3,4),
"object"=>(object)array("prop1"=>"val1", "prop2"=>"val2"),
"object_with_length_property"=>(object)array("length"=>"15cm")
);
$context = new \Handlebars\Context($data);
// make sure we are getting the array length when given an array
$this->assertEquals($context->get("numbers.length"), 4);
// make sure we are not getting a length when given an object
$this->assertEmpty($context->get("object.length"));
// make sure we can still get the length property when given an object
$this->assertEquals($context->get("object_with_length_property.length"), "15cm");
}
public function argumentParserProvider(){
return array(
array('arg1 arg2', array("arg1","arg2")),
array('"arg1 arg2"', array("arg1 arg2")),
array('arg1 arg2 "arg number 3"', array("arg1","arg2","arg number 3")),
array('arg1 "arg\"2" "\"arg3\""', array("arg1",'arg"2', '"arg3"')),
array("'arg1 arg2'", array("arg1 arg2")),
array("arg1 arg2 'arg number 3'", array("arg1","arg2","arg number 3")),
array('arg1 "arg\"2" "\\\'arg3\\\'"', array("arg1",'arg"2', "'arg3'"))
);
}
/**
* Test Argument Parser
*
* @param string $arg_string argument text
* @param array $arg_ array data
*
* @dataProvider argumentParserProvider
*
* @return void
*/
public function testArgumentParser($arg_string, $expected_array){
$engine = new \Handlebars\Handlebars();
$template = new \Handlebars\Template($engine, null, null);
// get the string version of the arguments array
$args = $template->parseArguments($arg_string);
$args = array_map(function($a){ return (string)$a; }, $args);
$this->assertEquals($args, $expected_array);
}
}