Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for arguments description #623

Merged
merged 2 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/InputTypeUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use ReflectionNamedType;
use RuntimeException;
use TheCodingMachine\GraphQLite\Parameters\ExpandsInputTypeParameters;
use TheCodingMachine\GraphQLite\Parameters\InputTypeParameter;
use TheCodingMachine\GraphQLite\Parameters\InputTypeParameterInterface;
use TheCodingMachine\GraphQLite\Parameters\ParameterInterface;

Expand Down Expand Up @@ -144,6 +145,9 @@ public static function getInputTypeArgs(array $args): array
if ($parameter->hasDefaultValue()) {
$desc['defaultValue'] = $parameter->getDefaultValue();
}
if ($parameter->getDescription()) {
$desc['description'] = $parameter->getDescription();
}

return $desc;
}, $inputTypeArgs);
Expand Down
18 changes: 17 additions & 1 deletion src/Mappers/Parameters/TypeHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ public function mapParameter(ReflectionParameter $parameter, DocBlock $docBlock,
}
}

$description = $this->getParameterDescriptionFromDocBlock($docBlock, $parameter);

$hasDefaultValue = false;
$defaultValue = null;
if ($parameter->allowsNull()) {
Expand All @@ -201,13 +203,27 @@ public function mapParameter(ReflectionParameter $parameter, DocBlock $docBlock,
return new InputTypeParameter(
name: $parameter->getName(),
type: $type,
description: null,
description: $description,
hasDefaultValue: $hasDefaultValue,
defaultValue: $defaultValue,
argumentResolver: $this->argumentResolver,
);
}

private function getParameterDescriptionFromDocBlock(DocBlock $docBlock, ReflectionParameter $parameter): string|null
{
/** @var DocBlock\Tags\Param[] $paramTags */
$paramTags = $docBlock->getTagsByName('param');

foreach ($paramTags as $paramTag) {
if ($paramTag->getVariableName() === $parameter->getName()) {
return $paramTag->getDescription()?->render();
}
}

return null;
}

/**
* Map class property to a GraphQL type.
*
Expand Down
4 changes: 4 additions & 0 deletions src/Parameters/InputTypeParameterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@ public function getType(): InputType&Type;
public function hasDefaultValue(): bool;

public function getDefaultValue(): mixed;

public function getName(): string;

public function getDescription(): string;
}
15 changes: 15 additions & 0 deletions tests/FieldsBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
use TheCodingMachine\GraphQLite\Fixtures\TestControllerWithReturnDateTime;
use TheCodingMachine\GraphQLite\Fixtures\TestControllerWithUnionInputParam;
use TheCodingMachine\GraphQLite\Fixtures\TestEnum;
use TheCodingMachine\GraphQLite\Fixtures\TestTypeWithDescriptions;
use TheCodingMachine\GraphQLite\Fixtures\TestTypeWithInvalidPrefetchMethod;
use TheCodingMachine\GraphQLite\Fixtures\TestControllerWithInvalidReturnType;
use TheCodingMachine\GraphQLite\Fixtures\TestControllerWithIterableReturnType;
Expand Down Expand Up @@ -708,6 +709,20 @@ public function testPrefetchMethod(): void
$this->assertSame('arg4', $testField->args[3]->name);
}

public function testOutputTypeArgumentDescription(): void
{
$controller = new TestTypeWithDescriptions();

$queryProvider = $this->buildFieldsBuilder();

$fields = $queryProvider->getFields($controller);
$testField = $fields['customField'];

$this->assertCount(1, $testField->args);
$this->assertSame('arg1', $testField->args[0]->name);
$this->assertSame('Test argument description', $testField->args[0]->description);
}

public function testSecurityBadQuery(): void
{
$controller = new TestControllerWithBadSecurity();
Expand Down
24 changes: 24 additions & 0 deletions tests/Fixtures/TestTypeWithDescriptions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php


namespace TheCodingMachine\GraphQLite\Fixtures;

use TheCodingMachine\GraphQLite\Annotations\Field;
use TheCodingMachine\GraphQLite\Annotations\Type;

/**
* @Type(class=TestObject::class)
*/
class TestTypeWithDescriptions
{
/**
* @Field()
* @param TestObject $test
* @param string $arg1 Test argument description
* @return string
*/
public function customField(TestObject $test, string $arg1): string
{
return $test->getTest().$arg1;
}
}
25 changes: 25 additions & 0 deletions tests/Mappers/Parameters/TypeMapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use TheCodingMachine\GraphQLite\Fixtures80\UnionOutputType;
use TheCodingMachine\GraphQLite\Mappers\CannotMapTypeException;
use TheCodingMachine\GraphQLite\Parameters\DefaultValueParameter;
use TheCodingMachine\GraphQLite\Parameters\InputTypeParameter;
use TheCodingMachine\GraphQLite\Reflection\CachedDocBlockFactory;

class TypeMapperTest extends AbstractQueryProviderTest
Expand Down Expand Up @@ -98,6 +99,22 @@ public function testHideParameter(): void
$this->assertSame(24, $param->resolve(null, [], null, $resolveInfo));
}

public function testParameterWithDescription(): void
{
$typeMapper = new TypeHandler($this->getArgumentResolver(), $this->getRootTypeMapper(), $this->getTypeResolver());

$cachedDocBlockFactory = new CachedDocBlockFactory(new Psr16Cache(new ArrayAdapter()));

$refMethod = new ReflectionMethod($this, 'withParamDescription');
$docBlockObj = $cachedDocBlockFactory->getDocBlock($refMethod);
$refParameter = $refMethod->getParameters()[0];

$parameter = $typeMapper->mapParameter($refParameter, $docBlockObj, null, $this->getAnnotationReader()->getParameterAnnotations($refParameter));
$this->assertInstanceOf(InputTypeParameter::class, $parameter);
assert($parameter instanceof InputTypeParameter);
$this->assertEquals('Foo parameter', $parameter->getDescription());
}

public function testHideParameterException(): void
{
$typeMapper = new TypeHandler($this->getArgumentResolver(), $this->getRootTypeMapper(), $this->getTypeResolver());
Expand All @@ -123,6 +140,14 @@ private function dummy()

}

/**
oojacoboo marked this conversation as resolved.
Show resolved Hide resolved
* @param int $foo Foo parameter
*/
private function withParamDescription(int $foo)
{

}

/**
* @HideParameter(for="$foo")
*/
Expand Down
13 changes: 13 additions & 0 deletions tests/QueryFieldTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
use GraphQL\Type\Definition\Type;
use PHPUnit\Framework\TestCase;
use TheCodingMachine\GraphQLite\Fixtures\TestObject;
use TheCodingMachine\GraphQLite\Middlewares\ServiceResolver;
use TheCodingMachine\GraphQLite\Middlewares\SourceMethodResolver;
use TheCodingMachine\GraphQLite\Parameters\InputTypeParameter;
use TheCodingMachine\GraphQLite\Parameters\ParameterInterface;
use TheCodingMachine\GraphQLite\Types\ArgumentResolver;

class QueryFieldTest extends TestCase
{
Expand All @@ -31,4 +34,14 @@ public function resolve(?object $source, array $args, mixed $context, ResolveInf
$this->expectException(Error::class);
$resolve(new TestObject('foo'), ['arg' => 12], null, $this->createMock(ResolveInfo::class));
}

public function testParametersDescription(): void
{
$sourceResolver = new ServiceResolver(static fn () => null);
$queryField = new QueryField('foo', Type::string(), [
'arg' => new InputTypeParameter('arg', Type::string(), 'Foo argument', false, null, new ArgumentResolver()),
], $sourceResolver, $sourceResolver, null, null, []);

$this->assertEquals('Foo argument', $queryField->args[0]->description);
}
}
Loading