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  }