Skip to content

Commit

Permalink
Fixed a bug where the unique name was not unique
Browse files Browse the repository at this point in the history
  • Loading branch information
boekkooi committed Jan 14, 2015
1 parent da50d76 commit 2ec1cd9
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 43 deletions.
2 changes: 1 addition & 1 deletion doc/twig-defer.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Example
{{ defer('js') }}
```

Output:
Output:
```html
<p>Hello</p>
<script src="1.js" />
Expand Down
25 changes: 21 additions & 4 deletions src/Twig/TokenParser/Defer.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,7 @@ public function parse(Twig_Token $token)
return null;
}
} else {
$i = 0;
do {
$name = $this->blockPrefix . $reference . ($i++);
} while ($this->parser->hasBlock($name));
$name = $this->createUniqueBlockName($token, $reference);
}

$this->parser->setBlock($name, $block = new Node\Defer($name, new Twig_Node(array()), $lineno));
Expand Down Expand Up @@ -125,4 +122,24 @@ protected function bodyParse(Twig_TokenStream $stream, $name)

return $body;
}

/**
* @param Twig_Token $token
* @param $reference
* @return string
*/
private function createUniqueBlockName(Twig_Token $token, $reference)
{
$name = $this->blockPrefix . $reference . sha1($this->parser->getFilename() . $token->getLine());
if (!$this->parser->hasBlock($name)) {
return $name;
}

$i = 0;
do {
$tmpName = $name . '_' . ($i++);
} while ($this->parser->hasBlock($tmpName));

return $tmpName;
}
}
90 changes: 52 additions & 38 deletions tests/Twig/TokenParser/DeferTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,28 @@
*/
class DeferTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \Twig_Environment
*/
protected $env;

protected function setUp()
{
$this->env = new \Twig_Environment(
new \Twig_Loader_String(),
array('cache' => false, 'autoescape' => false, 'optimizations' => 0)
);
}

/**
* @dataProvider getTests
*/
public function testCompile($source, \Twig_Node $bodyExpected, \Twig_Node $blocksExpected)
{
$env = new \Twig_Environment(new \Twig_Loader_String(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
$env->addTokenParser(new Defer('def_'));
$stream = $env->tokenize($source);
$parser = new \Twig_Parser($env);

$result = $parser->parse($stream);
$result = $this->parse($source);

$this->assertCount(1, $result->getNode('body'));
$this->assertEquals($bodyExpected, $result->getNode('body')->getNode(0));
$this->assertEquals($bodyExpected, $result->getNode('body')->getNode(0), "Nodes must be the same for:\n" . $source);

$this->assertCount(count($blocksExpected), $result->getNode('blocks'));
$this->assertEquals($blocksExpected, $result->getNode('blocks'));
Expand All @@ -36,26 +44,16 @@ public function testCompile($source, \Twig_Node $bodyExpected, \Twig_Node $block
*/
public function testNoEndBlock()
{
$env = new \Twig_Environment(new \Twig_Loader_String(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
$env->addTokenParser(new Defer('def_'));
$stream = $env->tokenize('{% defer js "x" "foo" %}');
$parser = new \Twig_Parser($env);

$parser->parse($stream);
$this->parse('{% defer js "x" "foo" %}');
}

/**
* @expectedException \Twig_Error_Syntax
* @expectedExceptionMessage Expected enddefer for defer 'def_js0' (but css given)
* @expectedExceptionMessage Expected enddefer for defer 'def_js356a192b7913b04c54574d18c28d46e6395428ab' (but css given)
*/
public function testInvalidEndBlockName()
{
$env = new \Twig_Environment(new \Twig_Loader_String(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
$env->addTokenParser(new Defer('def_'));
$stream = $env->tokenize('{% defer js %}X{% enddefer css %}');
$parser = new \Twig_Parser($env);

$parser->parse($stream);
$this->parse('{% defer js %}X{% enddefer css %}');
}

/**
Expand All @@ -64,24 +62,22 @@ public function testInvalidEndBlockName()
*/
public function testInvalidEndBlock()
{
$env = new \Twig_Environment(new \Twig_Loader_String(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0));
$env->addTokenParser(new Defer('def_'));
$stream = $env->tokenize('{% defer js %}X{% endblock js %}');
$parser = new \Twig_Parser($env);

$parser->parse($stream);
$this->parse('{% defer js %}X{% endblock js %}');
}

public function getTests()
{
$defLine1 = 'def_js'.sha1(1);
$defLine2 = 'def_js'.sha1(2);

return array(
array(<<<EOF
{% defer js %}X{% enddefer %}
EOF
,
new DeferReference('def_js0', false, false, 'js', null, 1, 'defer'),
new DeferReference($defLine1, false, false, 'js', null, 1, 'defer'),
new \Twig_Node(array(
'def_js0' => new \Twig_Node_Body(array(new DeferNode('def_js0', new \Twig_Node_Text('X', 1), 1)), array(), 1)
$defLine1 => new \Twig_Node_Body(array(new DeferNode($defLine1, new \Twig_Node_Text('X', 1), 1)), array(), 1)
))
),
array(<<<EOF
Expand All @@ -90,12 +86,12 @@ public function getTests()
EOF
,
new \Twig_Node(array(
new DeferReference('def_js0', false, false, 'js', null, 1, 'defer'),
new DeferReference('def_js1', false, false, 'js', null, 2, 'defer')
new DeferReference($defLine1, false, false, 'js', null, 1, 'defer'),
new DeferReference($defLine2, false, false, 'js', null, 2, 'defer')
), array(), 1),
new \Twig_Node(array(
'def_js0' => new \Twig_Node_Body(array(new DeferNode('def_js0', new \Twig_Node_Text('X1', 1), 1)), array(), 1),
'def_js1' => new \Twig_Node_Body(array(new DeferNode('def_js1', new \Twig_Node_Text('X2', 2), 2)), array(), 2)
$defLine1 => new \Twig_Node_Body(array(new DeferNode($defLine1, new \Twig_Node_Text('X1', 1), 1)), array(), 1),
$defLine2 => new \Twig_Node_Body(array(new DeferNode($defLine2, new \Twig_Node_Text('X2', 2), 2)), array(), 2)
))
),
array(<<<EOF
Expand All @@ -104,12 +100,12 @@ public function getTests()
EOF
,
new \Twig_Node(array(
new DeferReference('def_js0', 'x', false, 'js', null, 1, 'defer'),
new DeferReference('def_js1', 'y', false, 'js', null, 2, 'defer')
new DeferReference($defLine1, 'x', false, 'js', null, 1, 'defer'),
new DeferReference($defLine2, 'y', false, 'js', null, 2, 'defer')
), array(), 1),
new \Twig_Node(array(
'def_js0' => new \Twig_Node_Body(array(new DeferNode('def_js0', new \Twig_Node_Text('VAR X', 1), 1)), array(), 1),
'def_js1' => new \Twig_Node_Body(array(new DeferNode('def_js1', new \Twig_Node_Text('VAR Y', 2), 2)), array(), 2)
$defLine1 => new \Twig_Node_Body(array(new DeferNode($defLine1, new \Twig_Node_Text('VAR X', 1), 1)), array(), 1),
$defLine2 => new \Twig_Node_Body(array(new DeferNode($defLine2, new \Twig_Node_Text('VAR Y', 2), 2)), array(), 2)
))
),
array(<<<EOF
Expand All @@ -134,13 +130,31 @@ public function getTests()
,
new \Twig_Node(array(
new DeferReference('def_jsx', false, true, 'js', 1, 1, 'defer'),
new DeferReference('def_js0', false, false, 'js', 0, 2, 'defer')
new DeferReference($defLine2, false, false, 'js', 0, 2, 'defer')
), array(), 1),
new \Twig_Node(array(
'def_jsx' => new \Twig_Node_Body(array(new DeferNode('def_jsx', new \Twig_Node_Text('order 1', 1), 1)), array(), 1),
'def_js0' => new \Twig_Node_Body(array(new DeferNode('def_js0', new \Twig_Node_Text('order 0', 2), 2)), array(), 2)
$defLine2 => new \Twig_Node_Body(array(new DeferNode($defLine2, new \Twig_Node_Text('order 0', 2), 2)), array(), 2)
))
)
);
}

/**
* @param $source
* @return false|\Twig_Node_Module|\Twig_NodeInterface|void
* @throws \Exception
* @throws \Twig_Error_Syntax
*/
private function parse($source)
{
$env = $this->env;
$env->addTokenParser(new Defer('def_'));
$stream = $env->tokenize($source);
$parser = new \Twig_Parser($env);

$result = $parser->parse($stream);

return $result;
}
}

0 comments on commit 2ec1cd9

Please sign in to comment.