From 8d58c606b0617aaa250575da1616dc1dbf921c04 Mon Sep 17 00:00:00 2001 From: bpteam Date: Mon, 20 Nov 2023 00:10:22 +0200 Subject: [PATCH 1/2] fix auto gernerate resolver for not existed field in type model --- src/Generator/Code/Foundation/CodeGenerator.php | 4 ++-- tests/Generator/TypeRegistry/resources/AltCoinType.php | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 tests/Generator/TypeRegistry/resources/AltCoinType.php diff --git a/src/Generator/Code/Foundation/CodeGenerator.php b/src/Generator/Code/Foundation/CodeGenerator.php index d385968..afc36a9 100644 --- a/src/Generator/Code/Foundation/CodeGenerator.php +++ b/src/Generator/Code/Foundation/CodeGenerator.php @@ -21,9 +21,9 @@ use GraphQL\Type\Definition\CustomScalarType; use GraphQL\Type\Definition\Directive; use GraphQL\Type\Definition\FieldDefinition; +use GraphQL\Type\Definition\InterfaceType; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Type; -use GraphQL\Type\Definition\TypeWithFields; use GraphQL\Type\Definition\UnionType; use GraphQL\Type\Schema; use PhpParser\NodeTraverser; @@ -102,7 +102,7 @@ public function generateType(Type $type, Schema $schema): iterable foreach ($collector->getResults() as $fieldName => $field) { $existedFields[] = $fieldName; } - foreach ($type instanceof TypeWithFields ? $type->getFields() : [] as $field) { + foreach (($type instanceof ObjectType || $type instanceof InterfaceType) ? $type->getFields() : [] as $field) { if (!in_array($field->name, $existedFields)) { yield from $this->generateFieldResolver($type, $field, $schema); } diff --git a/tests/Generator/TypeRegistry/resources/AltCoinType.php b/tests/Generator/TypeRegistry/resources/AltCoinType.php new file mode 100644 index 0000000..c5b9aab --- /dev/null +++ b/tests/Generator/TypeRegistry/resources/AltCoinType.php @@ -0,0 +1,9 @@ + Date: Mon, 20 Nov 2023 13:56:33 +0200 Subject: [PATCH 2/2] fix auto gernerator of resolver for not existed field in type model --- .run/localhost.run.xml | 5 + tests/Builder/CodeGeneratorBuilderTest.php | 539 ++++++++++++++++++ .../Psr4}/resources/AltCoinType.php | 2 +- 3 files changed, 545 insertions(+), 1 deletion(-) create mode 100644 .run/localhost.run.xml create mode 100644 tests/Builder/CodeGeneratorBuilderTest.php rename tests/Generator/{TypeRegistry => Model/Psr4}/resources/AltCoinType.php (56%) diff --git a/.run/localhost.run.xml b/.run/localhost.run.xml new file mode 100644 index 0000000..95e8d01 --- /dev/null +++ b/.run/localhost.run.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/tests/Builder/CodeGeneratorBuilderTest.php b/tests/Builder/CodeGeneratorBuilderTest.php new file mode 100644 index 0000000..1b7e929 --- /dev/null +++ b/tests/Builder/CodeGeneratorBuilderTest.php @@ -0,0 +1,539 @@ +build(); + foreach ($codeGenerator->generateAllTypes($schema) as $code){} + + $builder = new TypeRegistryGeneratorBuilder($mainConfig); + $generator = $builder->build(); + + $this->assertEquals($expected, $generator->generate($schema)); + FileSystemHelper::rmdir($dir); + spl_autoload_unregister($myAutoloader); + } + + + public function dataProviderGeneratePhpCode(): iterable + { + yield [ + CodeGeneratorConfig::V7_4, + BuildSchema::build(Parser::parse(<< + */ + private array $types = []; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + public function getType(string $name): Type + { + return $this->types[$name] ??= $this->{$name}(); + } + + + public function NamedCurrency() + { + return new ObjectType([ + 'name' => 'NamedCurrency', + 'description' => NULL, + 'fields' => fn() => ['id' => new FieldDefinition([ + 'name' => 'id', + 'description' => NULL, + 'deprecationReason' => NULL, + // No resolver. Default used + 'type' => function() { return Type::nonNull(function() { return Type::id(); }); }, + 'args' => [], + ]),'name' => new FieldDefinition([ + 'name' => 'name', + 'description' => NULL, + 'deprecationReason' => NULL, + 'resolve' => function($rootValue, $args, $context, $info) { + return $this->container->get('Axtiva\FlexibleGraphql\Example\GraphQL\Directive\SumDirective')( + function($rootValue, $args, $context, $info) { + return $this->container->get('Axtiva\FlexibleGraphql\Example\GraphQL\Directive\UppercaseDirective')( + (function ($rootValue, $args, $context, $info) { + $args = new \Axtiva\FlexibleGraphql\Example\GraphQL\ResolverArgs\NamedCurrency\NameResolverArgs($args); + return $this->container->get('Axtiva\FlexibleGraphql\Example\GraphQL\Resolver\NamedCurrency\NameResolver')($rootValue, $args, $context, $info); +}), + array ( +), + $rootValue, $args, $context, $info + ); + }, + new \Axtiva\FlexibleGraphql\Example\GraphQL\DirectiveArgs\SumDirectiveArgs(array ( + 'x' => '2', +)), + $rootValue, $args, $context, $info + ); + }, + 'type' => function() { return Type::string(); }, + 'args' => ['x' => [ + 'name' => 'x', + 'type' => function() { return Type::int(); }, + 'description' => 'Description for argument', + 'defaultValue' => 5, + ],'testInput' => [ + 'name' => 'testInput', + 'type' => function() { return Type::nonNull(function() { return $this->getType('DemoInput'); }); }, + ],'demo' => [ + 'name' => 'demo', + 'type' => function() { return $this->getType('DemoEnum'); }, + ],'date' => [ + 'name' => 'date', + 'type' => function() { return $this->getType('DateTime'); }, + ],'hello' => [ + 'name' => 'hello', + 'type' => function() { return $this->getType('HelloScalar'); }, + ]], + ])], + ]); + } + + + + public function AltCoin() + { + return new ObjectType([ + 'name' => 'AltCoin', + 'description' => NULL, + 'fields' => fn() => ['id' => new FieldDefinition([ + 'name' => 'id', + 'description' => NULL, + 'deprecationReason' => NULL, + // No resolver. Default used + 'type' => function() { return Type::nonNull(function() { return Type::id(); }); }, + 'args' => [], + ]),'name' => new FieldDefinition([ + 'name' => 'name', + 'description' => NULL, + 'deprecationReason' => NULL, + 'resolve' => (function ($rootValue, $args, $context, $info) { + + return $this->container->get('Axtiva\FlexibleGraphql\Example\GraphQL\Resolver\AltCoin\NameResolver')($rootValue, $args, $context, $info); +}), + 'type' => function() { return Type::string(); }, + 'args' => [], + ])], + ]); + } + + + + public function DemoEnum() + { + return new EnumType([ + 'name' => 'DemoEnum', + 'description' => NULL, + 'values' => ['A' => [ + 'name' => 'A', + 'value' => 'A', + 'description' => NULL, + 'deprecationReason' => NULL, + ], +'B' => [ + 'name' => 'B', + 'value' => 'B', + 'description' => NULL, + 'deprecationReason' => NULL, + ]], + ]); + } + + + + public function DemoInput() + { + return new InputObjectType([ + 'name' => 'DemoInput', + 'description' => NULL, + 'fields' => fn() => ['field' => [ + 'name' => 'field', + 'type' => Type::int(), + ]], + ]); + } + + + + public function DateTime() + { + return new CustomScalarType([ + 'name' => 'DateTime', + 'description' => NULL, + 'serialize' => function($value) {return ($this->container->get('Axtiva\FlexibleGraphql\Example\GraphQL\Scalar\DateTimeScalar'))->serialize($value);}, + 'parseValue' => function($value) {return ($this->container->get('Axtiva\FlexibleGraphql\Example\GraphQL\Scalar\DateTimeScalar'))->parseValue($value);}, + 'parseLiteral' => function($value, $variables) {return ($this->container->get('Axtiva\FlexibleGraphql\Example\GraphQL\Scalar\DateTimeScalar'))->parseLiteral($value, $variables);}, + ]); + } + + + + public function HelloScalar() + { + return new CustomScalarType([ + 'name' => 'HelloScalar', + 'description' => NULL, + + ]); + } + + + public function Query() + { + return new ObjectType(['name' => 'Query']); + } + + public function Mutation() + { + return new ObjectType(['name' => 'Mutation']); + } + + + public function directive_sum() + { + static $directive = null; + if ($directive === null) { + $directive = new Directive([ + 'name' => 'sum', + 'description' => NULL, + 'isRepeatable' => false, + 'locations' => ['FIELD','FIELD_DEFINITION'], + 'args' => [ + [ + 'name' => 'x', + 'type' => function() { return Type::int(); }, + ] + ], + ]); + } + + return $directive; + } + + + + public function directive_uppercase() + { + static $directive = null; + if ($directive === null) { + $directive = new Directive([ + 'name' => 'uppercase', + 'description' => NULL, + 'isRepeatable' => false, + 'locations' => ['FIELD','FIELD_DEFINITION'], + 'args' => [ + + ], + ]); + } + + return $directive; + } + + + + public function getDirectives() + { + return [$this->directive_sum(),$this->directive_uppercase()]; + } + + +} + +PHP + ,]; +return; + yield [ + CodeGeneratorConfig::V7_4, + BuildSchema::build(Parser::parse(<< + */ + private array $types = []; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + public function getType(string $name): Type + { + return $this->types[$name] ??= $this->{$name}(); + } + + + public function Query() + { + return new ObjectType([ + 'name' => 'Query', + 'description' => NULL, + 'fields' => fn() => ['sum' => new FieldDefinition([ + 'name' => 'sum', + 'description' => NULL, + 'deprecationReason' => NULL, + 'resolve' => (function ($rootValue, $args, $context, $info) { + + return $this->container->get('Axtiva\FlexibleGraphql\Example\GraphQL\Resolver\Query\SumResolver')($rootValue, $args, $context, $info); +}), + 'type' => function() { return Type::int(); }, + 'args' => [], + ])], + ]); + } + + + public function Mutation() + { + return new ObjectType(['name' => 'Mutation']); + } + + + public function getDirectives() + { + return []; + } + + +} + +PHP + ,]; + + yield [ + CodeGeneratorConfig::V7_4, + BuildSchema::build(Parser::parse(<< + */ + private array $types = []; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + public function getType(string $name): Type + { + return $this->types[$name] ??= $this->{$name}(); + } + + + public function Mutation() + { + return new ObjectType([ + 'name' => 'Mutation', + 'description' => NULL, + 'fields' => fn() => ['sum' => new FieldDefinition([ + 'name' => 'sum', + 'description' => NULL, + 'deprecationReason' => NULL, + 'resolve' => (function ($rootValue, $args, $context, $info) { + + return $this->container->get('Axtiva\FlexibleGraphql\Example\GraphQL\Resolver\Mutation\SumResolver')($rootValue, $args, $context, $info); +}), + 'type' => function() { return Type::int(); }, + 'args' => [], + ])], + ]); + } + + + public function Query() + { + return new ObjectType(['name' => 'Query']); + } + + + public function getDirectives() + { + return []; + } + + +} + +PHP + ,]; + } +} \ No newline at end of file diff --git a/tests/Generator/TypeRegistry/resources/AltCoinType.php b/tests/Generator/Model/Psr4/resources/AltCoinType.php similarity index 56% rename from tests/Generator/TypeRegistry/resources/AltCoinType.php rename to tests/Generator/Model/Psr4/resources/AltCoinType.php index c5b9aab..8b2d9a8 100644 --- a/tests/Generator/TypeRegistry/resources/AltCoinType.php +++ b/tests/Generator/Model/Psr4/resources/AltCoinType.php @@ -1,7 +1,7 @@