Skip to content

Commit 8dd4ebd

Browse files
committed
bug #1607 [Icons] Compute viewBox with iconset data (+tests) (smnandre)
This PR was squashed before being merged into the 2.x branch. Discussion ---------- [Icons] Compute viewBox with iconset data (+tests) There were a bug for icons with no individual "height" attribute. Now it fallbacks on IconSet metada. And i started a test class for Iconify Commits ------- f3f9d12 [Icons] Compute viewBox with iconset data (+tests)
2 parents dd85ab2 + f3f9d12 commit 8dd4ebd

File tree

2 files changed

+127
-1
lines changed

2 files changed

+127
-1
lines changed

src/Icons/src/Iconify.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,14 @@ public function fetchIcon(string $prefix, string $name): Icon
6464
throw new IconNotFoundException(sprintf('The icon "%s:%s" does not exist on iconify.design.', $prefix, $name));
6565
}
6666

67+
$height = $data['icons'][$name]['height'] ?? $this->sets()[$prefix]['height'] ?? null;
68+
$width = $data['icons'][$name]['width'] ?? $this->sets()[$prefix]['width'] ?? null;
69+
if (null === $width && null === $height) {
70+
throw new \RuntimeException(sprintf('The icon "%s:%s" does not have a width or height.', $prefix, $name));
71+
}
72+
6773
return new Icon($data['icons'][$name]['body'], [
68-
'viewBox' => sprintf('0 0 %s %s', $data['width'], $data['height']),
74+
'viewBox' => sprintf('0 0 %s %s', $width ?? $height, $height ?? $width),
6975
]);
7076
}
7177

src/Icons/tests/Unit/IconifyTest.php

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\UX\Icons\Tests\Unit;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Cache\Adapter\NullAdapter;
16+
use Symfony\Component\HttpClient\MockHttpClient;
17+
use Symfony\Component\HttpClient\Response\JsonMockResponse;
18+
use Symfony\UX\Icons\Exception\IconNotFoundException;
19+
use Symfony\UX\Icons\Iconify;
20+
21+
/**
22+
* @author Simon André <[email protected]>
23+
*/
24+
class IconifyTest extends TestCase
25+
{
26+
public function testFetchIcon(): void
27+
{
28+
$iconify = new Iconify(
29+
cache: new NullAdapter(),
30+
endpoint: 'https://example.com',
31+
http: new MockHttpClient([
32+
new JsonMockResponse([
33+
'bi' => [],
34+
]),
35+
new JsonMockResponse([
36+
'icons' => [
37+
'heart' => [
38+
'body' => '<path d="M0 0h24v24H0z" fill="none"/>',
39+
'height' => 24,
40+
],
41+
],
42+
]),
43+
]),
44+
);
45+
46+
$icon = $iconify->fetchIcon('bi', 'heart');
47+
48+
$this->assertEquals($icon->getInnerSvg(), '<path d="M0 0h24v24H0z" fill="none"/>');
49+
$this->assertEquals($icon->getAttributes(), ['viewBox' => '0 0 24 24']);
50+
}
51+
52+
public function testFetchIconThrowsWhenIconSetDoesNotExists(): void
53+
{
54+
$iconify = new Iconify(
55+
cache: new NullAdapter(),
56+
endpoint: 'https://example.com',
57+
http: new MockHttpClient([
58+
new JsonMockResponse([]),
59+
]),
60+
);
61+
62+
$this->expectException(IconNotFoundException::class);
63+
$this->expectExceptionMessage('The icon "bi:heart" does not exist on iconify.design.');
64+
65+
$iconify->fetchIcon('bi', 'heart');
66+
}
67+
68+
public function testFetchIconUsesIconsetViewBoxHeight(): void
69+
{
70+
$iconify = new Iconify(
71+
cache: new NullAdapter(),
72+
endpoint: 'https://example.com',
73+
http: new MockHttpClient([
74+
new JsonMockResponse([
75+
'bi' => [
76+
'height' => 17,
77+
],
78+
]),
79+
new JsonMockResponse([
80+
'icons' => [
81+
'heart' => [
82+
'body' => '<path d="M0 0h24v24H0z" fill="none"/>',
83+
],
84+
],
85+
]),
86+
]),
87+
);
88+
89+
$icon = $iconify->fetchIcon('bi', 'heart');
90+
91+
$this->assertIsArray($icon->getAttributes());
92+
$this->assertArrayHasKey('viewBox', $icon->getAttributes());
93+
$this->assertEquals('0 0 17 17', $icon->getAttributes()['viewBox']);
94+
}
95+
96+
public function testFetchIconThrowsWhenViewBoxCannotBeComputed(): void
97+
{
98+
$iconify = new Iconify(
99+
cache: new NullAdapter(),
100+
endpoint: 'https://example.com',
101+
http: new MockHttpClient([
102+
new JsonMockResponse([
103+
'bi' => [],
104+
]),
105+
new JsonMockResponse([
106+
'icons' => [
107+
'heart' => [
108+
'body' => '<path d="M0 0h24v24H0z" fill="none"/>',
109+
],
110+
],
111+
]),
112+
]),
113+
);
114+
115+
$this->expectException(\RuntimeException::class);
116+
$this->expectExceptionMessage('The icon "bi:heart" does not have a width or height.');
117+
118+
$iconify->fetchIcon('bi', 'heart');
119+
}
120+
}

0 commit comments

Comments
 (0)