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