Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for interfaces, part 2: list-of-interface #54

Merged
merged 3 commits into from
Aug 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions generate/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,6 @@ func TestGenerate(t *testing.T) {
t.Run("Build", func(t *testing.T) {
if testing.Short() {
t.Skip("skipping build due to -short")
} else if sourceFilename == "InterfaceNesting.graphql" ||
sourceFilename == "InterfaceListField.graphql" {
t.Skip("TODO: enable after fixing " +
"https://github.com/Khan/genqlient/issues/8")
} else if sourceFilename == "Omitempty.graphql" {
t.Skip("TODO: enable after fixing " +
"https://github.com/Khan/genqlient/issues/43")
Expand Down
24 changes: 23 additions & 1 deletion generate/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"io"
"path/filepath"
"runtime"
"strings"
"text/template"
)

Expand All @@ -12,13 +13,34 @@ var (
thisDir = filepath.Dir(thisFilename)
)

func repeat(n int, s string) string {
var builder strings.Builder
for i := 0; i < n; i++ {
builder.WriteString(s)
}
return builder.String()
}

func intRange(n int) []int {
ret := make([]int, n)
for i := 0; i < n; i++ {
ret[i] = i
}
return ret
}

func sub(x, y int) int { return x - y }

// execute executes the given template with the funcs from this generator.
func (g *generator) execute(tmplRelFilename string, w io.Writer, data interface{}) error {
tmpl := g.templateCache[tmplRelFilename]
if tmpl == nil {
absFilename := filepath.Join(thisDir, tmplRelFilename)
funcMap := template.FuncMap{
"ref": g.ref,
"ref": g.ref,
"repeat": repeat,
"intRange": intRange,
"sub": sub,
}
var err error
tmpl, err = template.New(tmplRelFilename).Funcs(funcMap).ParseFiles(absFilename)
Expand Down
12 changes: 11 additions & 1 deletion generate/testdata/queries/InterfaceListField.graphql
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
query InterfaceNoFragmentsQuery {
query InterfaceListField {
root {
id
name
Expand All @@ -8,4 +8,14 @@ query InterfaceNoFragmentsQuery {
name
}
}
# @genqlient(pointer: true)
withPointer: root {
id
name
children {
__typename
id
name
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
query InterfaceListOfListOfListsField {
listOfListsOfListsOfContent { __typename id name }
# @genqlient(pointer: true)
withPointer: listOfListsOfListsOfContent { __typename id name }
}
2 changes: 2 additions & 0 deletions generate/testdata/queries/InterfaceNoFragments.graphql
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
query InterfaceNoFragmentsQuery {
root { id name } # (make sure sibling fields work)
randomItem { __typename id name }
# @genqlient(pointer: true)
withPointer: randomItem { __typename id name }
}
1 change: 1 addition & 0 deletions generate/testdata/queries/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ type Query {
getJunk: Junk
getComplexJunk: ComplexJunk
listOfListsOfLists: [[[String!]!]!]!
listOfListsOfListsOfContent: [[[Content!]!]!]!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

listOfListsOfListsOfContent: [[[Content]!]!]! is a type where one might want to use a pointer (though types like this usually seem to usually be accidental). Pointers to slices shouldn't be necessary, so it seems correct to only support pointers on the most-inner type.

Copy link
Collaborator Author

@benjaminjkraft benjaminjkraft Aug 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are valid uses for required-list-of-optional-item, if you want the input in correspondence to the output. But I agree I can only see a reason to support it at the innermost point. Anyways, this is all mentioned at #16; my attitude is basically "if someone finds a legitimate reason to want it, we can implement it" :-) .

}

type Mutation {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"operations": [
{
"operationName": "InterfaceNoFragmentsQuery",
"query": "\nquery InterfaceNoFragmentsQuery {\n\troot {\n\t\tid\n\t\tname\n\t\tchildren {\n\t\t\t__typename\n\t\t\tid\n\t\t\tname\n\t\t}\n\t}\n}\n",
"operationName": "InterfaceListField",
"query": "\nquery InterfaceListField {\n\troot {\n\t\tid\n\t\tname\n\t\tchildren {\n\t\t\t__typename\n\t\t\tid\n\t\t\tname\n\t\t}\n\t}\n\twithPointer: root {\n\t\tid\n\t\tname\n\t\tchildren {\n\t\t\t__typename\n\t\t\tid\n\t\t\tname\n\t\t}\n\t}\n}\n",
"sourceLocation": "testdata/queries/InterfaceListField.graphql"
}
]
Expand Down
Loading