xref: /aosp_15_r20/external/golang-protobuf/internal/cmd/pbdump/pbdump_test.go (revision 1c12ee1efe575feb122dbf939ff15148a3b3e8f2)
1// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package main
6
7import (
8	"fmt"
9	"strings"
10	"testing"
11
12	"google.golang.org/protobuf/encoding/prototext"
13	"google.golang.org/protobuf/proto"
14	"google.golang.org/protobuf/reflect/protoreflect"
15
16	"google.golang.org/protobuf/types/descriptorpb"
17)
18
19func mustMakeMessage(s string) *descriptorpb.DescriptorProto {
20	s = fmt.Sprintf(`name:"test.proto" syntax:"proto2" message_type:[{%s}]`, s)
21	pb := new(descriptorpb.FileDescriptorProto)
22	if err := prototext.Unmarshal([]byte(s), pb); err != nil {
23		panic(err)
24	}
25	return pb.MessageType[0]
26}
27
28func TestFields(t *testing.T) {
29	type fieldsKind struct {
30		kind   protoreflect.Kind
31		fields string
32	}
33	tests := []struct {
34		inFields []fieldsKind
35		wantMsg  *descriptorpb.DescriptorProto
36		wantErr  string
37	}{{
38		inFields: []fieldsKind{{protoreflect.MessageKind, ""}},
39		wantMsg:  mustMakeMessage(`name:"X"`),
40	}, {
41		inFields: []fieldsKind{{protoreflect.MessageKind, "987654321"}},
42		wantErr:  "invalid field: 987654321",
43	}, {
44		inFields: []fieldsKind{{protoreflect.MessageKind, "-1"}},
45		wantErr:  "invalid field: -1",
46	}, {
47		inFields: []fieldsKind{{protoreflect.MessageKind, "k"}},
48		wantErr:  "invalid field: k",
49	}, {
50		inFields: []fieldsKind{{protoreflect.MessageKind, "1.2"}, {protoreflect.Int32Kind, "1"}},
51		wantErr:  "field 1 of int32 type cannot have sub-fields",
52	}, {
53		inFields: []fieldsKind{{protoreflect.Int32Kind, "1"}, {protoreflect.MessageKind, "1.2"}},
54		wantErr:  "field 1 of int32 type cannot have sub-fields",
55	}, {
56		inFields: []fieldsKind{{protoreflect.Int32Kind, "30"}, {protoreflect.Int32Kind, "30"}},
57		wantErr:  "field 30 already set as int32 type",
58	}, {
59		inFields: []fieldsKind{
60			{protoreflect.Int32Kind, "10.20.31"},
61			{protoreflect.MessageKind, "  10.20.30, 10.21   "},
62			{protoreflect.GroupKind, "10"},
63		},
64		wantMsg: mustMakeMessage(`
65			name: "X"
66			field: [
67				{name:"x10" number:10 label:LABEL_OPTIONAL type:TYPE_GROUP type_name:".X.X10"}
68			]
69			nested_type: [{
70				name: "X10"
71				field: [
72					{name:"x20" number:20 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".X.X10.X20"},
73					{name:"x21" number:21 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".X.X10.X21"}
74				]
75				nested_type: [{
76					name: "X20"
77					field:[
78						{name:"x30" number:30 label:LABEL_OPTIONAL type:TYPE_MESSAGE, type_name:".X.X10.X20.X30"},
79						{name:"x31" number:31 label:LABEL_REPEATED type:TYPE_INT32 options:{packed:true}}
80					]
81					nested_type: [{
82						name: "X30"
83					}]
84				}, {
85					name: "X21"
86				}]
87			}]
88		`),
89	}}
90
91	for _, tt := range tests {
92		t.Run("", func(t *testing.T) {
93			var fields fields
94			for i, tc := range tt.inFields {
95				gotErr := fields.Set(tc.fields, tc.kind)
96				if gotErr != nil {
97					if tt.wantErr == "" || !strings.Contains(fmt.Sprint(gotErr), tt.wantErr) {
98						t.Fatalf("fields %d, Set(%q, %v) = %v, want %v", i, tc.fields, tc.kind, gotErr, tt.wantErr)
99					}
100					return
101				}
102			}
103			if tt.wantErr != "" {
104				t.Errorf("all Set calls succeeded, want %v error", tt.wantErr)
105			}
106			gotMsg := fields.messageDescriptor("X")
107			if !proto.Equal(gotMsg, tt.wantMsg) {
108				t.Errorf("messageDescriptor() mismatch:\ngot  %v\nwant %v", gotMsg, tt.wantMsg)
109			}
110			if _, err := fields.Descriptor(); err != nil {
111				t.Errorf("Descriptor() = %v, want nil error", err)
112			}
113		})
114	}
115}
116