protobuf-go/internal/cmd/pbdump/pbdump_test.go
Joe Tsai d888139e7b internal/filedesc, internal/filetype: initial commit
The internal/fileinit package is split apart into two packages:
* internal/filedesc constructs descriptors from the raw proto.
It is very similar to the previous internal/fileinit package.
* internal/filetype wraps descriptors with Go type information

Overview:
* The internal/fileinit package will be deleted in a future CL.
It is kept around since the v1 repo currently depends on it.
* The internal/prototype package is deleted. All former usages of it
are now using internal/filedesc instead. Most significantly,
the reflect/protodesc package was almost entirely re-written.
* The internal/impl package drops support for messages that do not
have a Descriptor method (pre-2016). This removes a significant amount
of technical debt.
filedesc.Builder to parse raw descriptors.
* The internal/encoding/defval package now handles enum values by name.

Change-Id: I3957bcc8588a70470fd6c7de1122216b80615ab7
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/182360
Reviewed-by: Damien Neil <dneil@google.com>
2019-06-20 02:06:11 +00:00

116 lines
3.3 KiB
Go

// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"fmt"
"strings"
"testing"
"google.golang.org/protobuf/encoding/prototext"
"google.golang.org/protobuf/proto"
pref "google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/descriptorpb"
)
func mustMakeMessage(s string) *descriptorpb.DescriptorProto {
s = fmt.Sprintf(`name:"test.proto" syntax:"proto2" message_type:[{%s}]`, s)
pb := new(descriptorpb.FileDescriptorProto)
if err := prototext.Unmarshal([]byte(s), pb); err != nil {
panic(err)
}
return pb.MessageType[0]
}
func TestFields(t *testing.T) {
type fieldsKind struct {
kind pref.Kind
fields string
}
tests := []struct {
inFields []fieldsKind
wantMsg *descriptorpb.DescriptorProto
wantErr string
}{{
inFields: []fieldsKind{{pref.MessageKind, ""}},
wantMsg: mustMakeMessage(`name:"M"`),
}, {
inFields: []fieldsKind{{pref.MessageKind, "987654321"}},
wantErr: "invalid field: 987654321",
}, {
inFields: []fieldsKind{{pref.MessageKind, "-1"}},
wantErr: "invalid field: -1",
}, {
inFields: []fieldsKind{{pref.MessageKind, "k"}},
wantErr: "invalid field: k",
}, {
inFields: []fieldsKind{{pref.MessageKind, "1.2"}, {pref.Int32Kind, "1"}},
wantErr: "field 1 of int32 type cannot have sub-fields",
}, {
inFields: []fieldsKind{{pref.Int32Kind, "1"}, {pref.MessageKind, "1.2"}},
wantErr: "field 1 of int32 type cannot have sub-fields",
}, {
inFields: []fieldsKind{{pref.Int32Kind, "30"}, {pref.Int32Kind, "30"}},
wantErr: "field 30 already set as int32 type",
}, {
inFields: []fieldsKind{
{pref.Int32Kind, "10.20.31"},
{pref.MessageKind, " 10.20.30, 10.21 "},
{pref.GroupKind, "10"},
},
wantMsg: mustMakeMessage(`
name: "M"
field: [
{name:"f10" number:10 label:LABEL_OPTIONAL type:TYPE_GROUP type_name:".M.M10"}
]
nested_type: [{
name: "M10"
field: [
{name:"f20" number:20 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".M.M10.M20"},
{name:"f21" number:21 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".M.M10.M21"}
]
nested_type: [{
name: "M20"
field:[
{name:"f30" number:30 label:LABEL_OPTIONAL type:TYPE_MESSAGE, type_name:".M.M10.M20.M30"},
{name:"f31" number:31 label:LABEL_REPEATED type:TYPE_INT32 options:{packed:true}}
]
nested_type: [{
name: "M30"
}]
}, {
name: "M21"
}]
}]
`),
}}
for _, tt := range tests {
t.Run("", func(t *testing.T) {
var fields fields
for i, tc := range tt.inFields {
gotErr := fields.Set(tc.fields, tc.kind)
if gotErr != nil {
if tt.wantErr == "" || !strings.Contains(fmt.Sprint(gotErr), tt.wantErr) {
t.Fatalf("fields %d, Set(%q, %v) = %v, want %v", i, tc.fields, tc.kind, gotErr, tt.wantErr)
}
return
}
}
if tt.wantErr != "" {
t.Errorf("all Set calls succeeded, want %v error", tt.wantErr)
}
gotMsg := fields.messageDescriptor("M")
if !proto.Equal(gotMsg, tt.wantMsg) {
t.Errorf("messageDescriptor() mismatch:\ngot %v\nwant %v", gotMsg, tt.wantMsg)
}
if _, err := fields.Descriptor(); err != nil {
t.Errorf("Descriptor() = %v, want nil error", err)
}
})
}
}