Skip to content

Commit 0f35b73

Browse files
authored
fix: add missing support for oneOf directive in schema printer (#1727)
1 parent 85aabf7 commit 0f35b73

File tree

4 files changed

+81
-1
lines changed

4 files changed

+81
-1
lines changed

src/Utils/ASTDefinitionBuilder.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,16 +536,36 @@ private function makeScalarDef(ScalarTypeDefinitionNode $def): CustomScalarType
536536
]);
537537
}
538538

539-
/** @throws InvariantViolation */
539+
/**
540+
* @throws \Exception
541+
* @throws \ReflectionException
542+
* @throws InvariantViolation
543+
*/
540544
private function makeInputObjectDef(InputObjectTypeDefinitionNode $def): InputObjectType
541545
{
542546
$name = $def->name->value;
543547
/** @var array<InputObjectTypeExtensionNode> $extensionASTNodes (proven by schema validation) */
544548
$extensionASTNodes = $this->typeExtensionsMap[$name] ?? [];
545549

550+
$oneOfDirective = Directive::oneOfDirective();
551+
552+
// Check for @oneOf directive in the definition node
553+
$isOneOf = Values::getDirectiveValues($oneOfDirective, $def) !== null;
554+
555+
// Check for @oneOf directive in extension nodes
556+
if (! $isOneOf) {
557+
foreach ($extensionASTNodes as $extensionNode) {
558+
if (Values::getDirectiveValues($oneOfDirective, $extensionNode) !== null) {
559+
$isOneOf = true;
560+
break;
561+
}
562+
}
563+
}
564+
546565
return new InputObjectType([
547566
'name' => $name,
548567
'description' => $def->description->value ?? null,
568+
'isOneOf' => $isOneOf,
549569
'fields' => fn (): array => $this->makeInputFields([$def, ...$extensionASTNodes]),
550570
'astNode' => $def,
551571
'extensionASTNodes' => $extensionASTNodes,

src/Utils/SchemaPrinter.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,7 @@ protected static function printInputObject(InputObjectType $type, array $options
563563

564564
return static::printDescription($options, $type)
565565
. "input {$type->name}"
566+
. ($type->isOneOf() ? ' @oneOf' : '')
566567
. static::printBlock($fields);
567568
}
568569

tests/Utils/BuildSchemaTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,39 @@ public function testCorrectlyExtendInputObjectType(): void
10421042
self::assertSame($inputSDL, $this->printAllASTNodes($someInput));
10431043
}
10441044

1045+
/** @see it('Correctly extend input object type with @oneOf directive') */
1046+
public function testCorrectlyExtendInputObjectTypeWithOneOfDirective(): void
1047+
{
1048+
$inputSDL = <<<'GRAPHQL'
1049+
input SomeInput {
1050+
first: String
1051+
}
1052+
1053+
extend input SomeInput @oneOf {
1054+
second: Int
1055+
}
1056+
1057+
GRAPHQL;
1058+
1059+
$schema = BuildSchema::build($inputSDL);
1060+
1061+
$someInput = $schema->getType('SomeInput');
1062+
assert($someInput instanceof InputObjectType);
1063+
1064+
// Verify that the @oneOf directive from the extension is properly applied
1065+
self::assertTrue($someInput->isOneOf());
1066+
1067+
$expectedSomeInputSDL = <<<'GRAPHQL'
1068+
input SomeInput @oneOf {
1069+
first: String
1070+
second: Int
1071+
}
1072+
GRAPHQL;
1073+
1074+
self::assertSame($expectedSomeInputSDL, SchemaPrinter::printType($someInput));
1075+
self::assertSame($inputSDL, $this->printAllASTNodes($someInput));
1076+
}
1077+
10451078
/** @see it('Correctly assign AST nodes') */
10461079
public function testCorrectlyAssignASTNodes(): void
10471080
{

tests/Utils/SchemaPrinterTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,32 @@ public function testInputType(): void
764764
);
765765
}
766766

767+
/** @see it('Print Input Type with @oneOf directive') */
768+
public function testInputTypeWithOneOfDirective(): void
769+
{
770+
$inputType = new InputObjectType([
771+
'name' => 'InputType',
772+
'isOneOf' => true,
773+
'fields' => [
774+
'int' => Type::int(),
775+
],
776+
]);
777+
778+
$schema = new Schema([
779+
'types' => [$inputType],
780+
]);
781+
782+
self::assertPrintedSchemaEquals(
783+
<<<'GRAPHQL'
784+
input InputType @oneOf {
785+
int: Int
786+
}
787+
788+
GRAPHQL,
789+
$schema
790+
);
791+
}
792+
767793
/** @see it('Custom Scalar') */
768794
public function testCustomScalar(): void
769795
{

0 commit comments

Comments
 (0)