From 33f3cf65b26cee786398cb7e12b689f6c4ac70ed Mon Sep 17 00:00:00 2001 From: Ruud Kamphuis Date: Thu, 28 Oct 2021 12:49:33 +0200 Subject: [PATCH 1/2] Allow types to be returned using `yield` Instead of checking for `array` or `callable`, why not check for `iterable` intead. This makes it possible to use `yield` to provide types. --- src/Type/Definition/FieldDefinition.php | 5 +++-- src/Type/Definition/InputObjectType.php | 5 +++-- tests/Type/DefinitionTest.php | 26 +++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/Type/Definition/FieldDefinition.php b/src/Type/Definition/FieldDefinition.php index 0cfd5e18f..a2e824c6c 100644 --- a/src/Type/Definition/FieldDefinition.php +++ b/src/Type/Definition/FieldDefinition.php @@ -11,6 +11,7 @@ use function is_array; use function is_callable; +use function is_iterable; use function is_string; use function sprintf; @@ -86,9 +87,9 @@ public static function defineFieldMap(Type $type, $fields): array $fields = $fields(); } - if (! is_array($fields)) { + if (! is_iterable($fields)) { throw new InvariantViolation( - "{$type->name} fields must be an array or a callable which returns such an array." + "{$type->name} fields must be an iterable or a callable which returns such an iterable." ); } diff --git a/src/Type/Definition/InputObjectType.php b/src/Type/Definition/InputObjectType.php index f78420b9b..9eee526ec 100644 --- a/src/Type/Definition/InputObjectType.php +++ b/src/Type/Definition/InputObjectType.php @@ -13,6 +13,7 @@ use function count; use function is_array; use function is_callable; +use function is_iterable; use function is_string; use function sprintf; @@ -96,9 +97,9 @@ protected function initializeFields(): void $fields = $fields(); } - if (! is_array($fields)) { + if (! is_iterable($fields)) { throw new InvariantViolation( - sprintf('%s fields must be an array or a callable which returns such an array.', $this->name) + sprintf('%s fields must be an iterable or a callable which returns such an iterable.', $this->name) ); } diff --git a/tests/Type/DefinitionTest.php b/tests/Type/DefinitionTest.php index 647957671..303740577 100644 --- a/tests/Type/DefinitionTest.php +++ b/tests/Type/DefinitionTest.php @@ -5,6 +5,7 @@ namespace GraphQL\Tests\Type; use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts; +use Generator; use GraphQL\Error\InvariantViolation; use GraphQL\Tests\Type\TestClasses\MyCustomType; use GraphQL\Tests\Type\TestClasses\OtherCustom; @@ -14,9 +15,11 @@ use GraphQL\Type\Definition\InputObjectField; use GraphQL\Type\Definition\InputObjectType; use GraphQL\Type\Definition\InterfaceType; +use GraphQL\Type\Definition\IntType; use GraphQL\Type\Definition\ListOfType; use GraphQL\Type\Definition\NonNull; use GraphQL\Type\Definition\ObjectType; +use GraphQL\Type\Definition\StringType; use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\UnionType; use GraphQL\Type\Schema; @@ -2040,4 +2043,27 @@ public function testThrowsWhenLazyLoadedFieldHasInvalidArgs(): void $objType->assertValid(); } + + public function testReturningFieldsUsingYield() + { + $type = new ObjectType([ + 'name' => 'Query', + 'fields' => static function (): Generator { + yield 'url' => ['type' => Type::string()]; + yield 'width' => ['type' => Type::int()]; + }, + ]); + + $blogSchema = new Schema(['query' => $type]); + + self::assertSame($blogSchema->getQueryType(), $type); + + $field = $type->getField('url'); + self::assertSame($field->name, 'url'); + self::assertInstanceOf(StringType::class, $field->getType()); + + $field = $type->getField('width'); + self::assertSame($field->name, 'width'); + self::assertInstanceOf(IntType::class, $field->getType()); + } } From 59d5d66fdfe3e2bf0d674eb59a03b69aa6fb7e41 Mon Sep 17 00:00:00 2001 From: Benedikt Franke Date: Thu, 28 Oct 2021 16:52:31 +0200 Subject: [PATCH 2/2] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff98273f8..4d863d458 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ You can find and compare releases at the [GitHub release page](https://github.co - Expose structured enumeration of directive locations - Add `AST::concatAST()` utility - Allow lazy input object fields +- Allow field definitions to be defined as any `iterable`, not just `array` ### Optimized