Files
genqlient/generate/generate_test.go
T

114 lines
3.1 KiB
Go

package generate
import (
"errors"
"fmt"
"go/format"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
)
const dataDir = "testdata/queries"
func readFile(t *testing.T, filename string, allowNotExist bool) string {
t.Helper()
data, err := ioutil.ReadFile(filepath.Join(dataDir, filename))
if err != nil {
if allowNotExist && errors.Is(err, os.ErrNotExist) {
return ""
}
t.Fatal(err)
}
return string(data)
}
func gofmt(filename, src string) (string, error) {
src = strings.TrimSpace(src)
formatted, err := format.Source([]byte(src))
if err != nil {
return src, fmt.Errorf("go parse error in %v: %w", filename, err)
}
return string(formatted), nil
}
// TestGenerate is a snapshot-based test of code-generation.
//
// This file just has the test runner; the actual data is all in
// testdata/queries. Specifically, the schema used for all the queries is in
// schema.graphql; the queries themselves are in TestName.graphql. The test
// asserts that running genqlient on that query produces the generated code in
// the snapshot-file TestName.graphql.go.
//
// To update the snapshots (if the code-generator has changed), run the test
// with `UPDATE_SNAPSHOTS=1`; it will fail the tests and print any diffs, but
// update the snapshots. Make sure to check that the output is sensible; the
// snapshots don't even get compiled!
func TestGenerate(t *testing.T) {
update := (os.Getenv("UPDATE_SNAPSHOTS") == "1")
// we can test parts of features even if they're not done yet!
allowBrokenFeatures = true
files, err := ioutil.ReadDir(dataDir)
if err != nil {
t.Fatal(err)
}
for _, file := range files {
graphqlFilename := file.Name()
if graphqlFilename == "schema.graphql" || !strings.HasSuffix(graphqlFilename, ".graphql") {
continue
}
goFilename := graphqlFilename + ".go"
queriesFilename := graphqlFilename + ".json"
t.Run(graphqlFilename, func(t *testing.T) {
generated, err := Generate(&Config{
Schema: filepath.Join(dataDir, "schema.graphql"),
Operations: []string{filepath.Join(dataDir, graphqlFilename)},
Package: "test",
Generated: goFilename,
ExportOperations: queriesFilename,
Scalars: map[string]string{
"ID": "github.com/me/mypkg.ID",
"DateTime": "time.Time",
},
})
if err != nil {
t.Fatal(err)
}
for filename, content := range generated {
expectedContent := readFile(t, filename, update)
if strings.HasSuffix(filename, ".go") {
fmted, err := gofmt(filename, expectedContent)
if err != nil {
// Ignore gofmt errors if we are updating
if !update {
t.Fatal(err)
}
} else {
expectedContent = fmted
}
}
if string(content) != expectedContent {
t.Errorf("mismatch in %v\ngot:\n%v\nwant:\n%v\n",
filename, string(content), expectedContent)
if update {
t.Log("Updating testdata dir to match")
err = ioutil.WriteFile(filepath.Join(dataDir, filename), content, 0o644)
if err != nil {
t.Errorf("Unable to update testdata dir: %v", err)
}
}
}
// TODO(benkraft): Also check that the code at least builds!
}
})
}
}