From 54ae67d66305281e77d64d1f8133b91eeee8b9f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Wed, 19 Jul 2023 14:40:55 +0200 Subject: [PATCH] Restore reverse lookup determinism (#6097) In #5036, it looks like I wrongly assumed I wouldn't be able to allow having 2 classes of the same type in the type registry without also allowing having 2 objects of the same type. `array_search` can perfectly tell the difference between both situations, so let us continue forbidding that last part, it will allow us to make sure a given type matches exactly one name. --- src/Types/Exception/TypeAlreadyRegistered.php | 25 +++++++++++++++++++ src/Types/TypeRegistry.php | 10 ++++++++ .../Exception/TypeAlreadyRegisteredTest.php | 22 ++++++++++++++++ tests/Types/TypeRegistryTest.php | 16 +++++++++--- 4 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 src/Types/Exception/TypeAlreadyRegistered.php create mode 100644 tests/Types/Exception/TypeAlreadyRegisteredTest.php diff --git a/src/Types/Exception/TypeAlreadyRegistered.php b/src/Types/Exception/TypeAlreadyRegistered.php new file mode 100644 index 00000000000..93ae8123bf9 --- /dev/null +++ b/src/Types/Exception/TypeAlreadyRegistered.php @@ -0,0 +1,25 @@ +instances, true) !== false) { + throw TypeAlreadyRegistered::new($type); + } + $this->instances[$name] = $type; } @@ -85,6 +91,10 @@ public function override(string $name, Type $type): void throw TypeNotFound::new($name); } + if (! in_array(array_search($type, $this->instances, true), [$name, false], true)) { + throw TypeAlreadyRegistered::new($type); + } + $this->instances[$name] = $type; } diff --git a/tests/Types/Exception/TypeAlreadyRegisteredTest.php b/tests/Types/Exception/TypeAlreadyRegisteredTest.php new file mode 100644 index 00000000000..3ba8c858bb3 --- /dev/null +++ b/tests/Types/Exception/TypeAlreadyRegisteredTest.php @@ -0,0 +1,22 @@ +getMessage(), + ); + } +} diff --git a/tests/Types/TypeRegistryTest.php b/tests/Types/TypeRegistryTest.php index fd6bf23ce80..7a56ec55bd3 100644 --- a/tests/Types/TypeRegistryTest.php +++ b/tests/Types/TypeRegistryTest.php @@ -95,11 +95,8 @@ public function testRegisterWithAlreadyRegisteredInstance(): void $newType = new TextType(); $this->registry->register('type1', $newType); + $this->expectException(Exception::class); $this->registry->register('type2', $newType); - self::assertSame( - $this->registry->get('type1'), - $this->registry->get('type2'), - ); } public function testOverride(): void @@ -129,6 +126,17 @@ public function testOverrideWithUnknownType(): void $this->registry->override('unknown', new TextType()); } + public function testOverrideWithAlreadyRegisteredInstance(): void + { + $newType = new TextType(); + + $this->registry->register('first', $newType); + $this->registry->register('second', new StringType()); + + $this->expectException(Exception::class); + $this->registry->override('second', $newType); + } + public function testGetMap(): void { $registeredTypes = $this->registry->getMap();