github.com/wolfd/bazel-gazelle@v0.14.0/internal/language/proto/resolve_test.go (about) 1 /* Copyright 2018 The Bazel Authors. All rights reserved. 2 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 Unless required by applicable law or agreed to in writing, software 10 distributed under the License is distributed on an "AS IS" BASIS, 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 */ 15 16 package proto 17 18 import ( 19 "path/filepath" 20 "strings" 21 "testing" 22 23 "github.com/bazelbuild/bazel-gazelle/internal/config" 24 "github.com/bazelbuild/bazel-gazelle/internal/label" 25 "github.com/bazelbuild/bazel-gazelle/internal/repos" 26 "github.com/bazelbuild/bazel-gazelle/internal/resolve" 27 "github.com/bazelbuild/bazel-gazelle/internal/rule" 28 bzl "github.com/bazelbuild/buildtools/build" 29 ) 30 31 func TestResolveProto(t *testing.T) { 32 type buildFile struct { 33 rel, content string 34 } 35 type testCase struct { 36 desc string 37 index []buildFile 38 old, want string 39 } 40 for _, tc := range []testCase{ 41 { 42 desc: "well_known", 43 index: []buildFile{{ 44 rel: "google/protobuf", 45 content: ` 46 proto_library( 47 name = "bad_proto", 48 srcs = ["any.proto"], 49 ) 50 `, 51 }}, 52 old: ` 53 proto_library( 54 name = "dep_proto", 55 _imports = [ 56 "google/api/http.proto", 57 "google/protobuf/any.proto", 58 "google/rpc/status.proto", 59 "google/type/latlng.proto", 60 ], 61 ) 62 `, 63 want: ` 64 proto_library( 65 name = "dep_proto", 66 deps = [ 67 "@com_google_protobuf//:any_proto", 68 "@go_googleapis//google/api:annotations_proto", 69 "@go_googleapis//google/rpc:status_proto", 70 "@go_googleapis//google/type:latlng_proto", 71 ], 72 ) 73 `, 74 }, { 75 desc: "index", 76 index: []buildFile{{ 77 rel: "foo", 78 content: ` 79 proto_library( 80 name = "foo_proto", 81 srcs = ["foo.proto"], 82 ) 83 `, 84 }}, 85 old: ` 86 proto_library( 87 name = "dep_proto", 88 _imports = ["foo/foo.proto"], 89 ) 90 `, 91 want: ` 92 proto_library( 93 name = "dep_proto", 94 deps = ["//foo:foo_proto"], 95 ) 96 `, 97 }, { 98 desc: "index_local", 99 old: ` 100 proto_library( 101 name = "foo_proto", 102 srcs = ["foo.proto"], 103 ) 104 105 proto_library( 106 name = "dep_proto", 107 _imports = ["test/foo.proto"], 108 ) 109 `, 110 want: ` 111 proto_library( 112 name = "foo_proto", 113 srcs = ["foo.proto"], 114 ) 115 116 proto_library( 117 name = "dep_proto", 118 deps = [":foo_proto"], 119 ) 120 `, 121 }, { 122 desc: "index_ambiguous", 123 index: []buildFile{{ 124 rel: "foo", 125 content: ` 126 proto_library( 127 name = "a_proto", 128 srcs = ["foo.proto"], 129 ) 130 131 proto_library( 132 name = "b_proto", 133 srcs = ["foo.proto"], 134 ) 135 `, 136 }}, 137 old: ` 138 proto_library( 139 name = "dep_proto", 140 _imports = ["foo/foo.proto"], 141 ) 142 `, 143 want: `proto_library(name = "dep_proto")`, 144 }, { 145 desc: "index_self", 146 old: ` 147 proto_library( 148 name = "dep_proto", 149 srcs = ["foo.proto"], 150 _imports = ["test/foo.proto"], 151 ) 152 `, 153 want: ` 154 proto_library( 155 name = "dep_proto", 156 srcs = ["foo.proto"], 157 ) 158 `, 159 }, { 160 desc: "unknown", 161 old: ` 162 proto_library( 163 name = "dep_proto", 164 _imports = ["foo/bar/unknown.proto"], 165 ) 166 `, 167 want: ` 168 proto_library( 169 name = "dep_proto", 170 deps = ["//foo/bar:bar_proto"], 171 ) 172 `, 173 }, 174 } { 175 t.Run(tc.desc, func(t *testing.T) { 176 c := config.New() 177 c.Exts[protoName] = &ProtoConfig{} 178 lang := New() 179 ix := resolve.NewRuleIndex(map[string]resolve.Resolver{"proto_library": lang}) 180 rc := (*repos.RemoteCache)(nil) 181 for _, bf := range tc.index { 182 f, err := rule.LoadData(filepath.Join(bf.rel, "BUILD.bazel"), bf.rel, []byte(bf.content)) 183 if err != nil { 184 t.Fatal(err) 185 } 186 for _, r := range f.Rules { 187 ix.AddRule(c, r, f) 188 } 189 } 190 f, err := rule.LoadData("test/BUILD.bazel", "test", []byte(tc.old)) 191 if err != nil { 192 t.Fatal(err) 193 } 194 for _, r := range f.Rules { 195 convertImportsAttr(r) 196 ix.AddRule(c, r, f) 197 } 198 ix.Finish() 199 for _, r := range f.Rules { 200 lang.Resolve(c, ix, rc, r, label.New("", "test", r.Name())) 201 } 202 f.Sync() 203 got := strings.TrimSpace(string(bzl.Format(f.File))) 204 want := strings.TrimSpace(tc.want) 205 if got != want { 206 t.Errorf("got:\n%s\nwant:\n%s", got, want) 207 } 208 }) 209 } 210 } 211 212 func convertImportsAttr(r *rule.Rule) { 213 value := r.AttrStrings("_imports") 214 if value == nil { 215 value = []string(nil) 216 } 217 r.DelAttr("_imports") 218 r.SetPrivateAttr(config.GazelleImportsKey, value) 219 }