github.com/stackb/rules_proto@v0.0.0-20240221195024-5428336c51f1/pkg/language/protobuf/override_test.go (about)

     1  package protobuf
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/bazelbuild/bazel-gazelle/config"
     7  	"github.com/bazelbuild/bazel-gazelle/label"
     8  	"github.com/bazelbuild/bazel-gazelle/rule"
     9  	"github.com/google/go-cmp/cmp"
    10  
    11  	"github.com/stackb/rules_proto/pkg/protoc"
    12  )
    13  
    14  // TestOverrideRule demonstrates the shape of an override rule: as a carrier for
    15  // ProtoLibrary instances in a PrivateAttr.  The proto_library rules inside it
    16  // might have go_googleapis deps that we want to scrub out and replace with
    17  // locally-resolved ones.  This is to get around gazelle's hardcoded resolver
    18  // strategy for these labels.
    19  func TestOverrideRule(t *testing.T) {
    20  	// rel is the package path.  deps are the input deps on the proto_library
    21  	// rule. imps are the imports of that proto_library rule's file(s). want are
    22  	// the expected deps on the rule.  resolve is mapping from the imp to a
    23  	// label.
    24  	for name, tc := range map[string]struct {
    25  		rel              string
    26  		deps, imps, want []string
    27  		known            map[string]label.Label
    28  	}{
    29  		"has go_googleapis dep": {
    30  			rel: "",
    31  			deps: []string{
    32  				"@com_google_protobuf//:any_proto",
    33  				"@go_googleapis//google/api:api_proto",
    34  			},
    35  			want: []string{
    36  				"//google/api:http_proto",
    37  				"@protoapis//google/protobuf:any_proto",
    38  			},
    39  			imps: []string{
    40  				"google/protobuf/any.proto",
    41  				"google/api/http.proto",
    42  			},
    43  			known: map[string]label.Label{
    44  				"google/protobuf/any.proto": label.New("protoapis", "google/protobuf", "any_proto"),
    45  				"google/api/http.proto":     label.New("", "google/api", "http_proto"),
    46  			},
    47  		},
    48  	} {
    49  		t.Run(name, func(t *testing.T) {
    50  			resolver := protoc.NewImportResolver(&protoc.ImportResolverOptions{
    51  				Printf: t.Logf,
    52  				Debug:  true,
    53  			})
    54  			for k, v := range tc.known {
    55  				resolver.Provide("proto", "proto", k, v)
    56  			}
    57  			c := config.New()
    58  			r := makeProtoLibraryRule("test_proto", tc.deps, tc.imps)
    59  			lib := makeOtherProtoLibrary(r)
    60  			overrideRule := makeProtoOverrideRule([]protoc.ProtoLibrary{lib})
    61  			resolveOverrideRule(c, tc.rel, overrideRule, resolver)
    62  
    63  			got := r.AttrStrings("deps")
    64  			if diff := cmp.Diff(tc.want, got); diff != "" {
    65  				t.Errorf("resolverOverrideRule() mismatch (-want +got):\n%s", diff)
    66  			}
    67  		})
    68  	}
    69  }
    70  
    71  func makeProtoLibraryRule(name string, deps, imps []string) *rule.Rule {
    72  	r := rule.NewRule("proto_library", name)
    73  	r.SetAttr("deps", deps)
    74  	r.SetPrivateAttr(config.GazelleImportsKey, imps)
    75  	return r
    76  }
    77  
    78  func makeOtherProtoLibrary(r *rule.Rule) protoc.ProtoLibrary {
    79  	f := rule.EmptyFile("", "")
    80  	return protoc.NewOtherProtoLibrary(f, r)
    81  }