From 9c63f7c1a5d2cec01f5c215375484123432861f7 Mon Sep 17 00:00:00 2001 From: Dmitry Frolov Date: Sun, 29 Dec 2024 12:39:21 +0700 Subject: [PATCH] fix(astprinter): implement transitive interface output Just copied relevant part from EnterObjectTypeDefinition() Also add tests Fixes #1018 --- pkg/astprinter/astprinter.go | 14 ++++++++++++++ pkg/astprinter/astprinter_test.go | 4 ++++ v2/pkg/astprinter/astprinter.go | 14 ++++++++++++++ v2/pkg/astprinter/astprinter_test.go | 4 ++++ 4 files changed, 36 insertions(+) diff --git a/pkg/astprinter/astprinter.go b/pkg/astprinter/astprinter.go index 2e4e619cd2..a23d1dfbf3 100644 --- a/pkg/astprinter/astprinter.go +++ b/pkg/astprinter/astprinter.go @@ -538,6 +538,20 @@ func (p *printVisitor) EnterInterfaceTypeDefinition(ref int) { p.write(p.document.InterfaceTypeDefinitionNameBytes(ref)) p.write(literal.SPACE) + if len(p.document.InterfaceTypeDefinitions[ref].ImplementsInterfaces.Refs) != 0 { + p.write(literal.IMPLEMENTS) + p.write(literal.SPACE) + for i, j := range p.document.InterfaceTypeDefinitions[ref].ImplementsInterfaces.Refs { + if i != 0 { + p.write(literal.SPACE) + p.write(literal.AND) + p.write(literal.SPACE) + } + p.must(p.document.PrintType(j, p.out)) + } + p.write(literal.SPACE) + } + p.inputValueDefinitionOpener = literal.LPAREN p.inputValueDefinitionCloser = literal.RPAREN } diff --git a/pkg/astprinter/astprinter_test.go b/pkg/astprinter/astprinter_test.go index e50d5556fd..1d316d4a5c 100644 --- a/pkg/astprinter/astprinter_test.go +++ b/pkg/astprinter/astprinter_test.go @@ -485,6 +485,10 @@ vary: [String]! = []) on QUERY directive @include(if: Boolean!) repeatable on FI `scalar Date schema {query: Query} type Query {me: User! user(id: ID!): User allUsers: [User] search(term: String!): [SearchResult!]! myChats: [Chat!]!} enum Role {USER ADMIN} interface Node {id: ID!} union SearchResult = User | Chat | ChatMessage type User implements Node {id: ID! username: String! email: String! role: Role!} type Chat implements Node {id: ID! users: [User!]! messages: [ChatMessage!]!} type ChatMessage implements Node {id: ID! content: String! time: Date! user: User!}`) }) }) + t.Run("transitive interfaces", func(t *testing.T) { + run(t, "interface I1 {id: ID!} interface I2 implements I1 {id: ID!} interface I3 implements I1 & I2 {id: ID!}", + "interface I1 {id: ID!} interface I2 implements I1 {id: ID!} interface I3 implements I1 & I2 {id: ID!}") + }) } func TestPrintArgumentWithBeforeAfterValue(t *testing.T) { diff --git a/v2/pkg/astprinter/astprinter.go b/v2/pkg/astprinter/astprinter.go index cd492dc25d..58d9d0d9c9 100644 --- a/v2/pkg/astprinter/astprinter.go +++ b/v2/pkg/astprinter/astprinter.go @@ -601,6 +601,20 @@ func (p *printVisitor) EnterInterfaceTypeDefinition(ref int) { p.write(p.document.InterfaceTypeDefinitionNameBytes(ref)) p.write(literal.SPACE) + if len(p.document.InterfaceTypeDefinitions[ref].ImplementsInterfaces.Refs) != 0 { + p.write(literal.IMPLEMENTS) + p.write(literal.SPACE) + for i, j := range p.document.InterfaceTypeDefinitions[ref].ImplementsInterfaces.Refs { + if i != 0 { + p.write(literal.SPACE) + p.write(literal.AND) + p.write(literal.SPACE) + } + p.must(p.document.PrintType(j, p.out)) + } + p.write(literal.SPACE) + } + p.inputValueDefinitionOpener = literal.LPAREN p.inputValueDefinitionCloser = literal.RPAREN } diff --git a/v2/pkg/astprinter/astprinter_test.go b/v2/pkg/astprinter/astprinter_test.go index 41f38c676c..d57b81ae85 100644 --- a/v2/pkg/astprinter/astprinter_test.go +++ b/v2/pkg/astprinter/astprinter_test.go @@ -654,6 +654,10 @@ fragment NameFragment on Dog { `scalar Date schema {query: Query} type Query {me: User! user(id: ID!): User allUsers: [User] search(term: String!): [SearchResult!]! myChats: [Chat!]!} enum Role {USER ADMIN} interface Node {id: ID!} union SearchResult = User | Chat | ChatMessage type User implements Node {id: ID! username: String! email: String! role: Role!} type Chat implements Node {id: ID! users: [User!]! messages: [ChatMessage!]!} type ChatMessage implements Node {id: ID! content: String! time: Date! user: User!}`) }) }) + t.Run("transitive interfaces", func(t *testing.T) { + run(t, "interface I1 {id: ID!} interface I2 implements I1 {id: ID!} interface I3 implements I1 & I2 {id: ID!}", + "interface I1 {id: ID!} interface I2 implements I1 {id: ID!} interface I3 implements I1 & I2 {id: ID!}") + }) } func TestPrintArgumentWithBeforeAfterValue(t *testing.T) {