reg/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor/registry_test.go
Jess Frazelle 843aebf2c1
update deps
Signed-off-by: Jess Frazelle <acidburn@microsoft.com>
2018-07-14 11:48:41 -04:00

589 lines
15 KiB
Go

package descriptor
import (
"testing"
"github.com/golang/protobuf/proto"
descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
)
func loadFile(t *testing.T, reg *Registry, src string) *descriptor.FileDescriptorProto {
var file descriptor.FileDescriptorProto
if err := proto.UnmarshalText(src, &file); err != nil {
t.Fatalf("proto.UnmarshalText(%s, &file) failed with %v; want success", src, err)
}
reg.loadFile(&file)
return &file
}
func load(t *testing.T, reg *Registry, src string) error {
var req plugin.CodeGeneratorRequest
if err := proto.UnmarshalText(src, &req); err != nil {
t.Fatalf("proto.UnmarshalText(%s, &file) failed with %v; want success", src, err)
}
return reg.Load(&req)
}
func TestLoadFile(t *testing.T) {
reg := NewRegistry()
fd := loadFile(t, reg, `
name: 'example.proto'
package: 'example'
message_type <
name: 'ExampleMessage'
field <
name: 'str'
label: LABEL_OPTIONAL
type: TYPE_STRING
number: 1
>
>
`)
file := reg.files["example.proto"]
if file == nil {
t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
return
}
wantPkg := GoPackage{Path: ".", Name: "example"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
msg, err := reg.LookupMsg("", ".example.ExampleMessage")
if err != nil {
t.Errorf("reg.LookupMsg(%q, %q)) failed with %v; want success", "", ".example.ExampleMessage", err)
return
}
if got, want := msg.DescriptorProto, fd.MessageType[0]; got != want {
t.Errorf("reg.lookupMsg(%q, %q).DescriptorProto = %#v; want %#v", "", ".example.ExampleMessage", got, want)
}
if got, want := msg.File, file; got != want {
t.Errorf("msg.File = %v; want %v", got, want)
}
if got := msg.Outers; got != nil {
t.Errorf("msg.Outers = %v; want %v", got, nil)
}
if got, want := len(msg.Fields), 1; got != want {
t.Errorf("len(msg.Fields) = %d; want %d", got, want)
} else if got, want := msg.Fields[0].FieldDescriptorProto, fd.MessageType[0].Field[0]; got != want {
t.Errorf("msg.Fields[0].FieldDescriptorProto = %v; want %v", got, want)
} else if got, want := msg.Fields[0].Message, msg; got != want {
t.Errorf("msg.Fields[0].Message = %v; want %v", got, want)
}
if got, want := len(file.Messages), 1; got != want {
t.Errorf("file.Meeesages = %#v; want %#v", file.Messages, []*Message{msg})
}
if got, want := file.Messages[0], msg; got != want {
t.Errorf("file.Meeesages[0] = %v; want %v", got, want)
}
}
func TestLoadFileNestedPackage(t *testing.T) {
reg := NewRegistry()
loadFile(t, reg, `
name: 'example.proto'
package: 'example.nested.nested2'
`)
file := reg.files["example.proto"]
if file == nil {
t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
return
}
wantPkg := GoPackage{Path: ".", Name: "example_nested_nested2"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
}
func TestLoadFileWithDir(t *testing.T) {
reg := NewRegistry()
loadFile(t, reg, `
name: 'path/to/example.proto'
package: 'example'
`)
file := reg.files["path/to/example.proto"]
if file == nil {
t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
return
}
wantPkg := GoPackage{Path: "path/to", Name: "example"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
}
func TestLoadFileWithoutPackage(t *testing.T) {
reg := NewRegistry()
loadFile(t, reg, `
name: 'path/to/example_file.proto'
`)
file := reg.files["path/to/example_file.proto"]
if file == nil {
t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
return
}
wantPkg := GoPackage{Path: "path/to", Name: "example_file"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
}
func TestLoadFileWithMapping(t *testing.T) {
reg := NewRegistry()
reg.AddPkgMap("path/to/example.proto", "example.com/proj/example/proto")
loadFile(t, reg, `
name: 'path/to/example.proto'
package: 'example'
`)
file := reg.files["path/to/example.proto"]
if file == nil {
t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
return
}
wantPkg := GoPackage{Path: "example.com/proj/example/proto", Name: "example"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
}
func TestLoadFileWithPackageNameCollision(t *testing.T) {
reg := NewRegistry()
loadFile(t, reg, `
name: 'path/to/another.proto'
package: 'example'
`)
loadFile(t, reg, `
name: 'path/to/example.proto'
package: 'example'
`)
if err := reg.ReserveGoPackageAlias("ioutil", "io/ioutil"); err != nil {
t.Fatalf("reg.ReserveGoPackageAlias(%q) failed with %v; want success", "ioutil", err)
}
loadFile(t, reg, `
name: 'path/to/ioutil.proto'
package: 'ioutil'
`)
file := reg.files["path/to/another.proto"]
if file == nil {
t.Errorf("reg.files[%q] = nil; want non-nil", "path/to/another.proto")
return
}
wantPkg := GoPackage{Path: "path/to", Name: "example"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
file = reg.files["path/to/example.proto"]
if file == nil {
t.Errorf("reg.files[%q] = nil; want non-nil", "path/to/example.proto")
return
}
wantPkg = GoPackage{Path: "path/to", Name: "example", Alias: ""}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
file = reg.files["path/to/ioutil.proto"]
if file == nil {
t.Errorf("reg.files[%q] = nil; want non-nil", "path/to/ioutil.proto")
return
}
wantPkg = GoPackage{Path: "path/to", Name: "ioutil", Alias: "ioutil_0"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
}
func TestLoadFileWithIdenticalGoPkg(t *testing.T) {
reg := NewRegistry()
reg.AddPkgMap("path/to/another.proto", "example.com/example")
reg.AddPkgMap("path/to/example.proto", "example.com/example")
loadFile(t, reg, `
name: 'path/to/another.proto'
package: 'example'
`)
loadFile(t, reg, `
name: 'path/to/example.proto'
package: 'example'
`)
file := reg.files["path/to/example.proto"]
if file == nil {
t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
return
}
wantPkg := GoPackage{Path: "example.com/example", Name: "example"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
file = reg.files["path/to/another.proto"]
if file == nil {
t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
return
}
wantPkg = GoPackage{Path: "example.com/example", Name: "example"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
}
func TestLoadFileWithPrefix(t *testing.T) {
reg := NewRegistry()
reg.SetPrefix("third_party")
loadFile(t, reg, `
name: 'path/to/example.proto'
package: 'example'
`)
file := reg.files["path/to/example.proto"]
if file == nil {
t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
return
}
wantPkg := GoPackage{Path: "third_party/path/to", Name: "example"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
}
func TestLookupMsgWithoutPackage(t *testing.T) {
reg := NewRegistry()
fd := loadFile(t, reg, `
name: 'example.proto'
message_type <
name: 'ExampleMessage'
field <
name: 'str'
label: LABEL_OPTIONAL
type: TYPE_STRING
number: 1
>
>
`)
msg, err := reg.LookupMsg("", ".ExampleMessage")
if err != nil {
t.Errorf("reg.LookupMsg(%q, %q)) failed with %v; want success", "", ".ExampleMessage", err)
return
}
if got, want := msg.DescriptorProto, fd.MessageType[0]; got != want {
t.Errorf("reg.lookupMsg(%q, %q).DescriptorProto = %#v; want %#v", "", ".ExampleMessage", got, want)
}
}
func TestLookupMsgWithNestedPackage(t *testing.T) {
reg := NewRegistry()
fd := loadFile(t, reg, `
name: 'example.proto'
package: 'nested.nested2.mypackage'
message_type <
name: 'ExampleMessage'
field <
name: 'str'
label: LABEL_OPTIONAL
type: TYPE_STRING
number: 1
>
>
`)
for _, name := range []string{
"nested.nested2.mypackage.ExampleMessage",
"nested2.mypackage.ExampleMessage",
"mypackage.ExampleMessage",
"ExampleMessage",
} {
msg, err := reg.LookupMsg("nested.nested2.mypackage", name)
if err != nil {
t.Errorf("reg.LookupMsg(%q, %q)) failed with %v; want success", ".nested.nested2.mypackage", name, err)
return
}
if got, want := msg.DescriptorProto, fd.MessageType[0]; got != want {
t.Errorf("reg.lookupMsg(%q, %q).DescriptorProto = %#v; want %#v", ".nested.nested2.mypackage", name, got, want)
}
}
for _, loc := range []string{
".nested.nested2.mypackage",
"nested.nested2.mypackage",
".nested.nested2",
"nested.nested2",
".nested",
"nested",
".",
"",
"somewhere.else",
} {
name := "nested.nested2.mypackage.ExampleMessage"
msg, err := reg.LookupMsg(loc, name)
if err != nil {
t.Errorf("reg.LookupMsg(%q, %q)) failed with %v; want success", loc, name, err)
return
}
if got, want := msg.DescriptorProto, fd.MessageType[0]; got != want {
t.Errorf("reg.lookupMsg(%q, %q).DescriptorProto = %#v; want %#v", loc, name, got, want)
}
}
for _, loc := range []string{
".nested.nested2.mypackage",
"nested.nested2.mypackage",
".nested.nested2",
"nested.nested2",
".nested",
"nested",
} {
name := "nested2.mypackage.ExampleMessage"
msg, err := reg.LookupMsg(loc, name)
if err != nil {
t.Errorf("reg.LookupMsg(%q, %q)) failed with %v; want success", loc, name, err)
return
}
if got, want := msg.DescriptorProto, fd.MessageType[0]; got != want {
t.Errorf("reg.lookupMsg(%q, %q).DescriptorProto = %#v; want %#v", loc, name, got, want)
}
}
}
func TestLoadWithInconsistentTargetPackage(t *testing.T) {
for _, spec := range []struct {
req string
consistent bool
}{
// root package, no explicit go package
{
req: `
file_to_generate: 'a.proto'
file_to_generate: 'b.proto'
proto_file <
name: 'a.proto'
message_type < name: 'A' >
service <
name: "AService"
method <
name: "Meth"
input_type: "A"
output_type: "A"
options <
[google.api.http] < post: "/v1/a" body: "*" >
>
>
>
>
proto_file <
name: 'b.proto'
message_type < name: 'B' >
service <
name: "BService"
method <
name: "Meth"
input_type: "B"
output_type: "B"
options <
[google.api.http] < post: "/v1/b" body: "*" >
>
>
>
>
`,
consistent: false,
},
// named package, no explicit go package
{
req: `
file_to_generate: 'a.proto'
file_to_generate: 'b.proto'
proto_file <
name: 'a.proto'
package: 'example.foo'
message_type < name: 'A' >
service <
name: "AService"
method <
name: "Meth"
input_type: "A"
output_type: "A"
options <
[google.api.http] < post: "/v1/a" body: "*" >
>
>
>
>
proto_file <
name: 'b.proto'
package: 'example.foo'
message_type < name: 'B' >
service <
name: "BService"
method <
name: "Meth"
input_type: "B"
output_type: "B"
options <
[google.api.http] < post: "/v1/b" body: "*" >
>
>
>
>
`,
consistent: true,
},
// root package, explicit go package
{
req: `
file_to_generate: 'a.proto'
file_to_generate: 'b.proto'
proto_file <
name: 'a.proto'
options < go_package: 'foo' >
message_type < name: 'A' >
service <
name: "AService"
method <
name: "Meth"
input_type: "A"
output_type: "A"
options <
[google.api.http] < post: "/v1/a" body: "*" >
>
>
>
>
proto_file <
name: 'b.proto'
options < go_package: 'foo' >
message_type < name: 'B' >
service <
name: "BService"
method <
name: "Meth"
input_type: "B"
output_type: "B"
options <
[google.api.http] < post: "/v1/b" body: "*" >
>
>
>
>
`,
consistent: true,
},
// named package, explicit go package
{
req: `
file_to_generate: 'a.proto'
file_to_generate: 'b.proto'
proto_file <
name: 'a.proto'
package: 'example.foo'
options < go_package: 'foo' >
message_type < name: 'A' >
service <
name: "AService"
method <
name: "Meth"
input_type: "A"
output_type: "A"
options <
[google.api.http] < post: "/v1/a" body: "*" >
>
>
>
>
proto_file <
name: 'b.proto'
package: 'example.foo'
options < go_package: 'foo' >
message_type < name: 'B' >
service <
name: "BService"
method <
name: "Meth"
input_type: "B"
output_type: "B"
options <
[google.api.http] < post: "/v1/b" body: "*" >
>
>
>
>
`,
consistent: true,
},
} {
reg := NewRegistry()
err := load(t, reg, spec.req)
if got, want := err == nil, spec.consistent; got != want {
if want {
t.Errorf("reg.Load(%s) failed with %v; want success", spec.req, err)
continue
}
t.Errorf("reg.Load(%s) succeeded; want an package inconsistency error", spec.req)
}
}
}
func TestLoadOverridedPackageName(t *testing.T) {
reg := NewRegistry()
loadFile(t, reg, `
name: 'example.proto'
package: 'example'
options < go_package: 'example.com/xyz;pb' >
`)
file := reg.files["example.proto"]
if file == nil {
t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
return
}
wantPkg := GoPackage{Path: "example.com/xyz", Name: "pb"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
}
func TestLoadSetInputPath(t *testing.T) {
reg := NewRegistry()
reg.SetImportPath("foo/examplepb")
loadFile(t, reg, `
name: 'example.proto'
package: 'example'
`)
file := reg.files["example.proto"]
if file == nil {
t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
return
}
wantPkg := GoPackage{Path: ".", Name: "examplepb"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
}
func TestLoadGoPackageInputPath(t *testing.T) {
reg := NewRegistry()
reg.SetImportPath("examplepb")
loadFile(t, reg, `
name: 'example.proto'
package: 'example'
options < go_package: 'example.com/xyz;pb' >
`)
file := reg.files["example.proto"]
if file == nil {
t.Errorf("reg.files[%q] = nil; want non-nil", "example.proto")
return
}
wantPkg := GoPackage{Path: "example.com/xyz", Name: "pb"}
if got, want := file.GoPkg, wantPkg; got != want {
t.Errorf("file.GoPkg = %#v; want %#v", got, want)
}
}