mirror of
https://github.com/retailcrm/graphql-php.git
synced 2025-04-11 05:01:00 +00:00
Compare commits
9 commits
Author | SHA1 | Date | |
---|---|---|---|
|
167c3e7354 | ||
|
a8cd87acff | ||
|
e9cd1daedb | ||
|
2540436a2c | ||
|
d53f7f041e | ||
|
91daa23c5f | ||
|
57c77623ee | ||
|
78e2862e3b | ||
|
63b04df6ef |
8 changed files with 158 additions and 86 deletions
|
@ -1,4 +1,12 @@
|
|||
# Changelog
|
||||
#### v0.12.2
|
||||
- SchemaPrinter: Use multi-line block for trailing quote (#294)
|
||||
|
||||
#### v0.12.1
|
||||
- Fixed bug in validation rule OverlappingFieldsCanBeMerged (#292)
|
||||
- Added one more breaking change note in UPGRADE.md (#291)
|
||||
- Spec compliance: remove `data` entry from response on top-level error (#281)
|
||||
|
||||
## v0.12.0
|
||||
- RFC: Block String (multi-line strings via triple-quote """string""")
|
||||
- GraphQL Schema SDL: Descriptions as strings (including multi-line)
|
||||
|
|
27
UPGRADE.md
27
UPGRADE.md
|
@ -10,6 +10,33 @@ Exception inside `parseLiteral()`, `parseValue()` and `serialize()`.
|
|||
|
||||
Returning null from any of these methods will now be treated as valid result.
|
||||
|
||||
### Breaking: Custom scalar types parseLiteral() declaration changed
|
||||
A new parameter was added to `parseLiteral()`, which also needs to be added to any custom scalar type extending from `ScalarType`
|
||||
|
||||
Before:
|
||||
```php
|
||||
class MyType extends ScalarType {
|
||||
|
||||
...
|
||||
|
||||
public function parseLiteral($valueNode) {
|
||||
//custom implementation
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
After:
|
||||
```php
|
||||
class MyType extends ScalarType {
|
||||
|
||||
...
|
||||
|
||||
public function parseLiteral($valueNode, array $variables = null) {
|
||||
//custom implementation
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Breaking: Descriptions in comments are not used as descriptions by default anymore
|
||||
Descriptions now need to be inside Strings or BlockStrings in order to be picked up as
|
||||
description. If you want to keep the old behaviour you can supply the option `commentDescriptions`
|
||||
|
|
|
@ -106,7 +106,7 @@ echo json_encode($output);
|
|||
|
||||
Our example is finished. Try it by running:
|
||||
```sh
|
||||
php -S localhost:8000 graphql.php
|
||||
php -S localhost:8080 graphql.php
|
||||
curl http://localhost:8080 -d '{"query": "query { echo(message: \"Hello World\") }" }'
|
||||
```
|
||||
|
||||
|
|
|
@ -311,7 +311,10 @@ class Executor
|
|||
return null;
|
||||
})
|
||||
->then(function ($data) {
|
||||
return new ExecutionResult((array) $data, $this->exeContext->errors);
|
||||
if ($data !== null){
|
||||
$data = (array) $data;
|
||||
}
|
||||
return new ExecutionResult($data, $this->exeContext->errors);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -275,15 +275,35 @@ class SchemaPrinter
|
|||
return self::printDescriptionWithComments($lines, $indentation, $firstInBlock);
|
||||
}
|
||||
|
||||
$description = ($indentation && !$firstInBlock) ? "\n" : '';
|
||||
if (count($lines) === 1 && mb_strlen($lines[0]) < 70) {
|
||||
$description .= $indentation . '"""' . self::escapeQuote($lines[0]) . "\"\"\"\n";
|
||||
return $description;
|
||||
$description = ($indentation && !$firstInBlock)
|
||||
? "\n" . $indentation . '"""'
|
||||
: $indentation . '"""';
|
||||
|
||||
// In some circumstances, a single line can be used for the description.
|
||||
if (
|
||||
count($lines) === 1 &&
|
||||
mb_strlen($lines[0]) < 70 &&
|
||||
substr($lines[0], -1) !== '"'
|
||||
) {
|
||||
return $description . self::escapeQuote($lines[0]) . "\"\"\"\n";
|
||||
}
|
||||
|
||||
$description .= $indentation . "\"\"\"\n";
|
||||
foreach ($lines as $line) {
|
||||
$description .= $indentation . self::escapeQuote($line) . "\n";
|
||||
// Format a multi-line block quote to account for leading space.
|
||||
$hasLeadingSpace = isset($lines[0]) &&
|
||||
(
|
||||
substr($lines[0], 0, 1) === ' ' ||
|
||||
substr($lines[0], 0, 1) === '\t'
|
||||
);
|
||||
if (!$hasLeadingSpace) {
|
||||
$description .= "\n";
|
||||
}
|
||||
|
||||
$lineLength = count($lines);
|
||||
for ($i = 0; $i < $lineLength; $i++) {
|
||||
if ($i !== 0 || !$hasLeadingSpace) {
|
||||
$description .= $indentation;
|
||||
}
|
||||
$description .= self::escapeQuote($lines[$i]) . "\n";
|
||||
}
|
||||
$description .= $indentation . "\"\"\"\n";
|
||||
|
||||
|
|
|
@ -426,7 +426,7 @@ class OverlappingFieldsCanBeMerged extends AbstractValidationRule
|
|||
$fragmentNames1Length = count($fragmentNames1);
|
||||
if ($fragmentNames1Length !== 0) {
|
||||
$comparedFragments = [];
|
||||
for ($i = 0; $i < $fragmentNames2Length; $i++) {
|
||||
for ($i = 0; $i < $fragmentNames1Length; $i++) {
|
||||
$this->collectConflictsBetweenFieldsAndFragment(
|
||||
$context,
|
||||
$conflicts,
|
||||
|
|
|
@ -732,7 +732,6 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||
';
|
||||
|
||||
$expected = [
|
||||
'data' => null,
|
||||
'errors' => [
|
||||
FormattedError::create($this->nonNullSyncError->getMessage(), [new SourceLocation(2, 17)])
|
||||
]
|
||||
|
@ -750,7 +749,6 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||
$ast = Parser::parse($doc);
|
||||
|
||||
$expected = [
|
||||
'data' => null,
|
||||
'errors' => [
|
||||
FormattedError::create($this->nonNullPromiseError->getMessage(), [new SourceLocation(2, 17)]),
|
||||
]
|
||||
|
@ -789,7 +787,6 @@ class NonNullTest extends \PHPUnit_Framework_TestCase
|
|||
$ast = Parser::parse($doc);
|
||||
|
||||
$expected = [
|
||||
'data' => null,
|
||||
'errors' => [
|
||||
[
|
||||
'debugMessage' => 'Cannot return null for non-nullable field DataType.nonNullPromise.',
|
||||
|
|
|
@ -11,6 +11,7 @@ use GraphQL\Type\Definition\ObjectType;
|
|||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\EnumType;
|
||||
use GraphQL\Type\Definition\UnionType;
|
||||
use GraphQL\Utils\BuildSchema;
|
||||
use GraphQL\Utils\SchemaPrinter;
|
||||
|
||||
class SchemaPrinterTest extends \PHPUnit_Framework_TestCase
|
||||
|
@ -24,13 +25,13 @@ class SchemaPrinterTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
private function printSingleFieldSchema($fieldConfig)
|
||||
{
|
||||
$root = new ObjectType([
|
||||
'name' => 'Root',
|
||||
$query = new ObjectType([
|
||||
'name' => 'Query',
|
||||
'fields' => [
|
||||
'singleField' => $fieldConfig
|
||||
]
|
||||
]);
|
||||
return $this->printForTest(new Schema(['query' => $root]));
|
||||
return $this->printForTest(new Schema(['query' => $query]));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,11 +43,7 @@ class SchemaPrinterTest extends \PHPUnit_Framework_TestCase
|
|||
'type' => Type::string()
|
||||
]);
|
||||
$this->assertEquals('
|
||||
schema {
|
||||
query: Root
|
||||
}
|
||||
|
||||
type Root {
|
||||
type Query {
|
||||
singleField: String
|
||||
}
|
||||
', $output);
|
||||
|
@ -61,11 +58,7 @@ type Root {
|
|||
'type' => Type::listOf(Type::string())
|
||||
]);
|
||||
$this->assertEquals('
|
||||
schema {
|
||||
query: Root
|
||||
}
|
||||
|
||||
type Root {
|
||||
type Query {
|
||||
singleField: [String]
|
||||
}
|
||||
', $output);
|
||||
|
@ -80,11 +73,7 @@ type Root {
|
|||
'type' => Type::nonNull(Type::string())
|
||||
]);
|
||||
$this->assertEquals('
|
||||
schema {
|
||||
query: Root
|
||||
}
|
||||
|
||||
type Root {
|
||||
type Query {
|
||||
singleField: String!
|
||||
}
|
||||
', $output);
|
||||
|
@ -99,11 +88,7 @@ type Root {
|
|||
'type' => Type::nonNull(Type::listOf(Type::string()))
|
||||
]);
|
||||
$this->assertEquals('
|
||||
schema {
|
||||
query: Root
|
||||
}
|
||||
|
||||
type Root {
|
||||
type Query {
|
||||
singleField: [String]!
|
||||
}
|
||||
', $output);
|
||||
|
@ -118,11 +103,7 @@ type Root {
|
|||
'type' => Type::listOf(Type::nonNull(Type::string()))
|
||||
]);
|
||||
$this->assertEquals('
|
||||
schema {
|
||||
query: Root
|
||||
}
|
||||
|
||||
type Root {
|
||||
type Query {
|
||||
singleField: [String!]
|
||||
}
|
||||
', $output);
|
||||
|
@ -137,11 +118,7 @@ type Root {
|
|||
'type' => Type::nonNull(Type::listOf(Type::nonNull(Type::string())))
|
||||
]);
|
||||
$this->assertEquals('
|
||||
schema {
|
||||
query: Root
|
||||
}
|
||||
|
||||
type Root {
|
||||
type Query {
|
||||
singleField: [String!]!
|
||||
}
|
||||
', $output);
|
||||
|
@ -189,11 +166,7 @@ type Root {
|
|||
'args' => ['argOne' => ['type' => Type::int()]]
|
||||
]);
|
||||
$this->assertEquals('
|
||||
schema {
|
||||
query: Root
|
||||
}
|
||||
|
||||
type Root {
|
||||
type Query {
|
||||
singleField(argOne: Int): String
|
||||
}
|
||||
', $output);
|
||||
|
@ -209,11 +182,7 @@ type Root {
|
|||
'args' => ['argOne' => ['type' => Type::int(), 'defaultValue' => 2]]
|
||||
]);
|
||||
$this->assertEquals('
|
||||
schema {
|
||||
query: Root
|
||||
}
|
||||
|
||||
type Root {
|
||||
type Query {
|
||||
singleField(argOne: Int = 2): String
|
||||
}
|
||||
', $output);
|
||||
|
@ -229,11 +198,7 @@ type Root {
|
|||
'args' => ['argOne' => ['type' => Type::int(), 'defaultValue' => null]]
|
||||
]);
|
||||
$this->assertEquals('
|
||||
schema {
|
||||
query: Root
|
||||
}
|
||||
|
||||
type Root {
|
||||
type Query {
|
||||
singleField(argOne: Int = null): String
|
||||
}
|
||||
', $output);
|
||||
|
@ -249,11 +214,7 @@ type Root {
|
|||
'args' => ['argOne' => ['type' => Type::nonNull(Type::int())]]
|
||||
]);
|
||||
$this->assertEquals('
|
||||
schema {
|
||||
query: Root
|
||||
}
|
||||
|
||||
type Root {
|
||||
type Query {
|
||||
singleField(argOne: Int!): String
|
||||
}
|
||||
', $output);
|
||||
|
@ -272,11 +233,7 @@ type Root {
|
|||
]
|
||||
]);
|
||||
$this->assertEquals('
|
||||
schema {
|
||||
query: Root
|
||||
}
|
||||
|
||||
type Root {
|
||||
type Query {
|
||||
singleField(argOne: Int, argTwo: String): String
|
||||
}
|
||||
', $output);
|
||||
|
@ -296,11 +253,7 @@ type Root {
|
|||
]
|
||||
]);
|
||||
$this->assertEquals('
|
||||
schema {
|
||||
query: Root
|
||||
}
|
||||
|
||||
type Root {
|
||||
type Query {
|
||||
singleField(argOne: Int = 1, argTwo: String, argThree: Boolean): String
|
||||
}
|
||||
', $output);
|
||||
|
@ -320,11 +273,7 @@ type Root {
|
|||
]
|
||||
]);
|
||||
$this->assertEquals('
|
||||
schema {
|
||||
query: Root
|
||||
}
|
||||
|
||||
type Root {
|
||||
type Query {
|
||||
singleField(argOne: Int, argTwo: String = "foo", argThree: Boolean): String
|
||||
}
|
||||
', $output);
|
||||
|
@ -344,11 +293,7 @@ type Root {
|
|||
]
|
||||
]);
|
||||
$this->assertEquals('
|
||||
schema {
|
||||
query: Root
|
||||
}
|
||||
|
||||
type Root {
|
||||
type Query {
|
||||
singleField(argOne: Int, argTwo: String, argThree: Boolean = false): String
|
||||
}
|
||||
', $output);
|
||||
|
@ -661,6 +606,78 @@ type Query {
|
|||
', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* @it One-line prints a short description
|
||||
*/
|
||||
public function testOneLinePrintsAShortDescription()
|
||||
{
|
||||
$description = 'This field is awesome';
|
||||
$output = $this->printSingleFieldSchema([
|
||||
"type" => Type::string(),
|
||||
"description" => $description
|
||||
]);
|
||||
|
||||
$this->assertEquals('
|
||||
type Query {
|
||||
"""This field is awesome"""
|
||||
singleField: String
|
||||
}
|
||||
', $output);
|
||||
|
||||
$recreatedRoot = BuildSchema::build($output)->getTypeMap()['Query'];
|
||||
$recreatedField = $recreatedRoot->getFields()['singleField'];
|
||||
$this->assertEquals($description, $recreatedField->description);
|
||||
}
|
||||
|
||||
/**
|
||||
* @it Does not one-line print a description that ends with a quote
|
||||
*/
|
||||
public function testDoesNotOneLinePrintADescriptionThatEndsWithAQuote()
|
||||
{
|
||||
$description = 'This field is "awesome"';
|
||||
$output = $this->printSingleFieldSchema([
|
||||
"type" => Type::string(),
|
||||
"description" => $description
|
||||
]);
|
||||
|
||||
$this->assertEquals('
|
||||
type Query {
|
||||
"""
|
||||
This field is "awesome"
|
||||
"""
|
||||
singleField: String
|
||||
}
|
||||
', $output);
|
||||
|
||||
$recreatedRoot = BuildSchema::build($output)->getTypeMap()['Query'];
|
||||
$recreatedField = $recreatedRoot->getFields()['singleField'];
|
||||
$this->assertEquals($description, $recreatedField->description);
|
||||
}
|
||||
|
||||
/**
|
||||
* @it Preserves leading spaces when printing a description
|
||||
*/
|
||||
public function testPReservesLeadingSpacesWhenPrintingADescription()
|
||||
{
|
||||
$description = ' This field is "awesome"';
|
||||
$output = $this->printSingleFieldSchema([
|
||||
"type" => Type::string(),
|
||||
"description" => $description
|
||||
]);
|
||||
|
||||
$this->assertEquals('
|
||||
type Query {
|
||||
""" This field is "awesome"
|
||||
"""
|
||||
singleField: String
|
||||
}
|
||||
', $output);
|
||||
|
||||
$recreatedRoot = BuildSchema::build($output)->getTypeMap()['Query'];
|
||||
$recreatedField = $recreatedRoot->getFields()['singleField'];
|
||||
$this->assertEquals($description, $recreatedField->description);
|
||||
}
|
||||
|
||||
/**
|
||||
* @it Print Introspection Schema
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue