-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add "data_table_theme" Twig node (#102)
* Add "data_table_theme" Twig node
- Loading branch information
Showing
7 changed files
with
352 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Kreyu\Bundle\DataTableBundle\Twig; | ||
|
||
use Twig\Compiler; | ||
use Twig\Node\Node; | ||
|
||
class DataTableThemeNode extends Node | ||
{ | ||
public function __construct(Node $dataTable, Node $themes, int $lineno, ?string $tag = null, bool $only = false) | ||
{ | ||
parent::__construct(['data_table' => $dataTable, 'themes' => $themes], ['only' => $only], $lineno, $tag); | ||
} | ||
|
||
public function compile(Compiler $compiler): void | ||
{ | ||
$compiler | ||
->addDebugInfo($this) | ||
->write(sprintf('$this->env->getExtension("%s")->setDataTableThemes(', DataTableExtension::class)) | ||
->subcompile($this->getNode('data_table')) | ||
->raw(', ') | ||
->subcompile($this->getNode('themes')) | ||
->raw(sprintf(", %s);\n", $this->getAttribute('only') ? 'true' : 'false')) | ||
; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Kreyu\Bundle\DataTableBundle\Twig; | ||
|
||
use Twig\Node\Expression\ArrayExpression; | ||
use Twig\Token; | ||
use Twig\TokenParser\AbstractTokenParser; | ||
|
||
class DataTableThemeTokenParser extends AbstractTokenParser | ||
{ | ||
public function parse(Token $token): DataTableThemeNode | ||
{ | ||
$lineno = $token->getLine(); | ||
$stream = $this->parser->getStream(); | ||
|
||
$dataTable = $this->parser->getExpressionParser()->parseExpression(); | ||
$only = false; | ||
|
||
if ($this->parser->getStream()->test(Token::NAME_TYPE, 'with')) { | ||
$this->parser->getStream()->next(); | ||
|
||
$themes = $this->parser->getExpressionParser()->parseExpression(); | ||
|
||
if ($this->parser->getStream()->nextIf(Token::NAME_TYPE, 'only')) { | ||
$only = true; | ||
} | ||
} else { | ||
$themes = new ArrayExpression([], $stream->getCurrent()->getLine()); | ||
|
||
do { | ||
$themes->addElement($this->parser->getExpressionParser()->parseExpression()); | ||
} while (!$stream->test(Token::BLOCK_END_TYPE)); | ||
} | ||
|
||
$stream->expect(Token::BLOCK_END_TYPE); | ||
|
||
return new DataTableThemeNode($dataTable, $themes, $lineno, $this->getTag(), $only); | ||
} | ||
|
||
public function getTag(): string | ||
{ | ||
return 'data_table_theme'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Kreyu\Bundle\DataTableBundle\Tests\Unit\Twig; | ||
|
||
use Kreyu\Bundle\DataTableBundle\Column\ColumnSortUrlGeneratorInterface; | ||
use Kreyu\Bundle\DataTableBundle\DataTableView; | ||
use Kreyu\Bundle\DataTableBundle\Filter\FilterClearUrlGeneratorInterface; | ||
use Kreyu\Bundle\DataTableBundle\Twig\DataTableExtension; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
class DataTableExtensionTest extends TestCase | ||
{ | ||
public function testSetDataTableThemes(): void | ||
{ | ||
$view = new DataTableView(); | ||
$view->vars['themes'] = ['foo']; | ||
|
||
$this->createExtension()->setDataTableThemes($view, ['bar']); | ||
|
||
$this->assertEquals(['foo', 'bar'], $view->vars['themes']); | ||
} | ||
|
||
public function testSetDataTableThemesWithOnly(): void | ||
{ | ||
$view = new DataTableView(); | ||
$view->vars['themes'] = ['foo']; | ||
|
||
$this->createExtension()->setDataTableThemes($view, ['bar'], true); | ||
|
||
$this->assertEquals(['bar'], $view->vars['themes']); | ||
} | ||
|
||
private function createExtension(): DataTableExtension | ||
{ | ||
return new DataTableExtension( | ||
$this->createStub(ColumnSortUrlGeneratorInterface::class), | ||
$this->createStub(FilterClearUrlGeneratorInterface::class), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Kreyu\Bundle\DataTableBundle\Tests\Unit\Twig; | ||
|
||
use Kreyu\Bundle\DataTableBundle\Twig\DataTableExtension; | ||
use Kreyu\Bundle\DataTableBundle\Twig\DataTableThemeNode; | ||
use PHPUnit\Framework\Attributes\DataProvider; | ||
use PHPUnit\Framework\TestCase; | ||
use Twig\Compiler; | ||
use Twig\Environment; | ||
use Twig\Loader\LoaderInterface; | ||
use Twig\Node\Expression\ArrayExpression; | ||
use Twig\Node\Expression\ConstantExpression; | ||
use Twig\Node\Expression\NameExpression; | ||
use Twig\Node\Node; | ||
|
||
class DataTableThemeNodeTest extends TestCase | ||
{ | ||
public function testConstructor() | ||
{ | ||
$dataTable = new NameExpression('data_table', 0); | ||
|
||
$themes = new Node([ | ||
new ConstantExpression('foo', 0), | ||
new ConstantExpression('bar', 0), | ||
]); | ||
|
||
$node = new DataTableThemeNode($dataTable, $themes, 0); | ||
|
||
$this->assertEquals($dataTable, $node->getNode('data_table')); | ||
$this->assertEquals($themes, $node->getNode('themes')); | ||
$this->assertFalse($node->getAttribute('only')); | ||
} | ||
|
||
#[DataProvider('provideCompileCases')] | ||
public function testCompile(DataTableThemeNode $node, array $expected) | ||
{ | ||
$environment = new Environment($this->createMock(LoaderInterface::class)); | ||
|
||
$extension = $this->createMock(DataTableExtension::class); | ||
|
||
$environment->addExtension($extension); | ||
|
||
$compiler = new Compiler($environment); | ||
|
||
// In Twig 2, the ["foo", "bar"] is parsed with as [0 => "foo", 1 => "bar"]. | ||
// In Twig 3, the ["foo", "bar"] is parsed with as ["foo", "bar"]. | ||
// For compatibility, we are checking whether the compiled value is equal to one of the expected values. | ||
$this->assertThat(trim($compiler->compile($node)->getSource()), $this->logicalOr( | ||
$this->equalTo($expected[0]), | ||
$this->equalTo($expected[1]), | ||
)); | ||
} | ||
|
||
public static function provideCompileCases(): iterable | ||
{ | ||
yield 'single theme' => [ | ||
new DataTableThemeNode( | ||
new NameExpression('data_table', 0), | ||
new ArrayExpression([ | ||
new ConstantExpression(0, 0), | ||
new ConstantExpression('foo', 0), | ||
], 0), | ||
0, | ||
'data_table_theme', | ||
false, | ||
), [ | ||
'$this->env->getExtension("Kreyu\\Bundle\\DataTableBundle\\Twig\\DataTableExtension")->setDataTableThemes(($context["data_table"] ?? null), ["foo"], false);', | ||
'$this->env->getExtension("Kreyu\\Bundle\\DataTableBundle\\Twig\\DataTableExtension")->setDataTableThemes(($context["data_table"] ?? null), [0 => "foo"], false);', | ||
], | ||
]; | ||
|
||
yield 'multiple themes without only' => [ | ||
new DataTableThemeNode( | ||
new NameExpression('data_table', 0), | ||
new ArrayExpression([ | ||
new ConstantExpression(0, 0), | ||
new ConstantExpression('foo', 0), | ||
new ConstantExpression(1, 0), | ||
new ConstantExpression('bar', 0), | ||
], 0), | ||
0, | ||
'data_table_theme', | ||
false, | ||
), [ | ||
'$this->env->getExtension("Kreyu\\Bundle\\DataTableBundle\\Twig\\DataTableExtension")->setDataTableThemes(($context["data_table"] ?? null), ["foo", "bar"], false);', | ||
'$this->env->getExtension("Kreyu\\Bundle\\DataTableBundle\\Twig\\DataTableExtension")->setDataTableThemes(($context["data_table"] ?? null), [0 => "foo", 1 => "bar"], false);', | ||
], | ||
]; | ||
|
||
yield 'multiple themes with only' => [ | ||
new DataTableThemeNode( | ||
new NameExpression('data_table', 0), | ||
new ArrayExpression([ | ||
new ConstantExpression(0, 0), | ||
new ConstantExpression('foo', 0), | ||
new ConstantExpression(1, 0), | ||
new ConstantExpression('bar', 0), | ||
], 0), | ||
0, | ||
'data_table_theme', | ||
true, | ||
), [ | ||
'$this->env->getExtension("Kreyu\\Bundle\\DataTableBundle\\Twig\\DataTableExtension")->setDataTableThemes(($context["data_table"] ?? null), ["foo", "bar"], true);', | ||
'$this->env->getExtension("Kreyu\\Bundle\\DataTableBundle\\Twig\\DataTableExtension")->setDataTableThemes(($context["data_table"] ?? null), [0 => "foo", 1 => "bar"], true);', | ||
], | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Kreyu\Bundle\DataTableBundle\Tests\Unit\Twig; | ||
|
||
use Kreyu\Bundle\DataTableBundle\Twig\DataTableThemeNode; | ||
use Kreyu\Bundle\DataTableBundle\Twig\DataTableThemeTokenParser; | ||
use PHPUnit\Framework\Attributes\DataProvider; | ||
use PHPUnit\Framework\TestCase; | ||
use Twig\Environment; | ||
use Twig\Loader\LoaderInterface; | ||
use Twig\Node\Expression\ArrayExpression; | ||
use Twig\Node\Expression\ConstantExpression; | ||
use Twig\Node\Expression\NameExpression; | ||
use Twig\Parser; | ||
use Twig\Source; | ||
|
||
class DataTableThemeTokenParserTest extends TestCase | ||
{ | ||
#[DataProvider('provideCompileCases')] | ||
public function testCompile($source, $expected) | ||
{ | ||
$env = new Environment($this->createMock(LoaderInterface::class), ['cache' => false, 'autoescape' => false, 'optimizations' => 0]); | ||
$env->addTokenParser(new DataTableThemeTokenParser()); | ||
|
||
$source = new Source($source, ''); | ||
$stream = $env->tokenize($source); | ||
$parser = new Parser($env); | ||
|
||
$expected->setSourceContext($source); | ||
|
||
$this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode('0')); | ||
} | ||
|
||
public static function provideCompileCases(): iterable | ||
{ | ||
yield 'single theme' => [ | ||
'{% data_table_theme data_table "foo" %}', | ||
new DataTableThemeNode( | ||
new NameExpression('data_table', 1), | ||
new ArrayExpression([ | ||
new ConstantExpression(0, 1), | ||
new ConstantExpression('foo', 1), | ||
], 1), | ||
1, | ||
'data_table_theme', | ||
false, | ||
), | ||
]; | ||
|
||
yield 'multiple themes without only' => [ | ||
'{% data_table_theme data_table with ["foo", "bar"] %}', | ||
new DataTableThemeNode( | ||
new NameExpression('data_table', 1), | ||
new ArrayExpression([ | ||
new ConstantExpression(0, 1), | ||
new ConstantExpression('foo', 1), | ||
new ConstantExpression(1, 1), | ||
new ConstantExpression('bar', 1), | ||
], 1), | ||
1, | ||
'data_table_theme', | ||
false, | ||
), | ||
]; | ||
|
||
yield 'multiple themes with only' => [ | ||
'{% data_table_theme data_table with ["foo", "bar"] only %}', | ||
new DataTableThemeNode( | ||
new NameExpression('data_table', 1), | ||
new ArrayExpression([ | ||
new ConstantExpression(0, 1), | ||
new ConstantExpression('foo', 1), | ||
new ConstantExpression(1, 1), | ||
new ConstantExpression('bar', 1), | ||
], 1), | ||
1, | ||
'data_table_theme', | ||
true, | ||
), | ||
]; | ||
} | ||
} |