1
15
16 package golang
17
18 import (
19 "path"
20 "path/filepath"
21 "strings"
22 "testing"
23
24 "github.com/bazelbuild/bazel-gazelle/config"
25 "github.com/bazelbuild/bazel-gazelle/language"
26 "github.com/bazelbuild/bazel-gazelle/language/proto"
27 "github.com/bazelbuild/bazel-gazelle/resolve"
28 "github.com/bazelbuild/bazel-gazelle/rule"
29 "github.com/bazelbuild/bazel-gazelle/testtools"
30 "github.com/bazelbuild/bazel-gazelle/walk"
31 "github.com/google/go-cmp/cmp"
32 )
33
34 func testConfig(t *testing.T, args ...string) (*config.Config, []language.Language, []config.Configurer) {
35
36
37
38 haveRoot := false
39 for _, arg := range args {
40 if strings.HasPrefix(arg, "-repo_root") {
41 haveRoot = true
42 break
43 }
44 }
45 if !haveRoot {
46 args = append(args, "-repo_root=.")
47 }
48
49 cexts := []config.Configurer{
50 &config.CommonConfigurer{},
51 &walk.Configurer{},
52 &resolve.Configurer{},
53 }
54 langs := []language.Language{proto.NewLanguage(), NewLanguage()}
55 c := testtools.NewTestConfig(t, cexts, langs, args)
56 for _, lang := range langs {
57 cexts = append(cexts, lang)
58 }
59 return c, langs, cexts
60 }
61
62 func TestCommandLine(t *testing.T) {
63 c, _, _ := testConfig(
64 t,
65 "-build_tags=foo,bar",
66 "-go_prefix=example.com/repo",
67 "-go_naming_convention=import_alias",
68 "-external=vendored",
69 "-repo_root=.")
70 gc := getGoConfig(c)
71 for _, tag := range []string{"foo", "bar", "gc"} {
72 if !gc.genericTags[tag] {
73 t.Errorf("expected tag %q to be set", tag)
74 }
75 }
76 if gc.prefix != "example.com/repo" {
77 t.Errorf(`got prefix %q; want "example.com/repo"`, gc.prefix)
78 }
79 if gc.depMode != vendorMode {
80 t.Errorf("got dep mode %v; want %v", gc.depMode, vendorMode)
81 }
82 if gc.goNamingConvention != importAliasNamingConvention {
83 t.Errorf("got naming convention %v; want %v", gc.goNamingConvention, importAliasNamingConvention)
84 }
85 }
86
87 func TestDirectives(t *testing.T) {
88 c, _, cexts := testConfig(t)
89 content := []byte(`
90 # gazelle:build_tags foo,bar
91 # gazelle:importmap_prefix x
92 # gazelle:prefix y
93 # gazelle:go_grpc_compilers abc, def
94 # gazelle:go_proto_compilers foo, bar
95 `)
96 f, err := rule.LoadData(filepath.FromSlash("test/BUILD.bazel"), "test", content)
97 if err != nil {
98 t.Fatal(err)
99 }
100 for _, cext := range cexts {
101 cext.Configure(c, "test", f)
102 }
103 gc := getGoConfig(c)
104 for _, tag := range []string{"foo", "bar", "gc"} {
105 if !gc.genericTags[tag] {
106 t.Errorf("expected tag %q to be set", tag)
107 }
108 }
109 if gc.prefix != "y" {
110 t.Errorf(`got prefix %q; want "y"`, gc.prefix)
111 }
112 if gc.prefixRel != "test" {
113 t.Errorf(`got prefixRel %q; want "test"`, gc.prefixRel)
114 }
115 if gc.importMapPrefix != "x" {
116 t.Errorf(`got importmapPrefix %q; want "x"`, gc.importMapPrefix)
117 }
118 if gc.importMapPrefixRel != "test" {
119 t.Errorf(`got importmapPrefixRel %q; want "test"`, gc.importMapPrefixRel)
120 }
121 if !gc.goGrpcCompilersSet {
122 t.Error("expected goGrpcCompilersSet to be set")
123 }
124 if diff := cmp.Diff([]string{"abc", "def"}, gc.goGrpcCompilers); diff != "" {
125 t.Errorf("(-want, +got): %s", diff)
126 }
127
128 if !gc.goProtoCompilersSet {
129 t.Error("expected goProtoCompilersSet to be set")
130 }
131 if diff := cmp.Diff(gc.goProtoCompilers, []string{"foo", "bar"}); diff != "" {
132 t.Errorf("(-want, +got): %s", diff)
133 }
134
135 subContent := []byte(`
136 # gazelle:go_grpc_compilers
137 # gazelle:go_proto_compilers
138 `)
139 f, err = rule.LoadData(filepath.FromSlash("test/sub/BUILD.bazel"), "sub", subContent)
140 if err != nil {
141 t.Fatal(err)
142 }
143 for _, cext := range cexts {
144 cext.Configure(c, "test/sub", f)
145 }
146 gc = getGoConfig(c)
147 if gc.goGrpcCompilersSet {
148 t.Error("expected goGrpcCompilersSet to be unset")
149 }
150 if diff := cmp.Diff(defaultGoGrpcCompilers, gc.goGrpcCompilers); diff != "" {
151 t.Errorf("(-want, +got): %s", diff)
152 }
153
154 if gc.goProtoCompilersSet {
155 t.Error("expected goProtoCompilersSet to be unset")
156 }
157 if diff := cmp.Diff(defaultGoProtoCompilers, gc.goProtoCompilers); diff != "" {
158 t.Errorf("(-want, +got): %s", diff)
159 }
160
161 }
162
163 func TestVendorConfig(t *testing.T) {
164 c, _, cexts := testConfig(t)
165 gc := getGoConfig(c)
166 gc.prefix = "example.com/repo"
167 gc.prefixRel = ""
168 gc.importMapPrefix = "bad-importmap-prefix"
169 gc.importMapPrefixRel = ""
170 for _, cext := range cexts {
171 cext.Configure(c, "x/vendor", nil)
172 }
173 gc = getGoConfig(c)
174 if gc.prefix != "" {
175 t.Errorf(`prefix: got %q; want ""`, gc.prefix)
176 }
177 if gc.prefixRel != "x/vendor" {
178 t.Errorf(`prefixRel: got %q; want "x/vendor"`, gc.prefixRel)
179 }
180 if gc.importMapPrefix != "example.com/repo/x/vendor" {
181 t.Errorf(`importMapPrefix: got %q; want "example.com/repo/x/vendor"`, gc.importMapPrefix)
182 }
183 if gc.importMapPrefixRel != "x/vendor" {
184 t.Errorf(`importMapPrefixRel: got %q; want "x/vendor"`, gc.importMapPrefixRel)
185 }
186 }
187
188 func TestInferProtoMode(t *testing.T) {
189 c, _, cexts := testConfig(t)
190 for _, tc := range []struct {
191 desc, rel, content string
192 old proto.Mode
193 explicit bool
194 want proto.Mode
195 }{
196 {
197 desc: "default_empty",
198 old: proto.DefaultMode,
199 want: proto.DefaultMode,
200 }, {
201 desc: "default_to_legacy",
202 old: proto.DefaultMode,
203 content: `
204 load("@io_bazel_rules_go//proto:go_proto_library.bzl", "go_proto_library")
205
206 go_proto_library(
207 name = "foo_proto",
208 )
209 `,
210 want: proto.LegacyMode,
211 }, {
212 desc: "default_to_disable",
213 old: proto.DefaultMode,
214 content: `
215 load("@some_repo//:custom.bzl", "go_proto_library")
216 `,
217 want: proto.DisableMode,
218 }, {
219 desc: "vendor_disable",
220 old: proto.DefaultMode,
221 rel: "vendor",
222 want: proto.DisableMode,
223 }, {
224 desc: "explicit_override_legacy",
225 old: proto.DefaultMode,
226 explicit: true,
227 content: `
228 load("@io_bazel_rules_go//proto:go_proto_library.bzl", "go_proto_library")
229 `,
230 want: proto.DefaultMode,
231 }, {
232 desc: "explicit_override_vendor",
233 old: proto.DefaultMode,
234 explicit: true,
235 rel: "vendor",
236 want: proto.DefaultMode,
237 }, {
238 desc: "disable_override_legacy",
239 old: proto.DisableMode,
240 explicit: false,
241 content: `
242 load("@io_bazel_rules_go//proto:go_proto_library.bzl", "go_proto_library")
243 `,
244 want: proto.DisableMode,
245 },
246 } {
247 t.Run(tc.desc, func(t *testing.T) {
248 c := c.Clone()
249 pc := proto.GetProtoConfig(c)
250 pc.Mode = tc.old
251 pc.ModeExplicit = tc.explicit
252 var f *rule.File
253 if tc.content != "" {
254 var err error
255 f, err = rule.LoadData(path.Join(tc.rel, "BUILD.bazel"), tc.rel, []byte(tc.content))
256 if err != nil {
257 t.Fatal(err)
258 }
259 }
260 for _, cext := range cexts {
261 cext.Configure(c, tc.rel, f)
262 }
263 pc = proto.GetProtoConfig(c)
264 if pc.Mode != tc.want {
265 t.Errorf("got %v; want %v", pc.Mode, tc.want)
266 }
267 })
268 }
269 }
270
271 func TestPreprocessTags(t *testing.T) {
272 gc := newGoConfig()
273 expectedTags := []string{"gc"}
274 for _, tag := range expectedTags {
275 if !gc.genericTags[tag] {
276 t.Errorf("tag %q not set", tag)
277 }
278 }
279 unexpectedTags := []string{"x", "cgo", "go1.8", "go1.7"}
280 for _, tag := range unexpectedTags {
281 if gc.genericTags[tag] {
282 t.Errorf("tag %q unexpectedly set", tag)
283 }
284 }
285 }
286
287 func TestPrefixFallback(t *testing.T) {
288 c, _, cexts := testConfig(t)
289 for _, tc := range []struct {
290 desc, content, want string
291 }{
292 {
293 desc: "go_prefix",
294 content: `
295 go_prefix("example.com/repo")
296 `,
297 want: "example.com/repo",
298 }, {
299 desc: "gazelle",
300 content: `
301 gazelle(
302 name = "gazelle",
303 prefix = "example.com/repo",
304 )
305 `,
306 want: "example.com/repo",
307 },
308 } {
309 t.Run(tc.desc, func(t *testing.T) {
310 f, err := rule.LoadData("BUILD.bazel", "", []byte(tc.content))
311 if err != nil {
312 t.Fatal(err)
313 }
314 for _, cext := range cexts {
315 cext.Configure(c, "x", f)
316 }
317 gc := getGoConfig(c)
318 if !gc.prefixSet {
319 t.Fatalf("prefix not set")
320 }
321 if gc.prefix != tc.want {
322 t.Errorf("prefix: want %q; got %q", gc.prefix, tc.want)
323 }
324 if gc.prefixRel != "x" {
325 t.Errorf("rel: got %q; want %q", gc.prefixRel, "x")
326 }
327 })
328 }
329 }
330
331 func TestSplitValue(t *testing.T) {
332 for _, tc := range []struct {
333 value string
334 parts []string
335 }{
336 {
337 value: "\t foo, bar \t",
338 parts: []string{"foo", "bar"},
339 },
340 {
341 value: " foo ",
342 parts: []string{"foo"},
343 },
344 } {
345 parts := splitValue(tc.value)
346 if diff := cmp.Diff(tc.parts, parts); diff != "" {
347 t.Errorf("(-want, +got): %s", diff)
348 }
349
350 }
351 }
352
View as plain text