some tests for type-generation
This commit is contained in:
+8
-1
@@ -32,6 +32,7 @@ func writeSelectionSetStruct(builder *strings.Builder, selectionSet ast.Selectio
|
||||
if selection.Alias != "" {
|
||||
jsonName = selection.Alias
|
||||
} else {
|
||||
// TODO: is this case needed? tests don't seem to get here.
|
||||
jsonName = selection.Name
|
||||
}
|
||||
// We need an exportable name for JSON-marshaling.
|
||||
@@ -40,6 +41,11 @@ func writeSelectionSetStruct(builder *strings.Builder, selectionSet ast.Selectio
|
||||
builder.WriteString(goName)
|
||||
builder.WriteRune(' ')
|
||||
|
||||
if selection.Definition == nil {
|
||||
// Unclear why gqlparser hasn't already rejected this,
|
||||
// but empirically it might not.
|
||||
return fmt.Errorf("undefined selection %v", selection)
|
||||
}
|
||||
writeType(builder, selection.Definition.Type, selection.SelectionSet, schema)
|
||||
|
||||
if jsonName != goName {
|
||||
@@ -77,7 +83,8 @@ func writeType(builder *strings.Builder, typ *ast.Type, selectionSet ast.Selecti
|
||||
// Type is a list.
|
||||
builder.WriteString("[]")
|
||||
typ = typ.Elem
|
||||
} else if !typ.NonNull { // no need for pointer if we have a list
|
||||
}
|
||||
if !typ.NonNull {
|
||||
builder.WriteString("*")
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"go/format"
|
||||
"testing"
|
||||
|
||||
"github.com/vektah/gqlparser"
|
||||
"github.com/vektah/gqlparser/ast"
|
||||
)
|
||||
|
||||
func gofmt(src string) (string, error) {
|
||||
formatted, err := format.Source([]byte(src))
|
||||
if err != nil {
|
||||
return src, err
|
||||
}
|
||||
return string(formatted), nil
|
||||
}
|
||||
|
||||
func TestTypeForOperation(t *testing.T) {
|
||||
schema, err := gqlparser.LoadSchema(&ast.Source{Name: "test schema", Input: `
|
||||
type AuthMethod {
|
||||
provider: String
|
||||
email: String
|
||||
}
|
||||
|
||||
type User {
|
||||
id: ID!
|
||||
name: String
|
||||
emails: [String!]!
|
||||
emailsOrNull: [String!]
|
||||
emailsWithNulls: [String]!
|
||||
emailsWithNullsOrNull: [String]
|
||||
authMethods: [AuthMethod!]!
|
||||
}
|
||||
|
||||
type Query {
|
||||
user: User
|
||||
}
|
||||
`})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
operation string
|
||||
expectedGoType string
|
||||
}{{
|
||||
"SimpleQuery",
|
||||
`{ user { id } }`,
|
||||
`struct{
|
||||
User *struct {
|
||||
Id string ` + "`json:\"id\"`" + `
|
||||
} ` + "`json:\"user\"`" + `
|
||||
}`,
|
||||
}, {
|
||||
"QueryWithAlias",
|
||||
`{ User: user { ID: id } }`,
|
||||
`struct{
|
||||
User *struct {
|
||||
ID string
|
||||
}
|
||||
}`,
|
||||
// Here on out, we use aliases, just because aliases are a lot less
|
||||
// annoying to write in Go strings than Go struct tags.
|
||||
}, {
|
||||
"QueryWithSlices",
|
||||
`{
|
||||
User: user {
|
||||
Emails: emails
|
||||
EmailsOrNull: emailsOrNull
|
||||
EmailsWithNulls: emailsWithNulls
|
||||
EmailsWithNullsOrNull: emailsWithNullsOrNull
|
||||
}
|
||||
}`,
|
||||
`struct{
|
||||
User *struct {
|
||||
Emails []string
|
||||
EmailsOrNull []string
|
||||
EmailsWithNulls []*string
|
||||
EmailsWithNullsOrNull []*string
|
||||
}
|
||||
}`,
|
||||
}, {
|
||||
"QueryWithStructs",
|
||||
`{
|
||||
User: user {
|
||||
AuthMethods: authMethods {
|
||||
Provider: provider
|
||||
Email: email
|
||||
}
|
||||
}
|
||||
}`,
|
||||
`struct{
|
||||
User *struct {
|
||||
AuthMethods []struct {
|
||||
Provider *string
|
||||
Email *string
|
||||
}
|
||||
}
|
||||
}`,
|
||||
}}
|
||||
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
expectedGoType, err := gofmt("type Response " + test.expectedGoType)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
queryDoc, graphqlError := gqlparser.LoadQuery(schema, test.operation)
|
||||
if graphqlError != nil {
|
||||
t.Fatal(graphqlError)
|
||||
}
|
||||
|
||||
if len(queryDoc.Operations) != 1 {
|
||||
t.Fatalf("got %v operations, want 1", len(queryDoc.Operations))
|
||||
}
|
||||
|
||||
goType, err := typeForOperation(queryDoc.Operations[0], schema)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// gofmt before comparing.
|
||||
goType, err = gofmt("type Response " + goType)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if goType != expectedGoType {
|
||||
t.Errorf("got:\n%v\nwant:\n%v\n", goType, expectedGoType)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user