diff --git a/src/Type/Definition/PhpEnumType.php b/src/Type/Definition/PhpEnumType.php index 431187c35..32ee9de0f 100644 --- a/src/Type/Definition/PhpEnumType.php +++ b/src/Type/Definition/PhpEnumType.php @@ -10,6 +10,14 @@ /** * @phpstan-import-type PartialEnumValueConfig from EnumType + * + * @phpstan-type PhpEnumTypeConfig array{ + * name?: string|null, + * description?: string|null, + * enumClass: class-string<\UnitEnum>, + * astNode?: EnumTypeDefinitionNode|null, + * extensionASTNodes?: array|null + * } */ class PhpEnumType extends EnumType { @@ -20,23 +28,15 @@ class PhpEnumType extends EnumType protected string $enumClass; /** - * @param class-string<\UnitEnum> $enumClass The fully qualified class name of a native PHP enum - * @param string|null $name The name the enum will have in the schema, defaults to the basename of the given class - * @param string|null $description The description the enum will have in the schema, defaults to PHPDoc of the given class - * @param array|null $extensionASTNodes + * @phpstan-param PhpEnumTypeConfig $config * * @throws \Exception * @throws \ReflectionException */ - public function __construct( - string $enumClass, - ?string $name = null, - ?string $description = null, - ?EnumTypeDefinitionNode $astNode = null, - ?array $extensionASTNodes = null - ) { - $this->enumClass = $enumClass; - $reflection = new \ReflectionEnum($enumClass); + public function __construct(array $config) + { + $this->enumClass = $config['enumClass']; + $reflection = new \ReflectionEnum($this->enumClass); /** * @var array $enumDefinitions @@ -51,11 +51,12 @@ public function __construct( } parent::__construct([ - 'name' => $name ?? $this->baseName($enumClass), + 'name' => $config['name'] ?? $this->baseName($this->enumClass), 'values' => $enumDefinitions, - 'description' => $description ?? $this->extractDescription($reflection), - 'astNode' => $astNode, - 'extensionASTNodes' => $extensionASTNodes, + 'description' => $config['description'] ?? $this->extractDescription($reflection), + 'enumClass' => $this->enumClass, + 'astNode' => $config['astNode'] ?? null, + 'extensionASTNodes' => $config['extensionASTNodes'] ?? null, ]); } diff --git a/tests/Type/EnumTypeTest.php b/tests/Type/EnumTypeTest.php index 307f9bceb..637e82256 100644 --- a/tests/Type/EnumTypeTest.php +++ b/tests/Type/EnumTypeTest.php @@ -8,7 +8,7 @@ use GraphQL\Language\Parser; use GraphQL\Language\SourceLocation; use GraphQL\Tests\Type\PhpEnumType\BackedPhpEnum; -use GraphQL\Tests\Type\PhpEnumType\PhpEnum; +use GraphQL\Tests\Type\PhpEnumType\MyCustomPhpEnum; use GraphQL\Tests\Type\TestClasses\OtherEnumType; use GraphQL\Type\Definition\EnumType; use GraphQL\Type\Definition\EnumValueDefinition; @@ -717,7 +717,7 @@ enum PhpEnum { $this->schema = BuildSchema::build($documentNode); $resolvers = [ - 'phpEnum' => fn (): PhpEnum => PhpEnum::B, + 'phpEnum' => fn (): MyCustomPhpEnum => MyCustomPhpEnum::B, ]; self::assertSame( diff --git a/tests/Type/PhpEnumType/PhpEnum.php b/tests/Type/PhpEnumType/MyCustomPhpEnum.php similarity index 93% rename from tests/Type/PhpEnumType/PhpEnum.php rename to tests/Type/PhpEnumType/MyCustomPhpEnum.php index dd3f4b4e6..99eb178f9 100644 --- a/tests/Type/PhpEnumType/PhpEnum.php +++ b/tests/Type/PhpEnumType/MyCustomPhpEnum.php @@ -6,7 +6,7 @@ use GraphQL\Type\Definition\Description; #[Description(description: 'foo')] -enum PhpEnum +enum MyCustomPhpEnum { #[Description(description: 'bar')] case A; diff --git a/tests/Type/PhpEnumTypeTest.php b/tests/Type/PhpEnumTypeTest.php index e89f6b062..9371f8581 100644 --- a/tests/Type/PhpEnumTypeTest.php +++ b/tests/Type/PhpEnumTypeTest.php @@ -12,7 +12,7 @@ use GraphQL\Tests\Type\PhpEnumType\MultipleDeprecationsPhpEnum; use GraphQL\Tests\Type\PhpEnumType\MultipleDescriptionsCasePhpEnum; use GraphQL\Tests\Type\PhpEnumType\MultipleDescriptionsPhpEnum; -use GraphQL\Tests\Type\PhpEnumType\PhpEnum; +use GraphQL\Tests\Type\PhpEnumType\MyCustomPhpEnum; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\PhpEnumType; use GraphQL\Type\Definition\ResolveInfo; @@ -33,10 +33,12 @@ protected function setUp(): void public function testConstructEnumTypeFromPhpEnum(): void { - $enumType = new PhpEnumType(PhpEnum::class); + $enumType = new PhpEnumType([ + 'enumClass' => MyCustomPhpEnum::class, + ]); self::assertSame(<<<'GRAPHQL' "foo" -enum PhpEnum { +enum MyCustomPhpEnum { "bar" A B @deprecated @@ -56,13 +58,13 @@ enum MyEnum @directiveA $extensionASTNode2 = Parser::enumTypeExtension(<<<'GRAPHQL' extend enum MyEnum @directiveC GRAPHQL); - $enumType = new PhpEnumType( - PhpEnum::class, - 'MyEnum', - 'My description.', - $astNode, - [$extensionASTNode1, $extensionASTNode2] - ); + $enumType = new PhpEnumType([ + 'enumClass' => MyCustomPhpEnum::class, + 'name' => 'MyEnum', + 'description' => 'My description.', + 'astNode' => $astNode, + 'extensionASTNodes' => [$extensionASTNode1, $extensionASTNode2], + ]); self::assertSame(<<<'GRAPHQL' "My description." enum MyEnum { @@ -78,7 +80,7 @@ enum MyEnum { public function testConstructEnumTypeFromIntPhpEnum(): void { - $enumType = new PhpEnumType(IntPhpEnum::class); + $enumType = new PhpEnumType(['enumClass' => IntPhpEnum::class]); self::assertSame(<<<'GRAPHQL' enum IntPhpEnum { A @@ -88,7 +90,10 @@ enum IntPhpEnum { public function testConstructEnumTypeFromPhpEnumWithCustomName(): void { - $enumType = new PhpEnumType(PhpEnum::class, 'CustomNamedPhpEnum'); + $enumType = new PhpEnumType([ + 'enumClass' => MyCustomPhpEnum::class, + 'name' => 'CustomNamedPhpEnum', + ]); self::assertSame(<<<'GRAPHQL' "foo" enum CustomNamedPhpEnum { @@ -102,7 +107,7 @@ enum CustomNamedPhpEnum { public function testConstructEnumTypeFromPhpEnumWithDocBlockDescriptions(): void { - $enumType = new PhpEnumType(DocBlockPhpEnum::class); + $enumType = new PhpEnumType(['enumClass' => DocBlockPhpEnum::class]); self::assertSame(<<<'GRAPHQL' "foo." enum DocBlockPhpEnum { @@ -121,24 +126,32 @@ enum DocBlockPhpEnum { public function testMultipleDescriptionsDisallowed(): void { self::expectExceptionObject(new \Exception(PhpEnumType::MULTIPLE_DESCRIPTIONS_DISALLOWED)); - new PhpEnumType(MultipleDescriptionsPhpEnum::class); + new PhpEnumType([ + 'enumClass' => MultipleDescriptionsPhpEnum::class, + ]); } public function testMultipleDescriptionsDisallowedOnCase(): void { self::expectExceptionObject(new \Exception(PhpEnumType::MULTIPLE_DESCRIPTIONS_DISALLOWED)); - new PhpEnumType(MultipleDescriptionsCasePhpEnum::class); + new PhpEnumType([ + 'enumClass' => MultipleDescriptionsCasePhpEnum::class, + ]); } public function testMultipleDeprecationsDisallowed(): void { self::expectExceptionObject(new \Exception(PhpEnumType::MULTIPLE_DEPRECATIONS_DISALLOWED)); - new PhpEnumType(MultipleDeprecationsPhpEnum::class); + new PhpEnumType([ + 'enumClass' => MultipleDeprecationsPhpEnum::class, + ]); } public function testExecutesWithEnumTypeFromPhpEnum(): void { - $enumType = new PhpEnumType(PhpEnum::class); + $enumType = new PhpEnumType([ + 'enumClass' => MyCustomPhpEnum::class, + ]); $schema = new Schema([ 'query' => new ObjectType([ 'name' => 'Query', @@ -150,9 +163,9 @@ public function testExecutesWithEnumTypeFromPhpEnum(): void 'type' => Type::nonNull($enumType), ], ], - 'resolve' => static function ($_, array $args): PhpEnum { + 'resolve' => static function ($_, array $args): MyCustomPhpEnum { $bar = $args['bar']; - self::assertSame(PhpEnum::A, $bar); + \PHPUnit\Framework\Assert::assertSame(MyCustomPhpEnum::A, $bar); return $bar; }, @@ -170,7 +183,9 @@ public function testExecutesWithEnumTypeFromPhpEnum(): void public function testSerializesBackedEnumsByValue(): void { - $enumType = new PhpEnumType(IntPhpEnum::class); + $enumType = new PhpEnumType([ + 'enumClass' => IntPhpEnum::class, + ]); $schema = new Schema([ 'query' => new ObjectType([ 'name' => 'Query', @@ -192,7 +207,7 @@ public function testSerializesBackedEnumsByValue(): void public function testAcceptsEnumFromVariableValues(): void { - $enumType = new PhpEnumType(PhpEnum::class); + $enumType = new PhpEnumType(['enumClass' => MyCustomPhpEnum::class]); $schema = null; $schema = new Schema([ @@ -206,16 +221,16 @@ public function testAcceptsEnumFromVariableValues(): void 'type' => Type::nonNull($enumType), ], ], - 'resolve' => static function (bool $executeAgain, array $args, $context, ResolveInfo $resolveInfo) use (&$schema): PhpEnum { + 'resolve' => static function (bool $executeAgain, array $args, $context, ResolveInfo $resolveInfo) use (&$schema): MyCustomPhpEnum { $bar = $args['bar']; - self::assertSame(PhpEnum::A, $bar); + \PHPUnit\Framework\Assert::assertSame(MyCustomPhpEnum::A, $bar); self::assertInstanceOf(Schema::class, $schema); if ($executeAgain) { $executionResult = GraphQL::executeQuery( $schema, - 'query ($bar: PhpEnum!) { foo(bar: $bar) }', + 'query ($bar: MyCustomPhpEnum!) { foo(bar: $bar) }', false, null, $resolveInfo->variableValues @@ -236,7 +251,7 @@ public function testAcceptsEnumFromVariableValues(): void $executionResult = GraphQL::executeQuery( $schema, - 'query ($bar: PhpEnum!) { foo(bar: $bar) }', + 'query ($bar: MyCustomPhpEnum!) { foo(bar: $bar) }', true, null, ['bar' => 'A'] @@ -250,7 +265,7 @@ public function testAcceptsEnumFromVariableValues(): void public function testFailsToSerializeNonEnum(): void { - $enumType = new PhpEnumType(PhpEnum::class); + $enumType = new PhpEnumType(['enumClass' => MyCustomPhpEnum::class]); $schema = new Schema([ 'query' => new ObjectType([ 'name' => 'Query', @@ -265,13 +280,13 @@ public function testFailsToSerializeNonEnum(): void $result = GraphQL::executeQuery($schema, '{ foo }'); - self::expectExceptionObject(new SerializationError('Cannot serialize value as enum: "A", expected instance of GraphQL\\Tests\\Type\\PhpEnumType\\PhpEnum.')); + self::expectExceptionObject(new SerializationError('Cannot serialize value as enum: "A", expected instance of GraphQL\\Tests\\Type\\PhpEnumType\\MyCustomPhpEnum.')); $result->toArray(DebugFlag::RETHROW_INTERNAL_EXCEPTIONS); } public function testFailsToSerializeNonEnumValue(): void { - $enumType = new PhpEnumType(IntPhpEnum::class); + $enumType = new PhpEnumType(['enumClass' => IntPhpEnum::class]); $schema = new Schema([ 'query' => new ObjectType([ 'name' => 'Query',