equal_test.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. // Copyright 2019 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. package proto_test
  5. import (
  6. "math"
  7. "testing"
  8. "google.golang.org/protobuf/internal/encoding/pack"
  9. "google.golang.org/protobuf/proto"
  10. testpb "google.golang.org/protobuf/internal/testprotos/test"
  11. test3pb "google.golang.org/protobuf/internal/testprotos/test3"
  12. )
  13. func TestEqual(t *testing.T) {
  14. tests := []struct {
  15. x, y proto.Message
  16. eq bool
  17. }{
  18. {
  19. x: nil,
  20. y: nil,
  21. eq: true,
  22. }, {
  23. x: (*testpb.TestAllTypes)(nil),
  24. y: nil,
  25. eq: false,
  26. }, {
  27. x: (*testpb.TestAllTypes)(nil),
  28. y: new(testpb.TestAllTypes),
  29. eq: true,
  30. },
  31. // Proto2 scalars.
  32. {
  33. x: &testpb.TestAllTypes{OptionalInt32: proto.Int32(1)},
  34. y: &testpb.TestAllTypes{OptionalInt32: proto.Int32(2)},
  35. }, {
  36. x: &testpb.TestAllTypes{OptionalInt64: proto.Int64(1)},
  37. y: &testpb.TestAllTypes{OptionalInt64: proto.Int64(2)},
  38. }, {
  39. x: &testpb.TestAllTypes{OptionalUint32: proto.Uint32(1)},
  40. y: &testpb.TestAllTypes{OptionalUint32: proto.Uint32(2)},
  41. }, {
  42. x: &testpb.TestAllTypes{OptionalUint64: proto.Uint64(1)},
  43. y: &testpb.TestAllTypes{OptionalUint64: proto.Uint64(2)},
  44. }, {
  45. x: &testpb.TestAllTypes{OptionalSint32: proto.Int32(1)},
  46. y: &testpb.TestAllTypes{OptionalSint32: proto.Int32(2)},
  47. }, {
  48. x: &testpb.TestAllTypes{OptionalSint64: proto.Int64(1)},
  49. y: &testpb.TestAllTypes{OptionalSint64: proto.Int64(2)},
  50. }, {
  51. x: &testpb.TestAllTypes{OptionalFixed32: proto.Uint32(1)},
  52. y: &testpb.TestAllTypes{OptionalFixed32: proto.Uint32(2)},
  53. }, {
  54. x: &testpb.TestAllTypes{OptionalFixed64: proto.Uint64(1)},
  55. y: &testpb.TestAllTypes{OptionalFixed64: proto.Uint64(2)},
  56. }, {
  57. x: &testpb.TestAllTypes{OptionalSfixed32: proto.Int32(1)},
  58. y: &testpb.TestAllTypes{OptionalSfixed32: proto.Int32(2)},
  59. }, {
  60. x: &testpb.TestAllTypes{OptionalSfixed64: proto.Int64(1)},
  61. y: &testpb.TestAllTypes{OptionalSfixed64: proto.Int64(2)},
  62. }, {
  63. x: &testpb.TestAllTypes{OptionalFloat: proto.Float32(1)},
  64. y: &testpb.TestAllTypes{OptionalFloat: proto.Float32(2)},
  65. }, {
  66. x: &testpb.TestAllTypes{OptionalDouble: proto.Float64(1)},
  67. y: &testpb.TestAllTypes{OptionalDouble: proto.Float64(2)},
  68. }, {
  69. x: &testpb.TestAllTypes{OptionalFloat: proto.Float32(float32(math.NaN()))},
  70. y: &testpb.TestAllTypes{OptionalFloat: proto.Float32(0)},
  71. }, {
  72. x: &testpb.TestAllTypes{OptionalDouble: proto.Float64(float64(math.NaN()))},
  73. y: &testpb.TestAllTypes{OptionalDouble: proto.Float64(0)},
  74. }, {
  75. x: &testpb.TestAllTypes{OptionalBool: proto.Bool(true)},
  76. y: &testpb.TestAllTypes{OptionalBool: proto.Bool(false)},
  77. }, {
  78. x: &testpb.TestAllTypes{OptionalString: proto.String("a")},
  79. y: &testpb.TestAllTypes{OptionalString: proto.String("b")},
  80. }, {
  81. x: &testpb.TestAllTypes{OptionalBytes: []byte("a")},
  82. y: &testpb.TestAllTypes{OptionalBytes: []byte("b")},
  83. }, {
  84. x: &testpb.TestAllTypes{OptionalNestedEnum: testpb.TestAllTypes_FOO.Enum()},
  85. y: &testpb.TestAllTypes{OptionalNestedEnum: testpb.TestAllTypes_BAR.Enum()},
  86. },
  87. // Proto2 presence.
  88. {
  89. x: &testpb.TestAllTypes{},
  90. y: &testpb.TestAllTypes{OptionalInt32: proto.Int32(0)},
  91. }, {
  92. x: &testpb.TestAllTypes{},
  93. y: &testpb.TestAllTypes{OptionalInt64: proto.Int64(0)},
  94. }, {
  95. x: &testpb.TestAllTypes{},
  96. y: &testpb.TestAllTypes{OptionalUint32: proto.Uint32(0)},
  97. }, {
  98. x: &testpb.TestAllTypes{},
  99. y: &testpb.TestAllTypes{OptionalUint64: proto.Uint64(0)},
  100. }, {
  101. x: &testpb.TestAllTypes{},
  102. y: &testpb.TestAllTypes{OptionalSint32: proto.Int32(0)},
  103. }, {
  104. x: &testpb.TestAllTypes{},
  105. y: &testpb.TestAllTypes{OptionalSint64: proto.Int64(0)},
  106. }, {
  107. x: &testpb.TestAllTypes{},
  108. y: &testpb.TestAllTypes{OptionalFixed32: proto.Uint32(0)},
  109. }, {
  110. x: &testpb.TestAllTypes{},
  111. y: &testpb.TestAllTypes{OptionalFixed64: proto.Uint64(0)},
  112. }, {
  113. x: &testpb.TestAllTypes{},
  114. y: &testpb.TestAllTypes{OptionalSfixed32: proto.Int32(0)},
  115. }, {
  116. x: &testpb.TestAllTypes{},
  117. y: &testpb.TestAllTypes{OptionalSfixed64: proto.Int64(0)},
  118. }, {
  119. x: &testpb.TestAllTypes{},
  120. y: &testpb.TestAllTypes{OptionalFloat: proto.Float32(0)},
  121. }, {
  122. x: &testpb.TestAllTypes{},
  123. y: &testpb.TestAllTypes{OptionalDouble: proto.Float64(0)},
  124. }, {
  125. x: &testpb.TestAllTypes{},
  126. y: &testpb.TestAllTypes{OptionalBool: proto.Bool(false)},
  127. }, {
  128. x: &testpb.TestAllTypes{},
  129. y: &testpb.TestAllTypes{OptionalString: proto.String("")},
  130. }, {
  131. x: &testpb.TestAllTypes{},
  132. y: &testpb.TestAllTypes{OptionalBytes: []byte{}},
  133. }, {
  134. x: &testpb.TestAllTypes{},
  135. y: &testpb.TestAllTypes{OptionalNestedEnum: testpb.TestAllTypes_FOO.Enum()},
  136. },
  137. // Proto2 default values are not considered by Equal, so the following are still unequal.
  138. {
  139. x: &testpb.TestAllTypes{DefaultInt32: proto.Int32(81)},
  140. y: &testpb.TestAllTypes{},
  141. }, {
  142. x: &testpb.TestAllTypes{},
  143. y: &testpb.TestAllTypes{DefaultInt32: proto.Int32(81)},
  144. }, {
  145. x: &testpb.TestAllTypes{},
  146. y: &testpb.TestAllTypes{DefaultInt64: proto.Int64(82)},
  147. }, {
  148. x: &testpb.TestAllTypes{},
  149. y: &testpb.TestAllTypes{DefaultUint32: proto.Uint32(83)},
  150. }, {
  151. x: &testpb.TestAllTypes{},
  152. y: &testpb.TestAllTypes{DefaultUint64: proto.Uint64(84)},
  153. }, {
  154. x: &testpb.TestAllTypes{},
  155. y: &testpb.TestAllTypes{DefaultSint32: proto.Int32(-85)},
  156. }, {
  157. x: &testpb.TestAllTypes{},
  158. y: &testpb.TestAllTypes{DefaultSint64: proto.Int64(86)},
  159. }, {
  160. x: &testpb.TestAllTypes{},
  161. y: &testpb.TestAllTypes{DefaultFixed32: proto.Uint32(87)},
  162. }, {
  163. x: &testpb.TestAllTypes{},
  164. y: &testpb.TestAllTypes{DefaultFixed64: proto.Uint64(88)},
  165. }, {
  166. x: &testpb.TestAllTypes{},
  167. y: &testpb.TestAllTypes{DefaultSfixed32: proto.Int32(89)},
  168. }, {
  169. x: &testpb.TestAllTypes{},
  170. y: &testpb.TestAllTypes{DefaultSfixed64: proto.Int64(-90)},
  171. }, {
  172. x: &testpb.TestAllTypes{},
  173. y: &testpb.TestAllTypes{DefaultFloat: proto.Float32(91.5)},
  174. }, {
  175. x: &testpb.TestAllTypes{},
  176. y: &testpb.TestAllTypes{DefaultDouble: proto.Float64(92e3)},
  177. }, {
  178. x: &testpb.TestAllTypes{},
  179. y: &testpb.TestAllTypes{DefaultBool: proto.Bool(true)},
  180. }, {
  181. x: &testpb.TestAllTypes{},
  182. y: &testpb.TestAllTypes{DefaultString: proto.String("hello")},
  183. }, {
  184. x: &testpb.TestAllTypes{},
  185. y: &testpb.TestAllTypes{DefaultBytes: []byte("world")},
  186. }, {
  187. x: &testpb.TestAllTypes{},
  188. y: &testpb.TestAllTypes{DefaultNestedEnum: testpb.TestAllTypes_BAR.Enum()},
  189. },
  190. // Groups.
  191. {
  192. x: &testpb.TestAllTypes{Optionalgroup: &testpb.TestAllTypes_OptionalGroup{
  193. A: proto.Int32(1),
  194. }},
  195. y: &testpb.TestAllTypes{Optionalgroup: &testpb.TestAllTypes_OptionalGroup{
  196. A: proto.Int32(2),
  197. }},
  198. }, {
  199. x: &testpb.TestAllTypes{},
  200. y: &testpb.TestAllTypes{Optionalgroup: &testpb.TestAllTypes_OptionalGroup{}},
  201. },
  202. // Messages.
  203. {
  204. x: &testpb.TestAllTypes{OptionalNestedMessage: &testpb.TestAllTypes_NestedMessage{
  205. A: proto.Int32(1),
  206. }},
  207. y: &testpb.TestAllTypes{OptionalNestedMessage: &testpb.TestAllTypes_NestedMessage{
  208. A: proto.Int32(2),
  209. }},
  210. }, {
  211. x: &testpb.TestAllTypes{},
  212. y: &testpb.TestAllTypes{OptionalNestedMessage: &testpb.TestAllTypes_NestedMessage{}},
  213. }, {
  214. x: &test3pb.TestAllTypes{},
  215. y: &test3pb.TestAllTypes{OptionalNestedMessage: &test3pb.TestAllTypes_NestedMessage{}},
  216. },
  217. // Lists.
  218. {
  219. x: &testpb.TestAllTypes{RepeatedInt32: []int32{1}},
  220. y: &testpb.TestAllTypes{RepeatedInt32: []int32{1, 2}},
  221. }, {
  222. x: &testpb.TestAllTypes{RepeatedInt32: []int32{1, 2}},
  223. y: &testpb.TestAllTypes{RepeatedInt32: []int32{1, 3}},
  224. }, {
  225. x: &testpb.TestAllTypes{RepeatedInt64: []int64{1, 2}},
  226. y: &testpb.TestAllTypes{RepeatedInt64: []int64{1, 3}},
  227. }, {
  228. x: &testpb.TestAllTypes{RepeatedUint32: []uint32{1, 2}},
  229. y: &testpb.TestAllTypes{RepeatedUint32: []uint32{1, 3}},
  230. }, {
  231. x: &testpb.TestAllTypes{RepeatedUint64: []uint64{1, 2}},
  232. y: &testpb.TestAllTypes{RepeatedUint64: []uint64{1, 3}},
  233. }, {
  234. x: &testpb.TestAllTypes{RepeatedSint32: []int32{1, 2}},
  235. y: &testpb.TestAllTypes{RepeatedSint32: []int32{1, 3}},
  236. }, {
  237. x: &testpb.TestAllTypes{RepeatedSint64: []int64{1, 2}},
  238. y: &testpb.TestAllTypes{RepeatedSint64: []int64{1, 3}},
  239. }, {
  240. x: &testpb.TestAllTypes{RepeatedFixed32: []uint32{1, 2}},
  241. y: &testpb.TestAllTypes{RepeatedFixed32: []uint32{1, 3}},
  242. }, {
  243. x: &testpb.TestAllTypes{RepeatedFixed64: []uint64{1, 2}},
  244. y: &testpb.TestAllTypes{RepeatedFixed64: []uint64{1, 3}},
  245. }, {
  246. x: &testpb.TestAllTypes{RepeatedSfixed32: []int32{1, 2}},
  247. y: &testpb.TestAllTypes{RepeatedSfixed32: []int32{1, 3}},
  248. }, {
  249. x: &testpb.TestAllTypes{RepeatedSfixed64: []int64{1, 2}},
  250. y: &testpb.TestAllTypes{RepeatedSfixed64: []int64{1, 3}},
  251. }, {
  252. x: &testpb.TestAllTypes{RepeatedFloat: []float32{1, 2}},
  253. y: &testpb.TestAllTypes{RepeatedFloat: []float32{1, 3}},
  254. }, {
  255. x: &testpb.TestAllTypes{RepeatedDouble: []float64{1, 2}},
  256. y: &testpb.TestAllTypes{RepeatedDouble: []float64{1, 3}},
  257. }, {
  258. x: &testpb.TestAllTypes{RepeatedBool: []bool{true, false}},
  259. y: &testpb.TestAllTypes{RepeatedBool: []bool{true, true}},
  260. }, {
  261. x: &testpb.TestAllTypes{RepeatedString: []string{"a", "b"}},
  262. y: &testpb.TestAllTypes{RepeatedString: []string{"a", "c"}},
  263. }, {
  264. x: &testpb.TestAllTypes{RepeatedBytes: [][]byte{[]byte("a"), []byte("b")}},
  265. y: &testpb.TestAllTypes{RepeatedBytes: [][]byte{[]byte("a"), []byte("c")}},
  266. }, {
  267. x: &testpb.TestAllTypes{RepeatedNestedEnum: []testpb.TestAllTypes_NestedEnum{testpb.TestAllTypes_FOO}},
  268. y: &testpb.TestAllTypes{RepeatedNestedEnum: []testpb.TestAllTypes_NestedEnum{testpb.TestAllTypes_BAR}},
  269. }, {
  270. x: &testpb.TestAllTypes{Repeatedgroup: []*testpb.TestAllTypes_RepeatedGroup{
  271. {A: proto.Int32(1)},
  272. {A: proto.Int32(2)},
  273. }},
  274. y: &testpb.TestAllTypes{Repeatedgroup: []*testpb.TestAllTypes_RepeatedGroup{
  275. {A: proto.Int32(1)},
  276. {A: proto.Int32(3)},
  277. }},
  278. }, {
  279. x: &testpb.TestAllTypes{RepeatedNestedMessage: []*testpb.TestAllTypes_NestedMessage{
  280. {A: proto.Int32(1)},
  281. {A: proto.Int32(2)},
  282. }},
  283. y: &testpb.TestAllTypes{RepeatedNestedMessage: []*testpb.TestAllTypes_NestedMessage{
  284. {A: proto.Int32(1)},
  285. {A: proto.Int32(3)},
  286. }},
  287. },
  288. // Maps: various configurations.
  289. {
  290. x: &testpb.TestAllTypes{MapInt32Int32: map[int32]int32{1: 2}},
  291. y: &testpb.TestAllTypes{MapInt32Int32: map[int32]int32{3: 4}},
  292. }, {
  293. x: &testpb.TestAllTypes{MapInt32Int32: map[int32]int32{1: 2}},
  294. y: &testpb.TestAllTypes{MapInt32Int32: map[int32]int32{1: 2, 3: 4}},
  295. }, {
  296. x: &testpb.TestAllTypes{MapInt32Int32: map[int32]int32{1: 2, 3: 4}},
  297. y: &testpb.TestAllTypes{MapInt32Int32: map[int32]int32{1: 2}},
  298. },
  299. // Maps: various types.
  300. {
  301. x: &testpb.TestAllTypes{MapInt32Int32: map[int32]int32{1: 2, 3: 4}},
  302. y: &testpb.TestAllTypes{MapInt32Int32: map[int32]int32{1: 2, 3: 5}},
  303. }, {
  304. x: &testpb.TestAllTypes{MapInt64Int64: map[int64]int64{1: 2, 3: 4}},
  305. y: &testpb.TestAllTypes{MapInt64Int64: map[int64]int64{1: 2, 3: 5}},
  306. }, {
  307. x: &testpb.TestAllTypes{MapUint32Uint32: map[uint32]uint32{1: 2, 3: 4}},
  308. y: &testpb.TestAllTypes{MapUint32Uint32: map[uint32]uint32{1: 2, 3: 5}},
  309. }, {
  310. x: &testpb.TestAllTypes{MapUint64Uint64: map[uint64]uint64{1: 2, 3: 4}},
  311. y: &testpb.TestAllTypes{MapUint64Uint64: map[uint64]uint64{1: 2, 3: 5}},
  312. }, {
  313. x: &testpb.TestAllTypes{MapSint32Sint32: map[int32]int32{1: 2, 3: 4}},
  314. y: &testpb.TestAllTypes{MapSint32Sint32: map[int32]int32{1: 2, 3: 5}},
  315. }, {
  316. x: &testpb.TestAllTypes{MapSint64Sint64: map[int64]int64{1: 2, 3: 4}},
  317. y: &testpb.TestAllTypes{MapSint64Sint64: map[int64]int64{1: 2, 3: 5}},
  318. }, {
  319. x: &testpb.TestAllTypes{MapFixed32Fixed32: map[uint32]uint32{1: 2, 3: 4}},
  320. y: &testpb.TestAllTypes{MapFixed32Fixed32: map[uint32]uint32{1: 2, 3: 5}},
  321. }, {
  322. x: &testpb.TestAllTypes{MapFixed64Fixed64: map[uint64]uint64{1: 2, 3: 4}},
  323. y: &testpb.TestAllTypes{MapFixed64Fixed64: map[uint64]uint64{1: 2, 3: 5}},
  324. }, {
  325. x: &testpb.TestAllTypes{MapSfixed32Sfixed32: map[int32]int32{1: 2, 3: 4}},
  326. y: &testpb.TestAllTypes{MapSfixed32Sfixed32: map[int32]int32{1: 2, 3: 5}},
  327. }, {
  328. x: &testpb.TestAllTypes{MapSfixed64Sfixed64: map[int64]int64{1: 2, 3: 4}},
  329. y: &testpb.TestAllTypes{MapSfixed64Sfixed64: map[int64]int64{1: 2, 3: 5}},
  330. }, {
  331. x: &testpb.TestAllTypes{MapInt32Float: map[int32]float32{1: 2, 3: 4}},
  332. y: &testpb.TestAllTypes{MapInt32Float: map[int32]float32{1: 2, 3: 5}},
  333. }, {
  334. x: &testpb.TestAllTypes{MapInt32Double: map[int32]float64{1: 2, 3: 4}},
  335. y: &testpb.TestAllTypes{MapInt32Double: map[int32]float64{1: 2, 3: 5}},
  336. }, {
  337. x: &testpb.TestAllTypes{MapBoolBool: map[bool]bool{true: false, false: true}},
  338. y: &testpb.TestAllTypes{MapBoolBool: map[bool]bool{true: false, false: false}},
  339. }, {
  340. x: &testpb.TestAllTypes{MapStringString: map[string]string{"a": "b", "c": "d"}},
  341. y: &testpb.TestAllTypes{MapStringString: map[string]string{"a": "b", "c": "e"}},
  342. }, {
  343. x: &testpb.TestAllTypes{MapStringBytes: map[string][]byte{"a": []byte("b"), "c": []byte("d")}},
  344. y: &testpb.TestAllTypes{MapStringBytes: map[string][]byte{"a": []byte("b"), "c": []byte("e")}},
  345. }, {
  346. x: &testpb.TestAllTypes{MapStringNestedMessage: map[string]*testpb.TestAllTypes_NestedMessage{
  347. "a": {A: proto.Int32(1)},
  348. "b": {A: proto.Int32(2)},
  349. }},
  350. y: &testpb.TestAllTypes{MapStringNestedMessage: map[string]*testpb.TestAllTypes_NestedMessage{
  351. "a": {A: proto.Int32(1)},
  352. "b": {A: proto.Int32(3)},
  353. }},
  354. }, {
  355. x: &testpb.TestAllTypes{MapStringNestedEnum: map[string]testpb.TestAllTypes_NestedEnum{
  356. "a": testpb.TestAllTypes_FOO,
  357. "b": testpb.TestAllTypes_BAR,
  358. }},
  359. y: &testpb.TestAllTypes{MapStringNestedEnum: map[string]testpb.TestAllTypes_NestedEnum{
  360. "a": testpb.TestAllTypes_FOO,
  361. "b": testpb.TestAllTypes_BAZ,
  362. }},
  363. },
  364. // Extensions.
  365. {
  366. x: build(&testpb.TestAllExtensions{},
  367. extend(testpb.E_OptionalInt32Extension, int32(1)),
  368. ),
  369. y: build(&testpb.TestAllExtensions{},
  370. extend(testpb.E_OptionalInt32Extension, int32(2)),
  371. ),
  372. }, {
  373. x: &testpb.TestAllExtensions{},
  374. y: build(&testpb.TestAllExtensions{},
  375. extend(testpb.E_OptionalInt32Extension, int32(2)),
  376. ),
  377. },
  378. // Unknown fields.
  379. {
  380. x: build(&testpb.TestAllTypes{}, unknown(pack.Message{
  381. pack.Tag{100000, pack.VarintType}, pack.Varint(1),
  382. }.Marshal())),
  383. y: build(&testpb.TestAllTypes{}, unknown(pack.Message{
  384. pack.Tag{100000, pack.VarintType}, pack.Varint(2),
  385. }.Marshal())),
  386. }, {
  387. x: build(&testpb.TestAllTypes{}, unknown(pack.Message{
  388. pack.Tag{100000, pack.VarintType}, pack.Varint(1),
  389. }.Marshal())),
  390. y: &testpb.TestAllTypes{},
  391. },
  392. }
  393. for _, tt := range tests {
  394. if !tt.eq && !proto.Equal(tt.x, tt.x) {
  395. t.Errorf("Equal(x, x) = false, want true\n==== x ====\n%v", marshalText(tt.x))
  396. }
  397. if !tt.eq && !proto.Equal(tt.y, tt.y) {
  398. t.Errorf("Equal(y, y) = false, want true\n==== y ====\n%v", marshalText(tt.y))
  399. }
  400. if eq := proto.Equal(tt.x, tt.y); eq != tt.eq {
  401. t.Errorf("Equal(x, y) = %v, want %v\n==== x ====\n%v==== y ====\n%v", eq, tt.eq, marshalText(tt.x), marshalText(tt.y))
  402. }
  403. }
  404. }