Test size
This commit is contained in:
@@ -9,13 +9,16 @@ use Twig\TwigFunction;
|
|||||||
|
|
||||||
final class IconExtension extends AbstractExtension
|
final class IconExtension extends AbstractExtension
|
||||||
{
|
{
|
||||||
public function __construct(private array $directories) {}
|
public const DEFAULT_SIZE = 32;
|
||||||
|
|
||||||
private const DEFAULT_OPTIONS = [
|
private const DEFAULT_OPTIONS = [
|
||||||
'icon' => null,
|
'icon' => null,
|
||||||
'title' => null,
|
'title' => null,
|
||||||
|
'size' => self::DEFAULT_SIZE
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function __construct(private array $directories) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
@@ -30,6 +33,7 @@ final class IconExtension extends AbstractExtension
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $options
|
* @param array $options
|
||||||
|
* [ options here ]
|
||||||
*/
|
*/
|
||||||
public function renderIcon(array $userOptions): string
|
public function renderIcon(array $userOptions): string
|
||||||
{
|
{
|
||||||
@@ -43,6 +47,16 @@ final class IconExtension extends AbstractExtension
|
|||||||
$markup = $this->addTitleToMarkup($cleanSvgMarkup, $options['title']);
|
$markup = $this->addTitleToMarkup($cleanSvgMarkup, $options['title']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($options['size'] < 0)
|
||||||
|
throw new \InvalidArgumentException('Size must not be negative');
|
||||||
|
|
||||||
|
if (!is_int($options['size']))
|
||||||
|
throw new \TypeError('Size value must be an integer');
|
||||||
|
|
||||||
|
|
||||||
|
$markup = $this->setSize($markup, $options['size']);
|
||||||
|
|
||||||
|
|
||||||
return $markup;
|
return $markup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,12 +101,35 @@ final class IconExtension extends AbstractExtension
|
|||||||
|
|
||||||
private function addTitleToMarkup(string $markup, ?string $title): string
|
private function addTitleToMarkup(string $markup, ?string $title): string
|
||||||
{
|
{
|
||||||
if (null === $title) {
|
if (null === $title)
|
||||||
return $markup;
|
return $markup;
|
||||||
}
|
|
||||||
|
|
||||||
return preg_replace('/(<svg(.|\n)*?>\n?)/', "$1<title>$title</title>", $markup);
|
return preg_replace('/(<svg(.|\n)*?>\n?)/', "$1<title>$title</title>", $markup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function setSize(string $content, int $size): string
|
||||||
|
{
|
||||||
|
$svgAsXmlElement = new \SimpleXMLElement($content);
|
||||||
|
$svgAsXmlElement = $this->addAttributeToXmlElement($svgAsXmlElement, 'width', $size);
|
||||||
|
$svgAsXmlElement = $this->addAttributeToXmlElement($svgAsXmlElement, 'height', $size);
|
||||||
|
return $this->removeXMLDeclaration($svgAsXmlElement->saveXML());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function removeXMLDeclaration(string $content): string
|
||||||
|
{
|
||||||
|
return trim(preg_replace('/<\?xml.*\?>/', '', $content));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addAttributeToXmlElement(\SimpleXMLElement $xml, string $attrName, mixed $attrValue): \SimpleXMLElement
|
||||||
|
{
|
||||||
|
if (isset($xml->attributes()->$attrName)) {
|
||||||
|
$xml->attributes()->$attrName = strval($attrValue);
|
||||||
|
} else {
|
||||||
|
$xml->addAttribute($attrName, strval($attrValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $xml;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class IconNotFound extends \Exception {};
|
class IconNotFound extends \Exception {};
|
||||||
|
|||||||
@@ -71,4 +71,76 @@ class IconExtensionTest extends TestCase
|
|||||||
$this->expectException(\InvalidArgumentException::class);
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
$this->icon->renderIcon(['icon' => self::ICON, 'title' => '']);
|
$this->icon->renderIcon(['icon' => self::ICON, 'title' => '']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testThrowsWhenPassedNegativeSizeValue(): void
|
||||||
|
{
|
||||||
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
|
$this->icon->renderIcon(['icon' => self::ICON, 'size' => -1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testThrowsWhenSizeIsNotAnInt(): void
|
||||||
|
{
|
||||||
|
$this->expectException(\TypeError::class);
|
||||||
|
$this->icon->renderIcon(['icon' => self::ICON, 'size' => 1.0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSvgWidthIsSet(): void
|
||||||
|
{
|
||||||
|
$regex = '/^<svg.+?width="99"/';
|
||||||
|
$content = $this->icon->renderIcon(['icon' => self::ICON, 'size' => 99]);
|
||||||
|
$this->assertMatchesRegularExpression($regex, $content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSvgHeightIsSet(): void
|
||||||
|
{
|
||||||
|
$regex = '/^<svg.+?width="99"/';
|
||||||
|
$content = $this->icon->renderIcon(['icon' => self::ICON, 'size' => 99]);
|
||||||
|
$this->assertMatchesRegularExpression($regex, $content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNoXmlDeclarationIsAdded(): void
|
||||||
|
{
|
||||||
|
$content = $this->icon->renderIcon(['icon' => self::ICON, 'size' => 99]);
|
||||||
|
$this->assertStringNotContainsString('<xml', $content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOnlyOneWidthAttributeIsSet(): void
|
||||||
|
{
|
||||||
|
$content = $this->icon->renderIcon(['icon' => self::ICON, 'size' => 99]);
|
||||||
|
$timesMatched = preg_match_all('/width="99"/', $content);
|
||||||
|
$this->assertSame(1, $timesMatched);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOnlyOneHeightAttributeIsSet(): void
|
||||||
|
{
|
||||||
|
$content = $this->icon->renderIcon(['icon' => self::ICON, 'size' => 99]);
|
||||||
|
$timesMatched = preg_match_all('/height="99"/', $content);
|
||||||
|
$this->assertSame(1, $timesMatched);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDefaultSizeIsSetOnSvgIfNoSizeOptionPassed(): void
|
||||||
|
{
|
||||||
|
$defaultSize = IconExtension::DEFAULT_SIZE;
|
||||||
|
$content = $this->icon->renderIcon(['icon' => self::ICON]);
|
||||||
|
|
||||||
|
$regex = "/^<svg.+?width=\"{$defaultSize}\"/";
|
||||||
|
$this->assertMatchesRegularExpression($regex, $content);
|
||||||
|
|
||||||
|
$regex = "/^<svg.+?height=\"{$defaultSize}\"/";
|
||||||
|
$this->assertMatchesRegularExpression($regex, $content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDefaultSizeIsOnlySetOnce(): void
|
||||||
|
{
|
||||||
|
$defaultSize = IconExtension::DEFAULT_SIZE;
|
||||||
|
$content = $this->icon->renderIcon(['icon' => self::ICON]);
|
||||||
|
|
||||||
|
$widthRegex = "/width=\"{$defaultSize}\"/";
|
||||||
|
$timesMatched = preg_match_all($widthRegex, $content);
|
||||||
|
$this->assertSame(1, $timesMatched);
|
||||||
|
|
||||||
|
$heightRegex = "/height=\"{$defaultSize}\"/";
|
||||||
|
$timesMatched = preg_match_all($heightRegex, $content);
|
||||||
|
$this->assertSame(1, $timesMatched);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="96 96 320 320">
|
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="96 96 320 320">
|
||||||
<title>Some cross lol</title>
|
<title>Some cross lol</title>
|
||||||
<line x1="256" y1="112" x2="256" y2="400" style="fill: none; stroke: rgb(0,0, 0); stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"></line>
|
<line x1="256" y1="112" x2="256" y2="400" width="101" height="101" style="fill: none; stroke: rgb(0,0, 0); stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"></line>
|
||||||
<line x1="400" y1="256" x2="112" y2="256" style="fill: none; stroke: #000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"></line>
|
<line x1="400" y1="256" x2="112" y2="256" width="102" height="102" style="fill: none; stroke: #000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"></line>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 448 B After Width: | Height: | Size: 498 B |
Reference in New Issue
Block a user