Skip to content

Commit 10dcfce

Browse files
authored
Fail nicely on enum FQCNs (#90)
1 parent 16d01f9 commit 10dcfce

File tree

6 files changed

+55
-14
lines changed

6 files changed

+55
-14
lines changed

Diff for: phpcs.xml.dist

+9
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,13 @@
5151
<exclude-pattern>src/Doctrine/Instantiator/Exception/ExceptionInterface.php</exclude-pattern>
5252
<exclude-pattern>src/Doctrine/Instantiator/InstantiatorInterface.php</exclude-pattern>
5353
</rule>
54+
55+
<rule ref="Generic.WhiteSpace.ScopeIndent.Incorrect">
56+
<!-- see https://github.com/squizlabs/PHP_CodeSniffer/issues/3474 -->
57+
<exclude-pattern>tests/DoctrineTest/InstantiatorTestAsset/SimpleEnumAsset.php</exclude-pattern>
58+
</rule>
59+
<rule ref="Generic.WhiteSpace.ScopeIndent.IncorrectExact">
60+
<!-- see https://github.com/squizlabs/PHP_CodeSniffer/issues/3474 -->
61+
<exclude-pattern>tests/DoctrineTest/InstantiatorTestAsset/SimpleEnumAsset.php</exclude-pattern>
62+
</rule>
5463
</ruleset>

Diff for: src/Doctrine/Instantiator/Exception/InvalidArgumentException.php

+11-3
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ class InvalidArgumentException extends BaseInvalidArgumentException implements E
1717
public static function fromNonExistingClass(string $className): self
1818
{
1919
if (interface_exists($className)) {
20-
return new self(sprintf('The provided type "%s" is an interface, and can not be instantiated', $className));
20+
return new self(sprintf('The provided type "%s" is an interface, and cannot be instantiated', $className));
2121
}
2222

2323
if (trait_exists($className)) {
24-
return new self(sprintf('The provided type "%s" is a trait, and can not be instantiated', $className));
24+
return new self(sprintf('The provided type "%s" is a trait, and cannot be instantiated', $className));
2525
}
2626

2727
return new self(sprintf('The provided class "%s" does not exist', $className));
@@ -35,8 +35,16 @@ public static function fromNonExistingClass(string $className): self
3535
public static function fromAbstractClass(ReflectionClass $reflectionClass): self
3636
{
3737
return new self(sprintf(
38-
'The provided class "%s" is abstract, and can not be instantiated',
38+
'The provided class "%s" is abstract, and cannot be instantiated',
3939
$reflectionClass->getName()
4040
));
4141
}
42+
43+
public static function fromEnum(string $className): self
44+
{
45+
return new self(sprintf(
46+
'The provided class "%s" is an enum, and cannot be instantiated',
47+
$className
48+
));
49+
}
4250
}

Diff for: src/Doctrine/Instantiator/Instantiator.php

+7
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@
1212
use Serializable;
1313

1414
use function class_exists;
15+
use function enum_exists;
1516
use function is_subclass_of;
1617
use function restore_error_handler;
1718
use function set_error_handler;
1819
use function sprintf;
1920
use function strlen;
2021
use function unserialize;
2122

23+
use const PHP_VERSION_ID;
24+
2225
final class Instantiator implements InstantiatorInterface
2326
{
2427
/**
@@ -148,6 +151,10 @@ private function getReflectionClass(string $className): ReflectionClass
148151
throw InvalidArgumentException::fromNonExistingClass($className);
149152
}
150153

154+
if (PHP_VERSION_ID >= 80100 && enum_exists($className, false)) {
155+
throw InvalidArgumentException::fromEnum($className);
156+
}
157+
151158
$reflection = new ReflectionClass($className);
152159

153160
if ($reflection->isAbstract()) {

Diff for: tests/DoctrineTest/InstantiatorTest/Exception/InvalidArgumentExceptionTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function testFromNonExistingTypeWithTrait(): void
3333
$exception = InvalidArgumentException::fromNonExistingClass(SimpleTraitAsset::class);
3434

3535
self::assertSame(
36-
sprintf('The provided type "%s" is a trait, and can not be instantiated', SimpleTraitAsset::class),
36+
sprintf('The provided type "%s" is a trait, and cannot be instantiated', SimpleTraitAsset::class),
3737
$exception->getMessage()
3838
);
3939
}
@@ -44,7 +44,7 @@ public function testFromNonExistingTypeWithInterface(): void
4444

4545
self::assertSame(
4646
sprintf(
47-
'The provided type "%s" is an interface, and can not be instantiated',
47+
'The provided type "%s" is an interface, and cannot be instantiated',
4848
InstantiatorInterface::class
4949
),
5050
$exception->getMessage()
@@ -58,7 +58,7 @@ public function testFromAbstractClass(): void
5858

5959
self::assertSame(
6060
sprintf(
61-
'The provided class "%s" is abstract, and can not be instantiated',
61+
'The provided class "%s" is abstract, and cannot be instantiated',
6262
AbstractClassAsset::class
6363
),
6464
$exception->getMessage()

Diff for: tests/DoctrineTest/InstantiatorTest/InstantiatorTest.php

+16-8
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@
1414
use DoctrineTest\InstantiatorTestAsset\PharExceptionAsset;
1515
use DoctrineTest\InstantiatorTestAsset\SerializableArrayObjectAsset;
1616
use DoctrineTest\InstantiatorTestAsset\SerializableFinalInternalChildAsset;
17+
use DoctrineTest\InstantiatorTestAsset\SimpleEnumAsset;
1718
use DoctrineTest\InstantiatorTestAsset\SimpleSerializableAsset;
1819
use DoctrineTest\InstantiatorTestAsset\SimpleTraitAsset;
1920
use DoctrineTest\InstantiatorTestAsset\UnCloneableAsset;
2021
use DoctrineTest\InstantiatorTestAsset\UnserializeExceptionArrayObjectAsset;
2122
use DoctrineTest\InstantiatorTestAsset\WakeUpNoticesAsset;
2223
use DoctrineTest\InstantiatorTestAsset\XMLReaderAsset;
2324
use Exception;
25+
use Generator;
2426
use PDORow;
2527
use PharException;
2628
use PHPUnit\Framework\TestCase;
@@ -29,6 +31,8 @@
2931
use function str_replace;
3032
use function uniqid;
3133

34+
use const PHP_VERSION_ID;
35+
3236
/**
3337
* Tests for {@see \Doctrine\Instantiator\Instantiator}
3438
*
@@ -142,15 +146,19 @@ public function getInstantiableClasses(): array
142146
/**
143147
* Provides a list of instantiable classes (existing)
144148
*
145-
* @return string[][]
149+
* @psalm-return Generator<string, array{string}>
146150
*/
147-
public function getInvalidClassNames(): array
151+
public function getInvalidClassNames(): Generator
148152
{
149-
return [
150-
[self::class . str_replace('.', '', uniqid('', true))],
151-
[InstantiatorInterface::class],
152-
[AbstractClassAsset::class],
153-
[SimpleTraitAsset::class],
154-
];
153+
yield 'invalid string' => [self::class . str_replace('.', '', uniqid('', true))];
154+
yield 'interface' => [InstantiatorInterface::class];
155+
yield 'abstract class' => [AbstractClassAsset::class];
156+
yield 'trait' => [SimpleTraitAsset::class];
157+
158+
if (PHP_VERSION_ID < 80100) {
159+
return;
160+
}
161+
162+
yield 'enum' => [SimpleEnumAsset::class];
155163
}
156164
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace DoctrineTest\InstantiatorTestAsset;
4+
5+
enum SimpleEnumAsset
6+
{
7+
case Foo;
8+
case Bar;
9+
}

0 commit comments

Comments
 (0)