cloneDeep(); $this->assertEquals($astCopy, $ast); Printer::doPrint($ast); $this->assertEquals($astCopy, $ast); } /** * @it prints minimal ast */ public function testPrintsMinimalAst() { $ast = new FieldNode(['name' => new NameNode(['value' => 'foo'])]); $this->assertEquals('foo', Printer::doPrint($ast)); } /** * @it produces helpful error messages */ public function testProducesHelpfulErrorMessages() { $badAst1 = new \ArrayObject(['random' => 'Data']); $this->expectException(\Throwable::class); $this->expectExceptionMessage('Invalid AST Node: {"random":"Data"}'); Printer::doPrint($badAst1); } /** * @it correctly prints non-query operations without name */ public function testCorrectlyPrintsOpsWithoutName() { $queryAstShorthanded = Parser::parse('query { id, name }'); $expected = '{ id name } '; $this->assertEquals($expected, Printer::doPrint($queryAstShorthanded)); $mutationAst = Parser::parse('mutation { id, name }'); $expected = 'mutation { id name } '; $this->assertEquals($expected, Printer::doPrint($mutationAst)); $queryAstWithArtifacts = Parser::parse( 'query ($foo: TestType) @testDirective { id, name }' ); $expected = 'query ($foo: TestType) @testDirective { id name } '; $this->assertEquals($expected, Printer::doPrint($queryAstWithArtifacts)); $mutationAstWithArtifacts = Parser::parse( 'mutation ($foo: TestType) @testDirective { id, name }' ); $expected = 'mutation ($foo: TestType) @testDirective { id name } '; $this->assertEquals($expected, Printer::doPrint($mutationAstWithArtifacts)); } /** * @it correctly prints single-line block strings with leading space */ public function testCorrectlyPrintsSingleLineBlockStringsWithLeadingSpace() { $mutationAstWithArtifacts = Parser::parse( '{ field(arg: """ space-led value""") }' ); $expected = '{ field(arg: """ space-led value""") } '; $this->assertEquals($expected, Printer::doPrint($mutationAstWithArtifacts)); } /** * @it correctly prints block strings with a first line indentation */ public function testCorrectlyPrintsBlockStringsWithAFirstLineIndentation() { $mutationAstWithArtifacts = Parser::parse( '{ field(arg: """ first line indentation """) }' ); $expected = '{ field(arg: """ first line indentation """) } '; $this->assertEquals($expected, Printer::doPrint($mutationAstWithArtifacts)); } /** * @it Experimental: correctly prints fragment defined variables */ public function testExperimentalCorrectlyPrintsFragmentDefinedVariables() { $fragmentWithVariable = Parser::parse(' fragment Foo($a: ComplexType, $b: Boolean = false) on TestType { id } ', ['experimentalFragmentVariables' => true] ); $this->assertEquals( Printer::doPrint($fragmentWithVariable), 'fragment Foo($a: ComplexType, $b: Boolean = false) on TestType { id } ' ); } /** * @it correctly prints single-line with leading space and quotation */ public function testCorrectlyPrintsSingleLineStringsWithLeadingSpaceAndQuotation() { $mutationAstWithArtifacts = Parser::parse( '{ field(arg: """ space-led value "quoted string" """) }' ); $expected = '{ field(arg: """ space-led value "quoted string" """) } '; $this->assertEquals($expected, Printer::doPrint($mutationAstWithArtifacts)); } /** * @it prints kitchen sink */ public function testPrintsKitchenSink() { $kitchenSink = file_get_contents(__DIR__ . '/kitchen-sink.graphql'); $ast = Parser::parse($kitchenSink); $printed = Printer::doPrint($ast); $expected = <<<'EOT' query queryName($foo: ComplexType, $site: Site = MOBILE) { whoever123is: node(id: [123, 456]) { id ... on User @defer { field2 { id alias: field1(first: 10, after: $foo) @include(if: $foo) { id ...frag } } } ... @skip(unless: $foo) { id } ... { id } } } mutation likeStory { like(story: 123) @defer { story { id } } } subscription StoryLikeSubscription($input: StoryLikeSubscribeInput) { storyLikeSubscribe(input: $input) { story { likers { count } likeSentence { text } } } } fragment frag on Friend { foo(size: $size, bar: $b, obj: {key: "value", block: """ block string uses \""" """}) } { unnamed(truthy: true, falsey: false, nullish: null) query } EOT; $this->assertEquals($expected, $printed); } }