Skip to content

Commit a40f1e1

Browse files
authored
Allow field definitions to be defined as any iterable, not just array (#993)
1 parent 1621018 commit a40f1e1

File tree

4 files changed

+33
-4
lines changed

4 files changed

+33
-4
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ You can find and compare releases at the [GitHub release page](https://github.co
3333
- Expose structured enumeration of directive locations
3434
- Add `AST::concatAST()` utility
3535
- Allow lazy input object fields
36+
- Allow field definitions to be defined as any `iterable`, not just `array`
3637

3738
### Optimized
3839

src/Type/Definition/FieldDefinition.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
use function is_array;
1313
use function is_callable;
14+
use function is_iterable;
1415
use function is_string;
1516
use function sprintf;
1617

@@ -86,9 +87,9 @@ public static function defineFieldMap(Type $type, $fields): array
8687
$fields = $fields();
8788
}
8889

89-
if (! is_array($fields)) {
90+
if (! is_iterable($fields)) {
9091
throw new InvariantViolation(
91-
"{$type->name} fields must be an array or a callable which returns such an array."
92+
"{$type->name} fields must be an iterable or a callable which returns such an iterable."
9293
);
9394
}
9495

src/Type/Definition/InputObjectType.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use function count;
1414
use function is_array;
1515
use function is_callable;
16+
use function is_iterable;
1617
use function is_string;
1718
use function sprintf;
1819

@@ -96,9 +97,9 @@ protected function initializeFields(): void
9697
$fields = $fields();
9798
}
9899

99-
if (! is_array($fields)) {
100+
if (! is_iterable($fields)) {
100101
throw new InvariantViolation(
101-
sprintf('%s fields must be an array or a callable which returns such an array.', $this->name)
102+
sprintf('%s fields must be an iterable or a callable which returns such an iterable.', $this->name)
102103
);
103104
}
104105

tests/Type/DefinitionTest.php

+26
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace GraphQL\Tests\Type;
66

77
use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
8+
use Generator;
89
use GraphQL\Error\InvariantViolation;
910
use GraphQL\Tests\Type\TestClasses\MyCustomType;
1011
use GraphQL\Tests\Type\TestClasses\OtherCustom;
@@ -14,9 +15,11 @@
1415
use GraphQL\Type\Definition\InputObjectField;
1516
use GraphQL\Type\Definition\InputObjectType;
1617
use GraphQL\Type\Definition\InterfaceType;
18+
use GraphQL\Type\Definition\IntType;
1719
use GraphQL\Type\Definition\ListOfType;
1820
use GraphQL\Type\Definition\NonNull;
1921
use GraphQL\Type\Definition\ObjectType;
22+
use GraphQL\Type\Definition\StringType;
2023
use GraphQL\Type\Definition\Type;
2124
use GraphQL\Type\Definition\UnionType;
2225
use GraphQL\Type\Schema;
@@ -2040,4 +2043,27 @@ public function testThrowsWhenLazyLoadedFieldHasInvalidArgs(): void
20402043

20412044
$objType->assertValid();
20422045
}
2046+
2047+
public function testReturningFieldsUsingYield()
2048+
{
2049+
$type = new ObjectType([
2050+
'name' => 'Query',
2051+
'fields' => static function (): Generator {
2052+
yield 'url' => ['type' => Type::string()];
2053+
yield 'width' => ['type' => Type::int()];
2054+
},
2055+
]);
2056+
2057+
$blogSchema = new Schema(['query' => $type]);
2058+
2059+
self::assertSame($blogSchema->getQueryType(), $type);
2060+
2061+
$field = $type->getField('url');
2062+
self::assertSame($field->name, 'url');
2063+
self::assertInstanceOf(StringType::class, $field->getType());
2064+
2065+
$field = $type->getField('width');
2066+
self::assertSame($field->name, 'width');
2067+
self::assertInstanceOf(IntType::class, $field->getType());
2068+
}
20432069
}

0 commit comments

Comments
 (0)