internal/cmd/pbdump: initial commit
The pbdump binary is an internal-only command line tool that is similar
to the hexdump tool in Linux, but is tailored towards the protocol buffer
wire format. This tool is not necessary for the new API, but is very useful
for debugging the wire format.
Change-Id: Ie688338d33b01aee5dd88a63606ec0ffce57741d
Reviewed-on: https://go-review.googlesource.com/129405
Reviewed-by: Herbie Ong <herbie@google.com>
diff --git a/internal/cmd/pbdump/pbdump_test.go b/internal/cmd/pbdump/pbdump_test.go
new file mode 100644
index 0000000..524a3a2
--- /dev/null
+++ b/internal/cmd/pbdump/pbdump_test.go
@@ -0,0 +1,116 @@
+// 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"
+
+ "github.com/google/go-cmp/cmp"
+ "github.com/google/go-cmp/cmp/cmpopts"
+
+ pref "google.golang.org/proto/reflect/protoreflect"
+ ptype "google.golang.org/proto/reflect/prototype"
+)
+
+func TestFields(t *testing.T) {
+ type fieldsKind struct {
+ kind pref.Kind
+ fields string
+ }
+ tests := []struct {
+ inFields []fieldsKind
+ wantMsg ptype.Message
+ wantErr string
+ }{{
+ inFields: []fieldsKind{{pref.MessageKind, ""}},
+ wantMsg: ptype.Message{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: ptype.Message{
+ Name: "M",
+ Fields: []ptype.Field{
+ {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.GroupKind, MessageType: ptype.PlaceholderMessage("M.M10")},
+ },
+ Messages: []ptype.Message{{
+ Name: "M10",
+ Fields: []ptype.Field{
+ {Name: "f20", Number: 20, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: ptype.PlaceholderMessage("M.M10.M20")},
+ {Name: "f21", Number: 21, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: ptype.PlaceholderMessage("M.M10.M21")},
+ },
+ Messages: []ptype.Message{{
+ Name: "M20",
+ Fields: []ptype.Field{
+ {Name: "f30", Number: 30, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: ptype.PlaceholderMessage("M.M10.M20.M30")},
+ {Name: "f31", Number: 31, Cardinality: pref.Repeated, IsPacked: true, Kind: pref.Int32Kind},
+ },
+ Messages: []ptype.Message{{
+ Name: "M30",
+ }},
+ }, {
+ Name: "M21",
+ }},
+ }},
+ },
+ }}
+
+ opts := cmp.Options{
+ cmp.Comparer(func(x, y pref.Descriptor) bool {
+ if x == nil || y == nil {
+ return x == nil && y == nil
+ }
+ return x.FullName() == y.FullName()
+ }),
+ cmpopts.IgnoreFields(ptype.Field{}, "Default"),
+ cmpopts.IgnoreUnexported(ptype.Message{}, ptype.Field{}),
+ }
+ 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 diff := cmp.Diff(tt.wantMsg, gotMsg, opts); diff != "" {
+ t.Errorf("messageDescriptor() mismatch (-want +got):\n%v", diff)
+ }
+ if _, err := fields.Descriptor(); err != nil {
+ t.Errorf("Descriptor() = %v, want nil error", err)
+ }
+ })
+ }
+}