From b959b4ce166701c32171a49c4a3961789dff65da Mon Sep 17 00:00:00 2001 From: kylekatarnls Date: Wed, 20 Sep 2023 23:44:41 +0200 Subject: [PATCH] Add exception for null cache_dir option --- .../Formatter/Formatter/Format/XmlFormat.php | 6 ++ .../Renderer/Renderer/Adapter/FileAdapter.php | 10 +++ tests/Phug/Adapter/FileAdapterTest.php | 53 ++++++++++++ tests/Phug/Element/AttributeElementTest.php | 85 +++++++++++-------- tests/Phug/Element/ExpressionElementTest.php | 12 +++ tests/Phug/Element/MixinElementTest.php | 33 +++++++ tests/Phug/Format/FormatExtendTest.php | 13 +++ 7 files changed, 177 insertions(+), 35 deletions(-) diff --git a/src/Phug/Formatter/Formatter/Format/XmlFormat.php b/src/Phug/Formatter/Formatter/Format/XmlFormat.php index e7b885df..757ade84 100644 --- a/src/Phug/Formatter/Formatter/Format/XmlFormat.php +++ b/src/Phug/Formatter/Formatter/Format/XmlFormat.php @@ -167,6 +167,7 @@ protected function formatAttributeElement(AttributeElement $element) $value = $element->getValue(); $name = $element->getName(); $nonEmptyAttribute = ($name === 'class' || $name === 'id'); + if ($nonEmptyAttribute && ( !$value || ($value instanceof TextElement && ((string) $value->getValue()) === '') || @@ -174,12 +175,15 @@ protected function formatAttributeElement(AttributeElement $element) )) { return ''; } + if ($value instanceof ExpressionElement) { if ($nonEmptyAttribute && in_array(trim($value->getValue()), ['', '""', "''"], true)) { return ''; } + if (strtolower($value->getValue()) === 'true') { $formattedValue = null; + if ($name instanceof ExpressionElement) { $bufferVariable = $this->pattern('buffer_variable'); $name = $this->pattern( @@ -193,6 +197,7 @@ protected function formatAttributeElement(AttributeElement $element) $value = new ExpressionElement($bufferVariable); $formattedValue = $this->format($value); } + $formattedName = $this->format($name); $formattedValue = $formattedValue || $formattedValue === '0' ? $formattedValue @@ -204,6 +209,7 @@ protected function formatAttributeElement(AttributeElement $element) $formattedValue ); } + if (in_array(strtolower($value->getValue()), ['false', 'null', 'undefined'], true)) { return ''; } diff --git a/src/Phug/Renderer/Renderer/Adapter/FileAdapter.php b/src/Phug/Renderer/Renderer/Adapter/FileAdapter.php index bde9953c..9bd79e20 100644 --- a/src/Phug/Renderer/Renderer/Adapter/FileAdapter.php +++ b/src/Phug/Renderer/Renderer/Adapter/FileAdapter.php @@ -394,15 +394,25 @@ private function getCacheDirectory() $cacheFolder = $this->hasOption('cache_dir') ? $this->getOption('cache_dir') : null; + if (!$cacheFolder && $cacheFolder !== false) { $cacheFolder = $this->getRenderer()->hasOption('cache_dir') ? $this->getRenderer()->getOption('cache_dir') : null; } + if ($cacheFolder === true) { $cacheFolder = $this->getOption('tmp_dir'); } + if ($cacheFolder === null) { + throw new RuntimeException( + 'You need to set "cache_dir" option to a writable location in order '. + 'to use cache feature.', + 7 + ); + } + if (!is_dir($cacheFolder) && !@mkdir($cacheFolder, 0777, true)) { throw new RuntimeException( $cacheFolder.': Cache directory doesn\'t exist.'."\n". diff --git a/tests/Phug/Adapter/FileAdapterTest.php b/tests/Phug/Adapter/FileAdapterTest.php index c3574232..4c6d19e0 100644 --- a/tests/Phug/Adapter/FileAdapterTest.php +++ b/tests/Phug/Adapter/FileAdapterTest.php @@ -172,6 +172,59 @@ function ($path, $input) { self::assertCount(2, $files); } + /** + * @covers ::getCacheDirectory + * + * @expectedException \RuntimeException + * + * @expectedExceptionMessage You need to set "cache_dir" option to a writable location in order to use cache feature. + */ + public function testNullCacheDir() + { + ExceptionAnnotationReader::read($this, __METHOD__); + + $renderer = new Renderer([ + 'cache_dir' => null, + 'adapter_class_name' => FileAdapter::class, + ]); + + /** @var FileAdapter $adapter */ + $adapter = $renderer->getAdapter(); + + self::assertInstanceOf(FileAdapter::class, $adapter); + + $adapter->cache('foo', 'bar', function () { + return 'abc'; + }); + } + + /** + * @covers ::getCacheDirectory + * + * @expectedException \RuntimeException + * + * @expectedExceptionMessage You need to set "cache_dir" option to a writable location in order to use cache feature. + */ + public function testUnsetCacheDir() + { + ExceptionAnnotationReader::read($this, __METHOD__); + + $renderer = new Renderer([ + 'adapter_class_name' => FileAdapter::class, + ]); + /** @var FileAdapter $adapter */ + $adapter = $renderer->getAdapter(); + + $renderer->unsetOption('cache_dir'); + $adapter->unsetOption('cache_dir'); + + self::assertInstanceOf(FileAdapter::class, $adapter); + + $adapter->cache('foo', 'bar', function () { + return 'abc'; + }); + } + /** * @covers :: * @covers ::getCachePath diff --git a/tests/Phug/Element/AttributeElementTest.php b/tests/Phug/Element/AttributeElementTest.php index c1f28361..6005ba7d 100644 --- a/tests/Phug/Element/AttributeElementTest.php +++ b/tests/Phug/Element/AttributeElementTest.php @@ -61,47 +61,62 @@ public function testStaticAttributeElement() 'default_format' => XmlFormat::class, ]); - $attribute = new AttributeElement('foo', new ExpressionElement('null')); - - ob_start(); - $php = $formatter->format($attribute); - eval('?>'.$formatter->formatDependencies().$php); - $actual = ob_get_contents(); - ob_end_clean(); - - self::assertSame('', $actual); - - $attribute = new AttributeElement('class', '""'); - - ob_start(); - $php = $formatter->format($attribute); - eval('?>'.$formatter->formatDependencies().$php); - $actual = ob_get_contents(); - ob_end_clean(); - - self::assertSame('', $actual); - - $attribute = new AttributeElement('class', new ExpressionElement("''")); - - ob_start(); - $php = $formatter->format($attribute); - eval('?>'.$formatter->formatDependencies().$php); - $actual = ob_get_contents(); - ob_end_clean(); - - self::assertSame('', $actual); - - $attribute = new AttributeElement('width', '12'); - $iframe = new MarkupElement('iframe'); - $iframe->getAttributes()->attach($attribute); +// $attribute = new AttributeElement('foo', new ExpressionElement('null')); +// +// ob_start(); +// $php = $formatter->format($attribute); +/* eval('?>'.$formatter->formatDependencies().$php);*/ +// $actual = ob_get_contents(); +// ob_end_clean(); +// +// self::assertSame('', $actual); +// +// $attribute = new AttributeElement('class', '""'); +// +// ob_start(); +// $php = $formatter->format($attribute); +/* eval('?>'.$formatter->formatDependencies().$php);*/ +// $actual = ob_get_contents(); +// ob_end_clean(); +// +// self::assertSame('', $actual); +// +// $attribute = new AttributeElement('class', new ExpressionElement("''")); +// +// ob_start(); +// $php = $formatter->format($attribute); +/* eval('?>'.$formatter->formatDependencies().$php);*/ +// $actual = ob_get_contents(); +// ob_end_clean(); +// +// self::assertSame('', $actual); +// +// $attribute = new AttributeElement('width', '12'); +// $iframe = new MarkupElement('iframe'); +// $iframe->getAttributes()->attach($attribute); +// +// ob_start(); +// $php = $formatter->format($iframe); +/* eval('?>'.$formatter->formatDependencies().$php);*/ +// $actual = ob_get_contents(); +// ob_end_clean(); +// +// self::assertSame('', $actual); + + $attribute = new AttributeElement( + new ExpressionElement('$mandatoryName'), + new ExpressionElement('true') + ); + $input = new MarkupElement('input', true); + $input->getAttributes()->attach($attribute); ob_start(); - $php = $formatter->format($iframe); + $php = $formatter->format($input); eval('?>'.$formatter->formatDependencies().$php); $actual = ob_get_contents(); ob_end_clean(); - self::assertSame('', $actual); + self::assertSame('', $actual); } /** diff --git a/tests/Phug/Element/ExpressionElementTest.php b/tests/Phug/Element/ExpressionElementTest.php index 65d1b7e5..a30379a0 100644 --- a/tests/Phug/Element/ExpressionElementTest.php +++ b/tests/Phug/Element/ExpressionElementTest.php @@ -2,6 +2,7 @@ namespace Phug\Test\Element; +use Phug\Ast\Node; use Phug\Formatter; use Phug\Formatter\Element\AttributeElement; use Phug\Formatter\Element\ExpressionElement; @@ -105,4 +106,15 @@ public function testTrueDynamicValue() $actual ); } + + /** + * @covers \Phug\Formatter\AbstractElement::dump + */ + public function testDump() + { + $expression = new ExpressionElement('$foo'); + $expression->appendChild(new Node()); + + self::assertSame("Expression\n ".Node::class, $expression->dump()); + } } diff --git a/tests/Phug/Element/MixinElementTest.php b/tests/Phug/Element/MixinElementTest.php index 572148a0..1eb29303 100644 --- a/tests/Phug/Element/MixinElementTest.php +++ b/tests/Phug/Element/MixinElementTest.php @@ -7,6 +7,7 @@ use Phug\Formatter\Element\AttributeElement; use Phug\Formatter\Element\CodeElement; use Phug\Formatter\Element\DocumentElement; +use Phug\Formatter\Element\ExpressionElement; use Phug\Formatter\Element\MarkupElement; use Phug\Formatter\Element\MixinElement; use Phug\Formatter\Element\TextElement; @@ -127,6 +128,38 @@ public function testRequireAllMixins() self::assertSame('
block
', $html); } + /** + * @covers \Phug\Formatter\AbstractFormat::formatMixinElement + */ + public function testFormatMixinWithDynamicName() + { + $mixin = new MixinElement(); + $name = new ExpressionElement(); + $name->setValue('$var'); + $mixin->setName($name); + $div = new MarkupElement('p'); + $div->appendChild(new AnonymousBlockElement()); + $mixin->appendChild($div); + + $formatter = new Formatter(); + + $php = $formatter->format($mixin); + $formatter->requireAllMixins(); + $php = $formatter->formatDependencies().$php; + $call = ''; + + ob_start(); + $var = 'foo'; + eval('?>'.$php.$call); + $html = ob_get_contents(); + ob_end_clean(); + + self::assertSame('

foo

', $html); + } + /** * @covers \Phug\Formatter::getMixins * @covers \Phug\Formatter::requireMixin diff --git a/tests/Phug/Format/FormatExtendTest.php b/tests/Phug/Format/FormatExtendTest.php index 4e8f808f..e0e48467 100644 --- a/tests/Phug/Format/FormatExtendTest.php +++ b/tests/Phug/Format/FormatExtendTest.php @@ -5,6 +5,7 @@ use Phug\Formatter; use Phug\Formatter\Element\AttributeElement; use Phug\Formatter\Element\ExpressionElement; +use Phug\Formatter\Element\MarkupElement; use Phug\Util\TestCase; /** @@ -23,6 +24,18 @@ public function testExtendedFormat() $formatter = new Formatter(); $format = new FakeXmlFormat($formatter); + $attribute = new AttributeElement( + 'required', + new ExpressionElement('true') + ); + + ob_start(); + eval('?>'.$format->callFormatAttributeElement($attribute)); + $actual = ob_get_contents(); + ob_end_clean(); + + self::assertSame(' required="required"', $actual); + ob_start(); eval('?>'.$format->callFormatAttributeElement( new AttributeElement(new ExpressionElement('"foo" . "bar"'), 'abc')