diff --git a/src/Map/CHANGELOG.md b/src/Map/CHANGELOG.md
index 33431733d59..d4894408a83 100644
--- a/src/Map/CHANGELOG.md
+++ b/src/Map/CHANGELOG.md
@@ -2,8 +2,11 @@
## 2.20
-- Rename `render_map` Twig function `ux_map`
-- Deprecate `render_map` Twig function
+- Deprecate `render_map` Twig function (will be removed in 2.21). Use
+ `ux_map` or the `` Twig component instead.
+- Add `ux_map` Twig function (replaces `render_map` with a more flexible
+ interface)
+- Add `` Twig component
## 2.19
diff --git a/src/Map/composer.json b/src/Map/composer.json
index 73d39303f74..a24b4fd3ca9 100644
--- a/src/Map/composer.json
+++ b/src/Map/composer.json
@@ -39,7 +39,8 @@
"symfony/asset-mapper": "^6.4|^7.0",
"symfony/framework-bundle": "^6.4|^7.0",
"symfony/phpunit-bridge": "^6.4|^7.0",
- "symfony/twig-bundle": "^6.4|^7.0"
+ "symfony/twig-bundle": "^6.4|^7.0",
+ "symfony/ux-twig-component": "^2.18"
},
"extra": {
"thanks": {
diff --git a/src/Map/config/services.php b/src/Map/config/services.php
index 7dada5ec563..c94a9043cd9 100644
--- a/src/Map/config/services.php
+++ b/src/Map/config/services.php
@@ -15,6 +15,7 @@
use Symfony\UX\Map\Renderer\Renderer;
use Symfony\UX\Map\Renderer\Renderers;
use Symfony\UX\Map\Twig\MapExtension;
+use Symfony\UX\Map\Twig\MapRuntime;
/*
* @author Hugo Alliaume
@@ -26,7 +27,6 @@
->args([
abstract_arg('renderers configuration'),
])
- ->tag('twig.runtime')
->set('ux_map.renderer_factory.abstract', AbstractRendererFactory::class)
->abstract()
@@ -41,5 +41,11 @@
->set('ux_map.twig_extension', MapExtension::class)
->tag('twig.extension')
+
+ ->set('ux_map.twig_runtime', MapRuntime::class)
+ ->args([
+ service('ux_map.renderers'),
+ ])
+ ->tag('twig.runtime')
;
};
diff --git a/src/Map/config/twig_component.php b/src/Map/config/twig_component.php
new file mode 100644
index 00000000000..f09999e9b5c
--- /dev/null
+++ b/src/Map/config/twig_component.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\DependencyInjection\Loader\Configurator;
+
+use Symfony\UX\Map\Twig\UXMapComponent;
+use Symfony\UX\Map\Twig\UXMapComponentListener;
+use Symfony\UX\TwigComponent\Event\PreCreateForRenderEvent;
+
+return static function (ContainerConfigurator $container): void {
+ $container->services()
+ ->set('.ux_map.twig_component_listener', UXMapComponentListener::class)
+ ->args([
+ service('ux_map.twig_runtime'),
+ ])
+ ->tag('kernel.event_listener', [
+ 'event' => PreCreateForRenderEvent::class,
+ 'method' => 'onPreCreateForRender',
+ ])
+
+ ->set('.ux_map.twig_component.map', UXMapComponent::class)
+ ->tag('twig.component', ['key' => 'UX:Map'])
+ ;
+};
diff --git a/src/Map/src/InfoWindow.php b/src/Map/src/InfoWindow.php
index 4897b3c9cd2..f98fbb6995e 100644
--- a/src/Map/src/InfoWindow.php
+++ b/src/Map/src/InfoWindow.php
@@ -19,7 +19,8 @@
final readonly class InfoWindow
{
/**
- * @param array $extra Extra data, can be used by the developer to store additional information and use them later JavaScript side
+ * @param array $extra Extra data, can be used by the developer to store additional information and
+ * use them later JavaScript side
*/
public function __construct(
private ?string $headerContent = null,
@@ -31,6 +32,16 @@ public function __construct(
) {
}
+ /**
+ * @return array{
+ * headerContent: string|null,
+ * content: string|null,
+ * position: array{lat: float, lng: float}|null,
+ * opened: bool,
+ * autoClose: bool,
+ * extra: object,
+ * }
+ */
public function toArray(): array
{
return [
@@ -42,4 +53,25 @@ public function toArray(): array
'extra' => (object) $this->extra,
];
}
+
+ /**
+ * @param array{
+ * headerContent: string|null,
+ * content: string|null,
+ * position: array{lat: float, lng: float}|null,
+ * opened: bool,
+ * autoClose: bool,
+ * extra: object,
+ * } $data
+ *
+ * @internal
+ */
+ public static function fromArray(array $data): self
+ {
+ if (isset($data['position'])) {
+ $data['position'] = Point::fromArray($data['position']);
+ }
+
+ return new self(...$data);
+ }
}
diff --git a/src/Map/src/Map.php b/src/Map/src/Map.php
index 834e0d3d299..d8fdf005e56 100644
--- a/src/Map/src/Map.php
+++ b/src/Map/src/Map.php
@@ -103,4 +103,36 @@ public function toArray(): array
'markers' => array_map(static fn (Marker $marker) => $marker->toArray(), $this->markers),
];
}
+
+ /**
+ * @param array{
+ * center?: array{lat: float, lng: float},
+ * zoom?: float,
+ * markers?: list,
+ * fitBoundsToMarkers?: bool,
+ * options?: object,
+ * } $map
+ *
+ * @internal
+ */
+ public static function fromArray(array $map): self
+ {
+ $map['fitBoundsToMarkers'] = true;
+
+ if (isset($map['center'])) {
+ $map['center'] = Point::fromArray($map['center']);
+ }
+
+ if (isset($map['zoom']) || isset($map['center'])) {
+ $map['fitBoundsToMarkers'] = false;
+ }
+
+ $map['markers'] ??= [];
+ if (!\is_array($map['markers'])) {
+ throw new InvalidArgumentException('The "markers" parameter must be an array.');
+ }
+ $map['markers'] = array_map(Marker::fromArray(...), $map['markers']);
+
+ return new self(...$map);
+ }
}
diff --git a/src/Map/src/Marker.php b/src/Map/src/Marker.php
index 5c822698b74..ac0dc0e0af6 100644
--- a/src/Map/src/Marker.php
+++ b/src/Map/src/Marker.php
@@ -11,6 +11,8 @@
namespace Symfony\UX\Map;
+use Symfony\UX\Map\Exception\InvalidArgumentException;
+
/**
* Represents a marker on a map.
*
@@ -19,7 +21,8 @@
final readonly class Marker
{
/**
- * @param array $extra Extra data, can be used by the developer to store additional information and use them later JavaScript side
+ * @param array $extra Extra data, can be used by the developer to store additional information and
+ * use them later JavaScript side
*/
public function __construct(
private Point $position,
@@ -29,6 +32,14 @@ public function __construct(
) {
}
+ /**
+ * @return array{
+ * position: array{lat: float, lng: float},
+ * title: string|null,
+ * infoWindow: array|null,
+ * extra: object,
+ * }
+ */
public function toArray(): array
{
return [
@@ -38,4 +49,28 @@ public function toArray(): array
'extra' => (object) $this->extra,
];
}
+
+ /**
+ * @param array{
+ * position: array{lat: float, lng: float},
+ * title: string|null,
+ * infoWindow: array|null,
+ * extra: object,
+ * } $marker
+ *
+ * @internal
+ */
+ public static function fromArray(array $marker): self
+ {
+ if (!isset($marker['position'])) {
+ throw new InvalidArgumentException('The "position" parameter is required.');
+ }
+ $marker['position'] = Point::fromArray($marker['position']);
+
+ if (isset($marker['infoWindow'])) {
+ $marker['infoWindow'] = InfoWindow::fromArray($marker['infoWindow']);
+ }
+
+ return new self(...$marker);
+ }
}
diff --git a/src/Map/src/Point.php b/src/Map/src/Point.php
index a6d71d88f69..f34f37a2387 100644
--- a/src/Map/src/Point.php
+++ b/src/Map/src/Point.php
@@ -43,4 +43,16 @@ public function toArray(): array
'lng' => $this->longitude,
];
}
+
+ /**
+ * @param array{lat: float, lng: float}|array{0: float, 1: float} $point
+ */
+ public static function fromArray(array $point): self
+ {
+ if (isset($point['lat'], $point['lng'])) {
+ return new self($point['lat'], $point['lng']);
+ }
+
+ return new self(...$point);
+ }
}
diff --git a/src/Map/src/Twig/MapExtension.php b/src/Map/src/Twig/MapExtension.php
index 57807f54c4e..6442ff1b340 100644
--- a/src/Map/src/Twig/MapExtension.php
+++ b/src/Map/src/Twig/MapExtension.php
@@ -11,7 +11,6 @@
namespace Symfony\UX\Map\Twig;
-use Symfony\UX\Map\Renderer\Renderers;
use Twig\DeprecatedCallableInfo;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
@@ -26,13 +25,13 @@ final class MapExtension extends AbstractExtension
public function getFunctions(): array
{
return [
- new TwigFunction('render_map', [Renderers::class, 'renderMap'], [
+ new TwigFunction('render_map', [MapRuntime::class, 'renderMap'], [
'is_safe' => ['html'],
...(class_exists(DeprecatedCallableInfo::class)
? ['deprecation_info' => new DeprecatedCallableInfo('symfony/ux-map', '2.20', 'ux_map')]
: ['deprecated' => '2.20', 'deprecating_package' => 'symfony/ux-map', 'alternative' => 'ux_map']),
]),
- new TwigFunction('ux_map', [Renderers::class, 'renderMap'], ['is_safe' => ['html']]),
+ new TwigFunction('ux_map', [MapRuntime::class, 'renderMap'], ['is_safe' => ['html']]),
];
}
}
diff --git a/src/Map/src/Twig/MapRuntime.php b/src/Map/src/Twig/MapRuntime.php
new file mode 100644
index 00000000000..62e50be86da
--- /dev/null
+++ b/src/Map/src/Twig/MapRuntime.php
@@ -0,0 +1,64 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\UX\Map\Twig;
+
+use Symfony\UX\Map\Map;
+use Symfony\UX\Map\Marker;
+use Symfony\UX\Map\Point;
+use Symfony\UX\Map\Renderer\RendererInterface;
+use Twig\Extension\RuntimeExtensionInterface;
+
+/**
+ * @author Simon André
+ *
+ * @internal
+ */
+final class MapRuntime implements RuntimeExtensionInterface
+{
+ public function __construct(
+ private readonly RendererInterface $renderer,
+ ) {
+ }
+
+ /**
+ * @param array $attributes
+ * @param array $markers
+ */
+ public function renderMap(
+ ?Map $map = null,
+ array $attributes = [],
+ ?array $markers = null,
+ ?array $center = null,
+ ?float $zoom = null,
+ ): string {
+ if ($map instanceof Map) {
+ if (null !== $center || null !== $zoom || $markers) {
+ throw new \InvalidArgumentException('You cannot set "center", "markers" or "zoom" on an existing Map.');
+ }
+
+ return $this->renderer->renderMap($map, $attributes);
+ }
+
+ $map = new Map();
+ foreach ($markers ?? [] as $marker) {
+ $map->addMarker(Marker::fromArray($marker));
+ }
+ if (null !== $center) {
+ $map->center(Point::fromArray($center));
+ }
+ if (null !== $zoom) {
+ $map->zoom($zoom);
+ }
+
+ return $this->renderer->renderMap($map, $attributes);
+ }
+}
diff --git a/src/Map/src/Twig/UXMapComponent.php b/src/Map/src/Twig/UXMapComponent.php
new file mode 100644
index 00000000000..94cb6407e8f
--- /dev/null
+++ b/src/Map/src/Twig/UXMapComponent.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\UX\Map\Twig;
+
+use Symfony\UX\Map\Marker;
+use Symfony\UX\Map\Point;
+
+/**
+ * @author Simon André
+ *
+ * @internal
+ */
+final class UXMapComponent
+{
+ public ?float $zoom;
+
+ public ?Point $center;
+
+ /**
+ * @var Marker[]
+ */
+ public array $markers;
+}
diff --git a/src/Map/src/Twig/UXMapComponentListener.php b/src/Map/src/Twig/UXMapComponentListener.php
new file mode 100644
index 00000000000..3a36e5587da
--- /dev/null
+++ b/src/Map/src/Twig/UXMapComponentListener.php
@@ -0,0 +1,42 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\UX\Map\Twig;
+
+use Symfony\UX\TwigComponent\Event\PreCreateForRenderEvent;
+
+/**
+ * @author Simon André
+ *
+ * @internal
+ */
+final class UXMapComponentListener
+{
+ public function __construct(
+ private MapRuntime $mapRuntime,
+ ) {
+ }
+
+ public function onPreCreateForRender(PreCreateForRenderEvent $event): void
+ {
+ if ('ux:map' !== strtolower($event->getName())) {
+ return;
+ }
+
+ $attributes = $event->getInputProps();
+ $map = array_intersect_key($attributes, ['markers' => 0, 'center' => 1, 'zoom' => 2]);
+ $attributes = array_diff_key($attributes, $map);
+
+ $html = $this->mapRuntime->renderMap(...$map, attributes: $attributes);
+ $event->setRenderedString($html);
+ $event->stopPropagation();
+ }
+}
diff --git a/src/Map/src/UXMapBundle.php b/src/Map/src/UXMapBundle.php
index 52ecec412b5..1392926131f 100644
--- a/src/Map/src/UXMapBundle.php
+++ b/src/Map/src/UXMapBundle.php
@@ -19,6 +19,7 @@
use Symfony\UX\Map\Bridge as MapBridge;
use Symfony\UX\Map\Renderer\AbstractRendererFactory;
use Symfony\UX\Map\Renderer\NullRendererFactory;
+use Symfony\UX\TwigComponent\TwigComponentBundle;
/**
* @author Hugo Alliaume
@@ -55,6 +56,10 @@ public function loadExtension(array $config, ContainerConfigurator $container, C
$config['renderer'] = 'null://null';
}
+ if (ContainerBuilder::willBeAvailable('symfony/ux-twig-component', TwigComponentBundle::class, ['symfony/ux-map'])) {
+ $container->import('../config/twig_component.php');
+ }
+
if (str_starts_with($config['renderer'], 'null://')) {
$container->services()
->set('ux_map.renderer_factory.null', NullRendererFactory::class)
diff --git a/src/Map/tests/Kernel/TwigComponentKernel.php b/src/Map/tests/Kernel/TwigComponentKernel.php
new file mode 100644
index 00000000000..7ee33360058
--- /dev/null
+++ b/src/Map/tests/Kernel/TwigComponentKernel.php
@@ -0,0 +1,63 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\UX\Map\Tests\Kernel;
+
+use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
+use Symfony\Bundle\TwigBundle\TwigBundle;
+use Symfony\Component\Config\Loader\LoaderInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\HttpKernel\Kernel;
+use Symfony\UX\Map\UXMapBundle;
+use Symfony\UX\StimulusBundle\StimulusBundle;
+use Symfony\UX\TwigComponent\TwigComponentBundle;
+
+/**
+ * @internal
+ */
+class TwigComponentKernel extends Kernel
+{
+ use AppKernelTrait;
+
+ public function registerBundles(): iterable
+ {
+ return [
+ new FrameworkBundle(),
+ new StimulusBundle(),
+ new TwigBundle(),
+ new TwigComponentBundle(),
+ new UXMapBundle(),
+ ];
+ }
+
+ public function registerContainerConfiguration(LoaderInterface $loader)
+ {
+ $loader->load(function (ContainerBuilder $container) {
+ $container->loadFromExtension('framework', [
+ 'secret' => '$ecret',
+ 'test' => true,
+ 'http_method_override' => false,
+ ]);
+ $container->loadFromExtension('twig', [
+ 'default_path' => __DIR__.'/templates',
+ 'strict_variables' => true,
+ 'exception_controller' => null,
+ ]);
+ $container->loadFromExtension('twig_component', [
+ 'defaults' => [],
+ 'anonymous_template_directory' => 'components',
+ ]);
+ $container->loadFromExtension('ux_map', []);
+
+ $container->setAlias('test.ux_map.renderers', 'ux_map.renderers')->setPublic(true);
+ });
+ }
+}
diff --git a/src/Map/tests/MapFactoryTest.php b/src/Map/tests/MapFactoryTest.php
new file mode 100644
index 00000000000..a19e2d7996c
--- /dev/null
+++ b/src/Map/tests/MapFactoryTest.php
@@ -0,0 +1,102 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\UX\Map\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\UX\Map\Map;
+
+class MapFactoryTest extends TestCase
+{
+ public function testFromArray(): void
+ {
+ $array = self::createMapArray();
+ $map = Map::fromArray($array);
+
+ $this->assertEquals($array['center']['lat'], $map->toArray()['center']['lat']);
+ $this->assertEquals($array['center']['lng'], $map->toArray()['center']['lng']);
+
+ $this->assertEquals((float) $array['zoom'], $map->toArray()['zoom']);
+
+ $this->assertCount(1, $markers = $map->toArray()['markers']);
+ $this->assertEquals($array['markers'][0]['position']['lat'], $markers[0]['position']['lat']);
+ $this->assertEquals($array['markers'][0]['position']['lng'], $markers[0]['position']['lng']);
+ $this->assertSame($array['markers'][0]['title'], $markers[0]['title']);
+ $this->assertSame($array['markers'][0]['infoWindow']['headerContent'], $markers[0]['infoWindow']['headerContent']);
+ $this->assertSame($array['markers'][0]['infoWindow']['content'], $markers[0]['infoWindow']['content']);
+ }
+
+ public function testFromArrayWithInvalidCenter(): void
+ {
+ $array = self::createMapArray();
+ $array['center'] = 'invalid';
+
+ $this->expectException(\TypeError::class);
+ Map::fromArray($array);
+ }
+
+ public function testFromArrayWithInvalidZoom(): void
+ {
+ $array = self::createMapArray();
+ $array['zoom'] = 'invalid';
+
+ $this->expectException(\TypeError::class);
+ Map::fromArray($array);
+ }
+
+ public function testFromArrayWithInvalidMarkers(): void
+ {
+ $array = self::createMapArray();
+ $array['markers'] = 'invalid';
+
+ $this->expectException(\InvalidArgumentException::class);
+ $this->expectExceptionMessage('The "markers" parameter must be an array.');
+ Map::fromArray($array);
+ }
+
+ public function testFromArrayWithInvalidMarker(): void
+ {
+ $array = self::createMapArray();
+ $array['markers'] = [
+ [
+ 'invalid',
+ ],
+ ];
+
+ $this->expectException(\InvalidArgumentException::class);
+ $this->expectExceptionMessage('The "position" parameter is required.');
+ Map::fromArray($array);
+ }
+
+ private static function createMapArray(): array
+ {
+ return [
+ 'center' => [
+ 'lat' => 48.8566,
+ 'lng' => 2.3522,
+ ],
+ 'zoom' => 12,
+ 'markers' => [
+ [
+ 'position' => [
+ 'lat' => 48.8566,
+ 'lng' => 2.3522,
+ ],
+ 'title' => 'Paris',
+ 'infoWindow' => [
+ 'headerContent' => 'Paris',
+ 'content' => 'Paris, the city of lights',
+ ],
+ ],
+ ],
+ ];
+ }
+}
diff --git a/src/Map/tests/Twig/MapComponentTest.php b/src/Map/tests/Twig/MapComponentTest.php
new file mode 100644
index 00000000000..031fd9293a3
--- /dev/null
+++ b/src/Map/tests/Twig/MapComponentTest.php
@@ -0,0 +1,50 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\UX\Map\Tests\Twig;
+
+use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
+use Symfony\UX\Map\Map;
+use Symfony\UX\Map\Point;
+use Symfony\UX\Map\Renderer\RendererInterface;
+use Symfony\UX\Map\Tests\Kernel\TwigComponentKernel;
+
+class MapComponentTest extends KernelTestCase
+{
+ protected static function getKernelClass(): string
+ {
+ return TwigComponentKernel::class;
+ }
+
+ public function testRenderMapComponent(): void
+ {
+ $map = (new Map())
+ ->center(new Point(latitude: 5, longitude: 10))
+ ->zoom(4);
+ $attributes = ['data-foo' => 'bar'];
+
+ $renderer = self::createMock(RendererInterface::class);
+ $renderer
+ ->method('renderMap')
+ ->with($map, $attributes)
+ ->willReturn('')
+ ;
+ self::getContainer()->set('test.ux_map.renderers', $renderer);
+
+ $twig = self::getContainer()->get('twig');
+ $template = $twig->createTemplate('');
+
+ $this->assertSame(
+ '',
+ $template->render(['attributes' => $attributes]),
+ );
+ }
+}
diff --git a/src/Map/tests/Twig/MapExtensionTest.php b/src/Map/tests/Twig/MapExtensionTest.php
new file mode 100644
index 00000000000..e78e0ec3d16
--- /dev/null
+++ b/src/Map/tests/Twig/MapExtensionTest.php
@@ -0,0 +1,113 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\UX\Map\Tests\Twig;
+
+use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
+use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
+use Symfony\UX\Map\Map;
+use Symfony\UX\Map\Point;
+use Symfony\UX\Map\Renderer\RendererInterface;
+use Symfony\UX\Map\Tests\Kernel\TwigAppKernel;
+use Symfony\UX\Map\Twig\MapExtension;
+use Symfony\UX\Map\Twig\MapRuntime;
+use Twig\DeprecatedCallableInfo;
+use Twig\Environment;
+use Twig\Loader\ArrayLoader;
+use Twig\Loader\ChainLoader;
+
+class MapExtensionTest extends KernelTestCase
+{
+ use ExpectDeprecationTrait;
+
+ protected static function getKernelClass(): string
+ {
+ return TwigAppKernel::class;
+ }
+
+ public function testExtensionIsRegistered(): void
+ {
+ /** @var Environment $twig */
+ $twig = self::getContainer()->get('twig');
+
+ $this->assertTrue($twig->hasExtension(MapExtension::class));
+ $this->assertInstanceOf(MapExtension::class, $twig->getExtension(MapExtension::class));
+ }
+
+ public function testRuntimeIsRegistered(): void
+ {
+ /** @var Environment $twig */
+ $twig = self::getContainer()->get('twig');
+
+ $this->assertInstanceOf(MapRuntime::class, $twig->getRuntime(MapRuntime::class));
+ }
+
+ /**
+ * @group legacy
+ */
+ public function testRenderFunctionIsDeprecated(): void
+ {
+ $map = (new Map())
+ ->center(new Point(latitude: 5, longitude: 10))
+ ->zoom(4);
+
+ $renderer = self::createMock(RendererInterface::class);
+ $renderer
+ ->expects(self::once())
+ ->method('renderMap')
+ ->with($map, [])
+ ->willReturn('')
+ ;
+ self::getContainer()->set('test.ux_map.renderers', $renderer);
+
+ /** @var Environment $twig */
+ $twig = self::getContainer()->get('twig');
+ $twig->setLoader(new ChainLoader([
+ new ArrayLoader([
+ 'test' => '{{ render_map(map) }}',
+ ]),
+ $twig->getLoader(),
+ ]));
+
+ if (class_exists(DeprecatedCallableInfo::class)) {
+ $this->expectDeprecation('Since symfony/ux-map 2.20: Twig Function "render_map" is deprecated; use "ux_map" instead in test at line 1.');
+ } else {
+ $this->expectDeprecation('Since symfony/ux-map 2.20: Twig Function "render_map" is deprecated. Use "ux_map" instead in test at line 1.');
+ }
+ $html = $twig->render('test', ['map' => $map]);
+ $this->assertSame('', $html);
+ }
+
+ public function testMapFunctionWithArray(): void
+ {
+ $map = (new Map())
+ ->center(new Point(latitude: 5, longitude: 10))
+ ->zoom(4);
+ $attributes = ['data-foo' => 'bar'];
+
+ $renderer = self::createMock(RendererInterface::class);
+ $renderer
+ ->expects(self::once())
+ ->method('renderMap')
+ ->with($map, $attributes)
+ ->willReturn('')
+ ;
+ self::getContainer()->set('test.ux_map.renderers', $renderer);
+
+ $twig = self::getContainer()->get('twig');
+ $template = $twig->createTemplate('{{ ux_map(center: {lat: 5, lng: 10}, zoom: 4, attributes: attributes) }}');
+
+ $this->assertSame(
+ '',
+ $template->render(['attributes' => $attributes]),
+ );
+ }
+}