diff --git a/cmd/gen.go b/cmd/gen.go index c69858b44b0..2d3f2aa1aac 100644 --- a/cmd/gen.go +++ b/cmd/gen.go @@ -6,6 +6,7 @@ import ( "github.com/99designs/gqlgen/api" "github.com/99designs/gqlgen/codegen/config" + "github.com/99designs/gqlgen/plugin/modelgen" "github.com/pkg/errors" "github.com/urfave/cli" ) @@ -42,3 +43,18 @@ var genCmd = cli.Command{ } }, } + +func main() { + cfg, err := config.LoadConfigFromDefaultLocations() + if os.IsNotExist(errors.Cause(err)) { + cfg = config.DefaultConfig() + } else if err != nil { + fmt.Fprintln(os.Stderr, err.Error()) + os.Exit(2) + } + + err = modelgen.New().(*modelgen.Plugin).MutateConfig(cfg) + if err != nil { + panic(err) + } +} diff --git a/plugin/resolvergen/out/model.go b/plugin/resolvergen/out/model.go new file mode 100644 index 00000000000..11d6d254209 --- /dev/null +++ b/plugin/resolvergen/out/model.go @@ -0,0 +1,14 @@ +package customresolver + +import "context" + +type Resolver struct { +} + +type QueryResolver interface { + Resolver(ctx context.Context) (*Resolver, error) +} + +type ResolverResolver interface { + Name(ctx context.Context, obj *Resolver) (string, error) +} diff --git a/plugin/resolvergen/out/resolver.go b/plugin/resolvergen/out/resolver.go new file mode 100644 index 00000000000..8461fbbbb29 --- /dev/null +++ b/plugin/resolvergen/out/resolver.go @@ -0,0 +1,26 @@ +package customresolver + +import ( + "context" +) // THIS CODE IS A STARTING POINT ONLY. IT WILL NOT BE UPDATED WITH SCHEMA CHANGES. + +type CustomResolverType struct{} + +func (r *CustomResolverType) Query() QueryResolver { + return &queryCustomResolverType{r} +} +func (r *CustomResolverType) Resolver() ResolverResolver { + return &resolverCustomResolverType{r} +} + +type queryCustomResolverType struct{ *CustomResolverType } + +func (r *queryCustomResolverType) Resolver(ctx context.Context) (*Resolver, error) { + panic("not implemented") +} + +type resolverCustomResolverType struct{ *CustomResolverType } + +func (r *resolverCustomResolverType) Name(ctx context.Context, obj *Resolver) (string, error) { + panic("not implemented") +} diff --git a/plugin/resolvergen/resolver_test.go b/plugin/resolvergen/resolver_test.go index b100f7cc74c..fce700db7fa 100644 --- a/plugin/resolvergen/resolver_test.go +++ b/plugin/resolvergen/resolver_test.go @@ -2,162 +2,47 @@ package resolvergen import ( "fmt" - "go/types" - "io/ioutil" - "os" - "path/filepath" - "strings" + "syscall" "testing" - "unicode" "github.com/99designs/gqlgen/codegen" "github.com/99designs/gqlgen/codegen/config" - "github.com/vektah/gqlparser/ast" + "github.com/stretchr/testify/require" + "golang.org/x/tools/go/packages" ) -func TestPlugin_Name(t *testing.T) { - t.Run("test plugin name", func(t *testing.T) { - m := &Plugin{} - if got, want := m.Name(), "resovlergen"; got != want { - t.Errorf("Plugin.Name() = %v, want %v", got, want) - } - }) -} +func TestPlugin(t *testing.T) { + _ = syscall.Unlink("out/resolver.go") -// Types for testing code generation, both Mutation and -// MutationResolver must implement types.Type. -type Mutation struct{} + cfg, err := config.LoadConfig("testdata/gqlgen.yml") + require.NoError(t, err) + p := Plugin{} -func (m *Mutation) Underlying() types.Type { - return m -} - -func (m *Mutation) String() string { - return "Mutation" -} - -type MutationResolver struct{} - -func (m *MutationResolver) Underlying() types.Type { - return m -} + data, err := codegen.BuildData(cfg) + if err != nil { + panic(err) + } -func (m *MutationResolver) String() string { - return "MutationResolver" + require.NoError(t, p.GenerateCode(data)) + assertNoErrors(t, "github.com/99designs/gqlgen/plugin/resolvergen/out") } -func TestPlugin_GenerateCode(t *testing.T) { - makeData := func(cfg config.PackageConfig) *codegen.Data { - m := &Mutation{} - obj := &codegen.Object{ - Definition: &ast.Definition{ - Name: fmt.Sprint(m), - }, - Root: true, - Fields: []*codegen.Field{ - &codegen.Field{ - IsResolver: true, - GoFieldName: "Name", - TypeReference: &config.TypeReference{ - GO: m, - }, - }, - }, - ResolverInterface: &MutationResolver{}, - } - obj.Fields[0].Object = obj - return &codegen.Data{ - Config: &config.Config{ - Resolver: cfg, - }, - Objects: codegen.Objects{obj}, - } +func assertNoErrors(t *testing.T, pkg string) { + pkgs, err := packages.Load(&packages.Config{ + Mode: packages.LoadTypes, + }, pkg) + if err != nil { + panic(err) } - t.Run("renders expected contents", func(t *testing.T) { - m := &Plugin{} - - // use a temp dir to ensure generated file uniqueness, - // since if a file already exists it won't be - // overwritten. - tempDir, err := ioutil.TempDir("", "resolvergen-") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tempDir) - filename := filepath.Join(tempDir, "generated.go") - - data := makeData(config.PackageConfig{ - Filename: filename, - Package: "customresolver", - Type: "CustomResolverType", - }) - if err := m.GenerateCode(data); err != nil { - t.Fatal(err) - } - - byteContents, err := ioutil.ReadFile(filename) - if err != nil { - t.Fatal(err) + hasErrors := false + for _, pkg := range pkgs { + for _, err := range pkg.Errors { + hasErrors = true + fmt.Println(err.Pos + ":" + err.Msg) } - contents := string(byteContents) - - want := "package customresolver" - if !strings.Contains(contents, want) { - t.Fatalf("expected package name not found: want = %q\n%s", want, contents) - } - - // Skip all white-space chars after start and want - // length. Useful to jump to next non-white character - // contents for generated code assertions. - skipWhitespace := func(start int, want string) int { - return start + len(want) + strings.IndexFunc( - string(contents[start+len(want):]), - func(r rune) bool { return !unicode.IsSpace(r) }, - ) - } - // Check if want begins at the given start point. - lookingAt := func(start int, want string) bool { - return strings.Index(string(contents[start:]), want) == 0 - } - - // Assert Mutation method contents for *CustomResolverType - want = "func (r *CustomResolverType) Mutation() MutationResolver {" - start := strings.Index(contents, want) - if start == -1 { - t.Fatalf("mutation method for custom resolver not found: want = %q\n%s", want, contents) - } - start = skipWhitespace(start, want) - want = "return &mutationCustomResolverType{r}" - if !lookingAt(start, want) { - t.Fatalf("unexpected return on mutation method for custom resolver: want = %q\n%s", want, contents) - } - start = skipWhitespace(start, want) - want = "}" - if !lookingAt(start, want) { - t.Fatalf("unexpected contents on mutation method for custom resolver: want = %q\n%s", want, contents) - } - - want = "type mutationCustomResolverType struct{ *CustomResolverType }" - if !strings.Contains(contents, want) { - t.Fatalf("expected embedded resolver type struct not found: want = %q\n%s", want, contents) - } - - // Assert Name method contents for *mutationCustomResolverType - want = "func (r *mutationCustomResolverType) Name(ctx context.Context) (Mutation, error) {" - start = strings.Index(contents, want) - if start == -1 { - t.Fatalf("Name method for mutation custom resolver type not found: want = %q\n%s", want, contents) - } - start = skipWhitespace(start, want) - want = `panic("not implemented")` - if !lookingAt(start, want) { - t.Fatalf("unexpected Name method contents for mutation custom resolver type: want = %q\n%s", want, contents) - } - start = skipWhitespace(start, want) - want = "}" - if !lookingAt(start, want) { - t.Fatalf("unexpected Name method contents for mutation custom resolver type: want = %q\n%s", want, contents) - } - }) + } + if hasErrors { + t.Fatal("see compilation errors above") + } } diff --git a/plugin/resolvergen/testdata/gqlgen.yml b/plugin/resolvergen/testdata/gqlgen.yml new file mode 100644 index 00000000000..f5f0f7bdcb7 --- /dev/null +++ b/plugin/resolvergen/testdata/gqlgen.yml @@ -0,0 +1,14 @@ +schema: + - "testdata/schema.graphql" + +exec: + filename: out/ignored.go +model: + filename: out/generated.go +resolver: + filename: out/resolver.go + type: CustomResolverType + +models: + Resolver: + model: github.com/99designs/gqlgen/plugin/resolvergen/out.Resolver diff --git a/plugin/resolvergen/testdata/schema.graphql b/plugin/resolvergen/testdata/schema.graphql new file mode 100644 index 00000000000..7ced7397b57 --- /dev/null +++ b/plugin/resolvergen/testdata/schema.graphql @@ -0,0 +1,7 @@ +type Query { + resolver: Resolver! +} + +type Resolver { + name: String! +}