Completed
Push — master ( 7f99bf...a7af46 )
by Vladimir
05:01 queued 02:37
created

SerializationTest   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 78
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 10
eloc 45
dl 0
loc 78
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A testUnserializesAst() 0 7 1
A testSerializeSupportsNoLocationOption() 0 6 1
B assertNodesAreEqual() 0 35 6
A testUnserializeSupportsNoLocationOption() 0 7 1
A testSerializesAst() 0 6 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQL\Tests\Language;
6
7
use GraphQL\Language\AST\Location;
8
use GraphQL\Language\AST\Node;
9
use GraphQL\Language\AST\NodeList;
10
use GraphQL\Language\Parser;
11
use GraphQL\Utils\AST;
12
use PHPUnit\Framework\TestCase;
13
use function array_keys;
14
use function count;
15
use function file_get_contents;
16
use function get_class;
17
use function get_object_vars;
18
use function implode;
19
use function json_decode;
20
21
class SerializationTest extends TestCase
22
{
23
    public function testSerializesAst() : void
24
    {
25
        $kitchenSink = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
26
        $ast         = Parser::parse($kitchenSink);
27
        $expectedAst = json_decode(file_get_contents(__DIR__ . '/kitchen-sink.ast'), true);
28
        $this->assertEquals($expectedAst, $ast->toArray(true));
29
    }
30
31
    public function testUnserializesAst() : void
32
    {
33
        $kitchenSink   = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
34
        $serializedAst = json_decode(file_get_contents(__DIR__ . '/kitchen-sink.ast'), true);
35
        $actualAst     = AST::fromArray($serializedAst);
36
        $parsedAst     = Parser::parse($kitchenSink);
37
        $this->assertNodesAreEqual($parsedAst, $actualAst);
38
    }
39
40
    /**
41
     * Compares two nodes by actually iterating over all NodeLists, properly comparing locations (ignoring tokens), etc
42
     *
43
     * @param string[] $path
44
     */
45
    private function assertNodesAreEqual(Node $expected, Node $actual, array $path = []) : void
46
    {
47
        $err = 'Mismatch at AST path: ' . implode(', ', $path);
48
49
        $this->assertInstanceOf(Node::class, $actual, $err);
50
        $this->assertEquals(get_class($expected), get_class($actual), $err);
51
52
        $expectedVars = get_object_vars($expected);
53
        $actualVars   = get_object_vars($actual);
54
        $this->assertSame(count($expectedVars), count($actualVars), $err);
55
        $this->assertEquals(array_keys($expectedVars), array_keys($actualVars), $err);
56
57
        foreach ($expectedVars as $name => $expectedValue) {
58
            $actualValue = $actualVars[$name];
59
            $tmpPath     = $path;
60
            $tmpPath[]   = $name;
61
            $err         = 'Mismatch at AST path: ' . implode(', ', $tmpPath);
62
63
            if ($expectedValue instanceof Node) {
64
                $this->assertNodesAreEqual($expectedValue, $actualValue, $tmpPath);
65
            } elseif ($expectedValue instanceof NodeList) {
66
                $this->assertEquals(count($expectedValue), count($actualValue), $err);
67
                $this->assertInstanceOf(NodeList::class, $actualValue, $err);
68
69
                foreach ($expectedValue as $index => $listNode) {
70
                    $tmpPath2   = $tmpPath;
71
                    $tmpPath2[] = $index;
72
                    $this->assertNodesAreEqual($listNode, $actualValue[$index], $tmpPath2);
73
                }
74
            } elseif ($expectedValue instanceof Location) {
75
                $this->assertInstanceOf(Location::class, $actualValue, $err);
76
                $this->assertSame($expectedValue->start, $actualValue->start, $err);
77
                $this->assertSame($expectedValue->end, $actualValue->end, $err);
78
            } else {
79
                $this->assertEquals($expectedValue, $actualValue, $err);
80
            }
81
        }
82
    }
83
84
    public function testSerializeSupportsNoLocationOption() : void
85
    {
86
        $kitchenSink = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
87
        $ast         = Parser::parse($kitchenSink, ['noLocation' => true]);
88
        $expectedAst = json_decode(file_get_contents(__DIR__ . '/kitchen-sink-noloc.ast'), true);
89
        $this->assertEquals($expectedAst, $ast->toArray(true));
90
    }
91
92
    public function testUnserializeSupportsNoLocationOption() : void
93
    {
94
        $kitchenSink   = file_get_contents(__DIR__ . '/kitchen-sink.graphql');
95
        $serializedAst = json_decode(file_get_contents(__DIR__ . '/kitchen-sink-noloc.ast'), true);
96
        $actualAst     = AST::fromArray($serializedAst);
97
        $parsedAst     = Parser::parse($kitchenSink, ['noLocation' => true]);
98
        $this->assertNodesAreEqual($parsedAst, $actualAst);
99
    }
100
}
101