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

Updates to allow printing of Schema Directives #638

Closed
wants to merge 8 commits into from
Closed
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
+ Cannot return null for non-nullable field "parentType.fieldName".
```
- Simplified Deferred implementation
- Allow SchemaPrinter to print Schema Directives

#### v0.13.5
- Fix coroutine executor when using with promise (#486)
Expand Down
50 changes: 48 additions & 2 deletions src/Utils/SchemaPrinter.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
namespace GraphQL\Utils;

use GraphQL\Error\Error;
use GraphQL\Language\AST\InterfaceTypeDefinitionNode;
use GraphQL\Language\AST\NodeList;
use GraphQL\Language\AST\ObjectTypeDefinitionNode;
use GraphQL\Language\Printer;
use GraphQL\Type\Definition\Directive;
use GraphQL\Type\Definition\EnumType;
Expand All @@ -24,6 +27,7 @@
use function count;
use function explode;
use function implode;
use function iterator_to_array;
use function ksort;
use function mb_strlen;
use function preg_match_all;
Expand Down Expand Up @@ -366,7 +370,7 @@ static function ($i) {
: '';

return self::printDescription($options, $type) .
sprintf("type %s%s {\n%s\n}", $type->name, $implementedInterfaces, self::printFields($options, $type));
sprintf("type %s%s%s {\n%s\n}", $type->name, $implementedInterfaces, self::printSchemaDirectives($type), self::printFields($options, $type));
}

/**
Expand Down Expand Up @@ -410,7 +414,7 @@ private static function printDeprecated($fieldOrEnumVal) : string
private static function printInterface(InterfaceType $type, array $options) : string
{
return self::printDescription($options, $type) .
sprintf("interface %s {\n%s\n}", $type->name, self::printFields($options, $type));
sprintf("interface %s%s {\n%s\n}", $type->name, self::printSchemaDirectives($type), self::printFields($options, $type));
}

/**
Expand Down Expand Up @@ -487,4 +491,46 @@ public static function printIntrospectionSchema(Schema $schema, array $options =
$options
);
}

public static function printSchemaDirectives(Type $type) : string
{
if ($type->astNode === null) {
return '';
}

if ($type->astNode instanceof ObjectTypeDefinitionNode) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First two codnitions can be merged

$directives = $type->astNode->directives;
} elseif ($type->astNode instanceof InterfaceTypeDefinitionNode) {
$directives = $type->astNode->directives;
} else {
return '';
}

if ($directives instanceof NodeList) {
$count = $directives->count();
$directives = iterator_to_array($directives->getIterator());
} else {
$count = count($directives);
}

return $count > 0 ? (' ' . implode(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd invert the condition so else is not hidden at the bottom: ' ' . $count === 0 ? '' : implode(

' ',
array_map(
static function ($directive) : string {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to add some type hint for $directive?

$directiveString = '@' . $directive->name->value;
if ($directive->arguments->count() > 0) {
$directiveString .= '(';
foreach ($directive->arguments as $argument) {
$directiveString .= $argument->name->value . ': ';
$directiveString .= Printer::doPrint($argument->value);
}
$directiveString .= ')';
}

return $directiveString;
},
$directives
)
)) : '';
}
}
199 changes: 199 additions & 0 deletions tests/Utils/SchemaPrinterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1237,4 +1237,203 @@ enum __TypeKind {
EOT;
self::assertEquals($introspectionSchema, $output);
}

public function testPrintSchemaDirectiveNoArgs()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public function testPrintSchemaDirectiveNoArgs()
public function testPrintSchemaDirectiveNoArgs() : void

{
$exceptedSdl = '
directive @sd on OBJECT

type Bar @sd {
foo: String
}

type Query {
foo: Bar
}
';

$schema = BuildSchema::build($exceptedSdl);
$actual = $this->printForTest($schema);

self::assertEquals($exceptedSdl, $actual);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self::assertEquals($exceptedSdl, $actual);
self::assertSame($exceptedSdl, $actual);

}

public function testPrintSchemaDirectiveWithStringArgs()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public function testPrintSchemaDirectiveWithStringArgs()
public function testPrintSchemaDirectiveWithStringArgs() : void

{
$exceptedSdl = '
directive @sd(field: String!) on OBJECT

type Bar @sd(field: "String") {
foo: String
}

type Query {
foo: Bar
}
';

$schema = BuildSchema::build($exceptedSdl);
$actual = $this->printForTest($schema);

self::assertEquals($exceptedSdl, $actual);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self::assertEquals($exceptedSdl, $actual);
self::assertSame($exceptedSdl, $actual);

}

public function testPrintSchemaDirectiveWithNumberArgs()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public function testPrintSchemaDirectiveWithNumberArgs()
public function testPrintSchemaDirectiveWithNumberArgs() : void

{
$exceptedSdl = '
directive @sd(field: Int!) on OBJECT

type Bar @sd(field: 1) {
foo: String
}

type Query {
foo: Bar
}
';

$schema = BuildSchema::build($exceptedSdl);
$actual = $this->printForTest($schema);

self::assertEquals($exceptedSdl, $actual);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self::assertEquals($exceptedSdl, $actual);
self::assertSame($exceptedSdl, $actual);

}

public function testPrintSchemaDirectiveWithArrayArgs()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public function testPrintSchemaDirectiveWithArrayArgs()
public function testPrintSchemaDirectiveWithArrayArgs() : void

{
$exceptedSdl = '
directive @sd(field: [Int!]) on OBJECT

type Bar @sd(field: [1, 2, 3, 4]) {
foo: String
}

type Query {
foo: Bar
}
';

$schema = BuildSchema::build($exceptedSdl);
$actual = $this->printForTest($schema);

self::assertEquals($exceptedSdl, $actual);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self::assertEquals($exceptedSdl, $actual);
self::assertSame($exceptedSdl, $actual);

}

public function testPrintSchemaDirectiveWithTypeArgs()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public function testPrintSchemaDirectiveWithTypeArgs()
public function testPrintSchemaDirectiveWithTypeArgs() : void

{
$exceptedSdl = '
directive @sd(field: Foo) on OBJECT

type Bar @sd(field: {bar: "test"}) {
foo: String
}

type Foo {
bar: String
}

type Query {
foo: Bar
}
';

$schema = BuildSchema::build($exceptedSdl);
$actual = $this->printForTest($schema);

self::assertEquals($exceptedSdl, $actual);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self::assertEquals($exceptedSdl, $actual);
self::assertSame($exceptedSdl, $actual);

}

public function testPrintSchemaDirectiveOptionalArgs()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public function testPrintSchemaDirectiveOptionalArgs()
public function testPrintSchemaDirectiveOptionalArgs() : void

{
$exceptedSdl = '
directive @sd(field: String) on OBJECT

type Bar @sd(field: "Testing") {
foo: String
}

type Foo @sd {
bar: String
}

type Query {
foo: Bar
bar: Foo
}
';

$schema = BuildSchema::build($exceptedSdl);
$actual = $this->printForTest($schema);

self::assertEquals($exceptedSdl, $actual);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self::assertEquals($exceptedSdl, $actual);
self::assertSame($exceptedSdl, $actual);

}

public function testPrintMultipleSchemaDirectives()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public function testPrintMultipleSchemaDirectives()
public function testPrintMultipleSchemaDirectives() : void

{
$exceptedSdl = '
directive @sd(field: [Int!]) on OBJECT

directive @sdb on OBJECT

type Bar @sd(field: [1, 2, 3, 4]) @sdb {
foo: String
}

type Query {
foo: Bar
}
';

$schema = BuildSchema::build($exceptedSdl);
$actual = $this->printForTest($schema);

self::assertEquals($exceptedSdl, $actual);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self::assertEquals($exceptedSdl, $actual);
self::assertSame($exceptedSdl, $actual);

}

public function testPrintSchemaDirectiveOnClassWithInterface()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public function testPrintSchemaDirectiveOnClassWithInterface()
public function testPrintSchemaDirectiveOnClassWithInterface() : void

{
$exceptedSdl = '
directive @sd on OBJECT

type Bar implements Foo @sd {
foo: String
}

interface Foo {
bar: String
}

type Query {
foo: Bar
}
';

$schema = BuildSchema::build($exceptedSdl);
$actual = $this->printForTest($schema);

self::assertEquals($exceptedSdl, $actual);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self::assertEquals($exceptedSdl, $actual);
self::assertSame($exceptedSdl, $actual);

}

public function testPrintSchemaDirectiveOnInterface()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public function testPrintSchemaDirectiveOnInterface()
public function testPrintSchemaDirectiveOnInterface() : void

{
$exceptedSdl = '
directive @sd on INTERFACE

type Bar implements Foo {
foo: String
}

interface Foo @sd {
bar: String
}

type Query {
foo: Bar
}
';

$schema = BuildSchema::build($exceptedSdl);
$actual = $this->printForTest($schema);

self::assertEquals($exceptedSdl, $actual);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self::assertEquals($exceptedSdl, $actual);
self::assertSame($exceptedSdl, $actual);

}
}