blob: 4da5b3ce40c8781d64d37ae56d8c9cc7f3449a9a [file] [log] [blame]
Damien Neil220c2022018-08-15 11:24:18 -07001// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package protogen
6
7import (
8 "io/ioutil"
9 "os"
10 "os/exec"
11 "path/filepath"
12 "strings"
13 "testing"
14
15 "github.com/golang/protobuf/proto"
16 pluginpb "github.com/golang/protobuf/protoc-gen-go/plugin"
17)
18
19func TestFiles(t *testing.T) {
20 gen, err := New(makeRequest(t, "testdata/go_package/no_go_package_import.proto"))
21 if err != nil {
22 t.Fatal(err)
23 }
24 for _, test := range []struct {
25 path string
26 wantGenerate bool
27 }{
28 {
29 path: "go_package/no_go_package_import.proto",
30 wantGenerate: true,
31 },
32 {
33 path: "go_package/no_go_package.proto",
34 wantGenerate: false,
35 },
36 } {
37 f, ok := gen.FileByName(test.path)
38 if !ok {
39 t.Errorf("%q: not found by gen.FileByName", test.path)
40 continue
41 }
42 if f.Generate != test.wantGenerate {
43 t.Errorf("%q: Generate=%v, want %v", test.path, f.Generate, test.wantGenerate)
44 }
45 }
46}
47
Damien Neild9016772018-08-23 14:39:30 -070048func TestImports(t *testing.T) {
49 gen, err := New(&pluginpb.CodeGeneratorRequest{})
50 if err != nil {
51 t.Fatal(err)
52 }
53 g := gen.NewGeneratedFile("foo.go", "golang.org/x/foo")
54 g.P("package foo")
55 g.P()
56 for _, importPath := range []GoImportPath{
57 "golang.org/x/foo",
58 // Multiple references to the same package.
59 "golang.org/x/bar",
60 "golang.org/x/bar",
61 // Reference to a different package with the same basename.
62 "golang.org/y/bar",
63 "golang.org/x/baz",
64 } {
65 g.P("var _ = ", GoIdent{GoName: "X", GoImportPath: importPath}, " // ", importPath)
66 }
67 want := `package foo
68
69import (
70 bar "golang.org/x/bar"
71 bar1 "golang.org/y/bar"
72 baz "golang.org/x/baz"
73)
74
75var _ = X // "golang.org/x/foo"
76var _ = bar.X // "golang.org/x/bar"
77var _ = bar.X // "golang.org/x/bar"
78var _ = bar1.X // "golang.org/y/bar"
79var _ = baz.X // "golang.org/x/baz"
80`
81 got, err := g.Content()
82 if err != nil {
83 t.Fatalf("g.Content() = %v", err)
84 }
85 if want != string(got) {
86 t.Fatalf(`want:
87==========
88%v
89==========
90
91got:
92==========
93%v
94==========`,
95 want, string(got))
96 }
97}
98
Damien Neil220c2022018-08-15 11:24:18 -070099// makeRequest returns a CodeGeneratorRequest for the given protoc inputs.
100//
101// It does this by running protoc with the current binary as the protoc-gen-go
102// plugin. This "plugin" produces a single file, named 'request', which contains
103// the code generator request.
104func makeRequest(t *testing.T, args ...string) *pluginpb.CodeGeneratorRequest {
105 workdir, err := ioutil.TempDir("", "test")
106 if err != nil {
107 t.Fatal(err)
108 }
109 defer os.RemoveAll(workdir)
110
111 cmd := exec.Command("protoc", "--plugin=protoc-gen-go="+os.Args[0])
112 cmd.Args = append(cmd.Args, "--go_out="+workdir, "-Itestdata")
113 cmd.Args = append(cmd.Args, args...)
114 cmd.Env = append(os.Environ(), "RUN_AS_PROTOC_PLUGIN=1")
115 out, err := cmd.CombinedOutput()
116 if len(out) > 0 || err != nil {
117 t.Log("RUNNING: ", strings.Join(cmd.Args, " "))
118 }
119 if len(out) > 0 {
120 t.Log(string(out))
121 }
122 if err != nil {
123 t.Fatalf("protoc: %v", err)
124 }
125
126 b, err := ioutil.ReadFile(filepath.Join(workdir, "request"))
127 if err != nil {
128 t.Fatal(err)
129 }
130 req := &pluginpb.CodeGeneratorRequest{}
131 if err := proto.UnmarshalText(string(b), req); err != nil {
132 t.Fatal(err)
133 }
134 return req
135}
136
137func init() {
138 if os.Getenv("RUN_AS_PROTOC_PLUGIN") != "" {
139 Run(func(p *Plugin) error {
Damien Neild9016772018-08-23 14:39:30 -0700140 g := p.NewGeneratedFile("request", "")
Damien Neil220c2022018-08-15 11:24:18 -0700141 return proto.MarshalText(g, p.Request)
142 })
143 os.Exit(0)
144 }
145}