2017-07-21 18:29:59 +03:00
|
|
|
<?php
|
2018-09-01 21:21:08 +03:00
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace GraphQL\Tests\Language;
|
2017-07-21 18:29:59 +03:00
|
|
|
|
|
|
|
use GraphQL\Language\AST\Location;
|
|
|
|
use GraphQL\Language\AST\Node;
|
|
|
|
use GraphQL\Language\AST\NodeList;
|
|
|
|
use GraphQL\Language\Parser;
|
2017-08-20 15:50:44 +03:00
|
|
|
use GraphQL\Utils\AST;
|
2018-07-29 18:43:10 +03:00
|
|
|
use PHPUnit\Framework\TestCase;
|
2018-09-01 21:21:08 +03:00
|
|
|
use function array_keys;
|
|
|
|
use function count;
|
|
|
|
use function file_get_contents;
|
|
|
|
use function get_class;
|
|
|
|
use function get_object_vars;
|
|
|
|
use function implode;
|
|
|
|
use function json_decode;
|
2017-07-21 18:29:59 +03:00
|
|
|
|
2018-07-29 18:43:10 +03:00
|
|
|
class SerializationTest extends TestCase
|
2017-07-21 18:29:59 +03:00
|
|
|
{
|
2018-08-31 12:07:29 +03:00
|
|
|
public function testSerializesAst() : void
|
2017-07-21 18:29:59 +03:00
|
|
|
{
|
|
|
|
$kitchenSink = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
|
2018-09-01 21:21:08 +03:00
|
|
|
$ast = Parser::parse($kitchenSink);
|
2017-07-21 18:29:59 +03:00
|
|
|
$expectedAst = json_decode(file_get_contents(__DIR__ . '/kitchen-sink.ast'), true);
|
|
|
|
$this->assertEquals($expectedAst, $ast->toArray(true));
|
|
|
|
}
|
|
|
|
|
2018-08-31 12:07:29 +03:00
|
|
|
public function testUnserializesAst() : void
|
2017-07-21 18:29:59 +03:00
|
|
|
{
|
2018-09-01 21:21:08 +03:00
|
|
|
$kitchenSink = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
|
2017-07-21 18:29:59 +03:00
|
|
|
$serializedAst = json_decode(file_get_contents(__DIR__ . '/kitchen-sink.ast'), true);
|
2018-09-01 21:21:08 +03:00
|
|
|
$actualAst = AST::fromArray($serializedAst);
|
|
|
|
$parsedAst = Parser::parse($kitchenSink);
|
2018-01-13 11:45:09 +03:00
|
|
|
$this->assertNodesAreEqual($parsedAst, $actualAst);
|
|
|
|
}
|
|
|
|
|
2017-07-21 18:29:59 +03:00
|
|
|
/**
|
|
|
|
* Compares two nodes by actually iterating over all NodeLists, properly comparing locations (ignoring tokens), etc
|
|
|
|
*
|
2018-09-01 21:21:08 +03:00
|
|
|
* @param string[] $path
|
2017-07-21 18:29:59 +03:00
|
|
|
*/
|
2018-09-01 21:21:08 +03:00
|
|
|
private function assertNodesAreEqual(Node $expected, Node $actual, array $path = []) : void
|
2017-07-21 18:29:59 +03:00
|
|
|
{
|
2018-09-01 21:21:08 +03:00
|
|
|
$err = 'Mismatch at AST path: ' . implode(', ', $path);
|
2017-07-21 18:29:59 +03:00
|
|
|
|
|
|
|
$this->assertInstanceOf(Node::class, $actual, $err);
|
|
|
|
$this->assertEquals(get_class($expected), get_class($actual), $err);
|
|
|
|
|
|
|
|
$expectedVars = get_object_vars($expected);
|
2018-09-01 21:21:08 +03:00
|
|
|
$actualVars = get_object_vars($actual);
|
2017-07-21 18:29:59 +03:00
|
|
|
$this->assertSame(count($expectedVars), count($actualVars), $err);
|
|
|
|
$this->assertEquals(array_keys($expectedVars), array_keys($actualVars), $err);
|
|
|
|
|
|
|
|
foreach ($expectedVars as $name => $expectedValue) {
|
|
|
|
$actualValue = $actualVars[$name];
|
2018-09-01 21:21:08 +03:00
|
|
|
$tmpPath = $path;
|
|
|
|
$tmpPath[] = $name;
|
|
|
|
$err = 'Mismatch at AST path: ' . implode(', ', $tmpPath);
|
2017-07-21 18:29:59 +03:00
|
|
|
|
|
|
|
if ($expectedValue instanceof Node) {
|
|
|
|
$this->assertNodesAreEqual($expectedValue, $actualValue, $tmpPath);
|
2018-09-01 21:21:08 +03:00
|
|
|
} elseif ($expectedValue instanceof NodeList) {
|
2017-07-21 18:29:59 +03:00
|
|
|
$this->assertEquals(count($expectedValue), count($actualValue), $err);
|
|
|
|
$this->assertInstanceOf(NodeList::class, $actualValue, $err);
|
|
|
|
|
|
|
|
foreach ($expectedValue as $index => $listNode) {
|
2018-09-01 21:21:08 +03:00
|
|
|
$tmpPath2 = $tmpPath;
|
|
|
|
$tmpPath2[] = $index;
|
2017-07-21 18:29:59 +03:00
|
|
|
$this->assertNodesAreEqual($listNode, $actualValue[$index], $tmpPath2);
|
|
|
|
}
|
2018-09-01 21:21:08 +03:00
|
|
|
} elseif ($expectedValue instanceof Location) {
|
2017-07-21 18:29:59 +03:00
|
|
|
$this->assertInstanceOf(Location::class, $actualValue, $err);
|
|
|
|
$this->assertSame($expectedValue->start, $actualValue->start, $err);
|
|
|
|
$this->assertSame($expectedValue->end, $actualValue->end, $err);
|
|
|
|
} else {
|
|
|
|
$this->assertEquals($expectedValue, $actualValue, $err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-09-01 21:21:08 +03:00
|
|
|
|
|
|
|
public function testSerializeSupportsNoLocationOption() : void
|
|
|
|
{
|
|
|
|
$kitchenSink = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
|
|
|
|
$ast = Parser::parse($kitchenSink, ['noLocation' => true]);
|
|
|
|
$expectedAst = json_decode(file_get_contents(__DIR__ . '/kitchen-sink-noloc.ast'), true);
|
|
|
|
$this->assertEquals($expectedAst, $ast->toArray(true));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testUnserializeSupportsNoLocationOption() : void
|
|
|
|
{
|
|
|
|
$kitchenSink = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
|
|
|
|
$serializedAst = json_decode(file_get_contents(__DIR__ . '/kitchen-sink-noloc.ast'), true);
|
|
|
|
$actualAst = AST::fromArray($serializedAst);
|
|
|
|
$parsedAst = Parser::parse($kitchenSink, ['noLocation' => true]);
|
|
|
|
$this->assertNodesAreEqual($parsedAst, $actualAst);
|
|
|
|
}
|
2017-07-21 18:29:59 +03:00
|
|
|
}
|