1
2
3
4
5 package proto_test
6
7 import (
8 "testing"
9
10 "github.com/golang/protobuf/proto"
11
12 pb2 "github.com/golang/protobuf/internal/testprotos/proto2_proto"
13 pb3 "github.com/golang/protobuf/internal/testprotos/proto3_proto"
14 )
15
16
17
18 var messageWithoutExtension = &pb2.MyMessage{Count: proto.Int32(7)}
19 var messageWithExtension1a = &pb2.MyMessage{Count: proto.Int32(7)}
20 var messageWithExtension1b = &pb2.MyMessage{Count: proto.Int32(7)}
21 var messageWithExtension2 = &pb2.MyMessage{Count: proto.Int32(7)}
22 var messageWithExtension3a = &pb2.MyMessage{Count: proto.Int32(7)}
23 var messageWithExtension3b = &pb2.MyMessage{Count: proto.Int32(7)}
24 var messageWithExtension3c = &pb2.MyMessage{Count: proto.Int32(7)}
25
26
27 var messageWithInt32Extension1 = &pb2.MyMessage{Count: proto.Int32(8)}
28 var messageWithInt32Extension2 = &pb2.MyMessage{Count: proto.Int32(8)}
29
30 func init() {
31 ext1 := &pb2.Ext{Data: proto.String("Kirk")}
32 ext2 := &pb2.Ext{Data: proto.String("Picard")}
33
34
35 if err := proto.SetExtension(messageWithExtension1a, pb2.E_Ext_More, ext1); err != nil {
36 panic("proto.SetExtension on 1a failed: " + err.Error())
37 }
38
39
40 if err := proto.SetExtension(messageWithExtension1b, pb2.E_Ext_More, ext1); err != nil {
41 panic("proto.SetExtension on 1b failed: " + err.Error())
42 }
43 buf, err := proto.Marshal(messageWithExtension1b)
44 if err != nil {
45 panic("proto.Marshal of 1b failed: " + err.Error())
46 }
47 messageWithExtension1b.Reset()
48 if err := proto.Unmarshal(buf, messageWithExtension1b); err != nil {
49 panic("proto.Unmarshal of 1b failed: " + err.Error())
50 }
51
52
53 if err := proto.SetExtension(messageWithExtension2, pb2.E_Ext_More, ext2); err != nil {
54 panic("proto.SetExtension on 2 failed: " + err.Error())
55 }
56
57 if err := proto.SetExtension(messageWithInt32Extension1, pb2.E_Ext_Number, proto.Int32(23)); err != nil {
58 panic("proto.SetExtension on Int32-1 failed: " + err.Error())
59 }
60 if err := proto.SetExtension(messageWithInt32Extension1, pb2.E_Ext_Number, proto.Int32(24)); err != nil {
61 panic("proto.SetExtension on Int32-2 failed: " + err.Error())
62 }
63
64
65 if proto.RegisteredExtensions(messageWithExtension3a)[200] != nil {
66 panic("expect extension 200 unregistered")
67 }
68 bytes := []byte{
69 0xc0, 0x0c, 0x01,
70 }
71 bytes2 := []byte{
72 0xc0, 0x0c, 0x02,
73 }
74 proto.SetRawExtension(messageWithExtension3a, 200, bytes)
75 proto.SetRawExtension(messageWithExtension3b, 200, bytes)
76 proto.SetRawExtension(messageWithExtension3c, 200, bytes2)
77 }
78
79 var EqualTests = []struct {
80 desc string
81 a, b proto.Message
82 exp bool
83 }{
84 {"different types", &pb2.GoEnum{}, &pb2.GoTestField{}, false},
85 {"equal empty", &pb2.GoEnum{}, &pb2.GoEnum{}, true},
86 {"nil vs nil", nil, nil, true},
87 {"typed nil vs typed nil", (*pb2.GoEnum)(nil), (*pb2.GoEnum)(nil), true},
88 {"typed nil vs empty", (*pb2.GoEnum)(nil), &pb2.GoEnum{}, false},
89 {"different typed nil", (*pb2.GoEnum)(nil), (*pb2.GoTestField)(nil), false},
90
91 {"one set field, one unset field", &pb2.GoTestField{Label: proto.String("foo")}, &pb2.GoTestField{}, false},
92 {"one set field zero, one unset field", &pb2.GoTest{Param: proto.Int32(0)}, &pb2.GoTest{}, false},
93 {"different set fields", &pb2.GoTestField{Label: proto.String("foo")}, &pb2.GoTestField{Label: proto.String("bar")}, false},
94 {"equal set", &pb2.GoTestField{Label: proto.String("foo")}, &pb2.GoTestField{Label: proto.String("foo")}, true},
95
96 {"repeated, one set", &pb2.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb2.GoTest{}, false},
97 {"repeated, different length", &pb2.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb2.GoTest{F_Int32Repeated: []int32{2}}, false},
98 {"repeated, different value", &pb2.GoTest{F_Int32Repeated: []int32{2}}, &pb2.GoTest{F_Int32Repeated: []int32{3}}, false},
99 {"repeated, equal", &pb2.GoTest{F_Int32Repeated: []int32{2, 4}}, &pb2.GoTest{F_Int32Repeated: []int32{2, 4}}, true},
100 {"repeated, nil equal nil", &pb2.GoTest{F_Int32Repeated: nil}, &pb2.GoTest{F_Int32Repeated: nil}, true},
101 {"repeated, nil equal empty", &pb2.GoTest{F_Int32Repeated: nil}, &pb2.GoTest{F_Int32Repeated: []int32{}}, true},
102 {"repeated, empty equal nil", &pb2.GoTest{F_Int32Repeated: []int32{}}, &pb2.GoTest{F_Int32Repeated: nil}, true},
103
104 {
105 "nested, different",
106 &pb2.GoTest{RequiredField: &pb2.GoTestField{Label: proto.String("foo")}},
107 &pb2.GoTest{RequiredField: &pb2.GoTestField{Label: proto.String("bar")}},
108 false,
109 },
110 {
111 "nested, equal",
112 &pb2.GoTest{RequiredField: &pb2.GoTestField{Label: proto.String("wow")}},
113 &pb2.GoTest{RequiredField: &pb2.GoTestField{Label: proto.String("wow")}},
114 true,
115 },
116
117 {"bytes", &pb2.OtherMessage{Value: []byte("foo")}, &pb2.OtherMessage{Value: []byte("foo")}, true},
118 {"bytes, empty", &pb2.OtherMessage{Value: []byte{}}, &pb2.OtherMessage{Value: []byte{}}, true},
119 {"bytes, empty vs nil", &pb2.OtherMessage{Value: []byte{}}, &pb2.OtherMessage{Value: nil}, false},
120 {
121 "repeated bytes",
122 &pb2.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}},
123 &pb2.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}},
124 true,
125 },
126
127 {"proto3 bytes, empty vs nil", &pb3.Message{Data: []byte{}}, &pb3.Message{Data: nil}, true},
128
129 {"extension vs. no extension", messageWithoutExtension, messageWithExtension1a, false},
130 {"extension vs. same extension", messageWithExtension1a, messageWithExtension1b, true},
131 {"extension vs. different extension", messageWithExtension1a, messageWithExtension2, false},
132
133 {"int32 extension vs. itself", messageWithInt32Extension1, messageWithInt32Extension1, true},
134 {"int32 extension vs. a different int32", messageWithInt32Extension1, messageWithInt32Extension2, false},
135
136 {"unregistered extension same", messageWithExtension3a, messageWithExtension3b, true},
137 {"unregistered extension different", messageWithExtension3a, messageWithExtension3c, false},
138
139 {
140 "message with group",
141 &pb2.MyMessage{
142 Count: proto.Int32(1),
143 Somegroup: &pb2.MyMessage_SomeGroup{
144 GroupField: proto.Int32(5),
145 },
146 },
147 &pb2.MyMessage{
148 Count: proto.Int32(1),
149 Somegroup: &pb2.MyMessage_SomeGroup{
150 GroupField: proto.Int32(5),
151 },
152 },
153 true,
154 },
155
156 {
157 "map same",
158 &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
159 &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
160 true,
161 },
162 {
163 "map different entry",
164 &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
165 &pb2.MessageWithMap{NameMapping: map[int32]string{2: "Rob"}},
166 false,
167 },
168 {
169 "map different key only",
170 &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
171 &pb2.MessageWithMap{NameMapping: map[int32]string{2: "Ken"}},
172 false,
173 },
174 {
175 "map different value only",
176 &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
177 &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}},
178 false,
179 },
180 {
181 "zero-length maps same",
182 &pb2.MessageWithMap{NameMapping: map[int32]string{}},
183 &pb2.MessageWithMap{NameMapping: nil},
184 true,
185 },
186 {
187 "orders in map don't matter",
188 &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken", 2: "Rob"}},
189 &pb2.MessageWithMap{NameMapping: map[int32]string{2: "Rob", 1: "Ken"}},
190 true,
191 },
192 {
193 "oneof same",
194 &pb2.Communique{Union: &pb2.Communique_Number{41}},
195 &pb2.Communique{Union: &pb2.Communique_Number{41}},
196 true,
197 },
198 {
199 "oneof one nil",
200 &pb2.Communique{Union: &pb2.Communique_Number{41}},
201 &pb2.Communique{},
202 false,
203 },
204 {
205 "oneof different",
206 &pb2.Communique{Union: &pb2.Communique_Number{41}},
207 &pb2.Communique{Union: &pb2.Communique_Name{"Bobby Tables"}},
208 false,
209 },
210 }
211
212 func TestEqual(t *testing.T) {
213 for _, tc := range EqualTests {
214 if res := proto.Equal(tc.a, tc.b); res != tc.exp {
215 t.Errorf("%v: Equal(%v, %v) = %v, want %v", tc.desc, tc.a, tc.b, res, tc.exp)
216 }
217 }
218 }
219
View as plain text