mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-01-14 09:44:39 +00:00
496557b1d5
This is important for test coverage: the makeMessages() function is where we declare the various different test message types. Using this central function is better than explicitly having to spell out all the various cases in the test table. This CL is roughly neutral in terms of lines changed, but actually increases coverage: in the existing table, not every group of tests had coverage for all cases (proto2, proto3, editions). This was difficult to spot previously, but now the different test message types are now clearly spelled out (allTypesNoProto3). Also, the test now prints the description and message types as subtest name. This makes it easy to verify coverage by just reading the test output. Change-Id: I08f541548d087233cbb4686785c456674371c2a3 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/623115 Reviewed-by: Chressie Himpel <chressie@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
1011 lines
28 KiB
Go
1011 lines
28 KiB
Go
// Copyright 2019 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 proto_test
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"testing"
|
|
|
|
"google.golang.org/protobuf/encoding/prototext"
|
|
"google.golang.org/protobuf/internal/pragma"
|
|
"google.golang.org/protobuf/internal/protobuild"
|
|
"google.golang.org/protobuf/proto"
|
|
"google.golang.org/protobuf/testing/protopack"
|
|
|
|
testpb "google.golang.org/protobuf/internal/testprotos/test"
|
|
test3pb "google.golang.org/protobuf/internal/testprotos/test3"
|
|
testeditionspb "google.golang.org/protobuf/internal/testprotos/testeditions"
|
|
)
|
|
|
|
func TestEqual(t *testing.T) {
|
|
identicalPtrPb := &testpb.TestAllTypes{MapStringString: map[string]string{"a": "b", "c": "d"}}
|
|
|
|
type incomparableMessage struct {
|
|
*testpb.TestAllTypes
|
|
pragma.DoNotCompare
|
|
}
|
|
|
|
type test struct {
|
|
desc string
|
|
x, y proto.Message
|
|
eq bool
|
|
}
|
|
tests := []test{
|
|
{
|
|
x: nil,
|
|
y: nil,
|
|
eq: true,
|
|
}, {
|
|
x: (*testpb.TestAllTypes)(nil),
|
|
y: nil,
|
|
eq: false,
|
|
}, {
|
|
x: (*testpb.TestAllTypes)(nil),
|
|
y: (*testpb.TestAllTypes)(nil),
|
|
eq: true,
|
|
}, {
|
|
x: new(testpb.TestAllTypes),
|
|
y: (*testpb.TestAllTypes)(nil),
|
|
eq: false,
|
|
}, {
|
|
x: new(testpb.TestAllTypes),
|
|
y: new(testpb.TestAllTypes),
|
|
eq: true,
|
|
}, {
|
|
x: (*testpb.TestAllTypes)(nil),
|
|
y: (*testpb.TestAllExtensions)(nil),
|
|
eq: false,
|
|
}, {
|
|
x: (*testpb.TestAllTypes)(nil),
|
|
y: new(testpb.TestAllExtensions),
|
|
eq: false,
|
|
}, {
|
|
x: new(testpb.TestAllTypes),
|
|
y: new(testpb.TestAllExtensions),
|
|
eq: false,
|
|
},
|
|
|
|
// Identical input pointers
|
|
{
|
|
x: identicalPtrPb,
|
|
y: identicalPtrPb,
|
|
eq: true,
|
|
},
|
|
|
|
// Incomparable types. The top-level types are not actually directly
|
|
// compared (which would panic), but rather the comparison happens on the
|
|
// objects returned by ProtoReflect(). These tests are here just to ensure
|
|
// that any short-circuit checks do not accidentally try to compare
|
|
// incomparable top-level types.
|
|
{
|
|
x: incomparableMessage{TestAllTypes: identicalPtrPb},
|
|
y: incomparableMessage{TestAllTypes: identicalPtrPb},
|
|
eq: true,
|
|
},
|
|
{
|
|
x: identicalPtrPb,
|
|
y: incomparableMessage{TestAllTypes: identicalPtrPb},
|
|
eq: true,
|
|
},
|
|
{
|
|
x: identicalPtrPb,
|
|
y: &incomparableMessage{TestAllTypes: identicalPtrPb},
|
|
eq: true,
|
|
},
|
|
}
|
|
|
|
type xy struct {
|
|
X proto.Message
|
|
Y proto.Message
|
|
}
|
|
cloneAll := func(in []proto.Message) []proto.Message {
|
|
out := make([]proto.Message, len(in))
|
|
for idx, msg := range in {
|
|
out[idx] = proto.Clone(msg)
|
|
}
|
|
return out
|
|
}
|
|
makeXY := func(x protobuild.Message, y protobuild.Message, messages ...proto.Message) []xy {
|
|
xs := makeMessages(x, cloneAll(messages)...)
|
|
ys := makeMessages(y, cloneAll(messages)...)
|
|
result := make([]xy, len(xs))
|
|
for idx := range xs {
|
|
result[idx] = xy{
|
|
X: xs[idx],
|
|
Y: ys[idx],
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
makeTest := func(tmpl test, msgs []xy) []test {
|
|
result := make([]test, 0, len(msgs))
|
|
for _, msg := range msgs {
|
|
tmpl.x = msg.X
|
|
tmpl.y = msg.Y
|
|
result = append(result, tmpl)
|
|
}
|
|
return result
|
|
}
|
|
|
|
// Scalars.
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_int32": 1},
|
|
protobuild.Message{"optional_int32": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_int64": 1},
|
|
protobuild.Message{"optional_int64": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_uint32": 1},
|
|
protobuild.Message{"optional_uint32": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_uint64": 1},
|
|
protobuild.Message{"optional_uint64": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_sint32": 1},
|
|
protobuild.Message{"optional_sint32": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_sint64": 1},
|
|
protobuild.Message{"optional_sint64": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_fixed32": 1},
|
|
protobuild.Message{"optional_fixed32": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_fixed64": 1},
|
|
protobuild.Message{"optional_fixed64": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_sfixed32": 1},
|
|
protobuild.Message{"optional_sfixed32": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_sfixed64": 1},
|
|
protobuild.Message{"optional_sfixed64": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_float": 1},
|
|
protobuild.Message{"optional_float": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_double": 1},
|
|
protobuild.Message{"optional_double": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_float": math.NaN()},
|
|
protobuild.Message{"optional_float": 0},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_double": math.NaN()},
|
|
protobuild.Message{"optional_double": 0},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_bool": true},
|
|
protobuild.Message{"optional_bool": false},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_string": "a"},
|
|
protobuild.Message{"optional_string": "b"},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_bytes": []byte("a")},
|
|
protobuild.Message{"optional_bytes": []byte("b")},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Scalars"}, makeXY(
|
|
protobuild.Message{"optional_nested_enum": "FOO"},
|
|
protobuild.Message{"optional_nested_enum": "BAR"},
|
|
))...)
|
|
|
|
// Scalars (equal).
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_int32": 2},
|
|
protobuild.Message{"optional_int32": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_int64": 2},
|
|
protobuild.Message{"optional_int64": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_uint32": 2},
|
|
protobuild.Message{"optional_uint32": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_uint64": 2},
|
|
protobuild.Message{"optional_uint64": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_sint32": 2},
|
|
protobuild.Message{"optional_sint32": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_sint64": 2},
|
|
protobuild.Message{"optional_sint64": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_fixed32": 2},
|
|
protobuild.Message{"optional_fixed32": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_fixed64": 2},
|
|
protobuild.Message{"optional_fixed64": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_sfixed32": 2},
|
|
protobuild.Message{"optional_sfixed32": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_sfixed64": 2},
|
|
protobuild.Message{"optional_sfixed64": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_float": 2},
|
|
protobuild.Message{"optional_float": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_double": 2},
|
|
protobuild.Message{"optional_double": 2},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_float": math.NaN()},
|
|
protobuild.Message{"optional_float": math.NaN()},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_double": math.NaN()},
|
|
protobuild.Message{"optional_double": math.NaN()},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_bool": true},
|
|
protobuild.Message{"optional_bool": true},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_string": "abc"},
|
|
protobuild.Message{"optional_string": "abc"},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_bytes": []byte("abc")},
|
|
protobuild.Message{"optional_bytes": []byte("abc")},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{
|
|
desc: "Scalars",
|
|
eq: true,
|
|
}, makeXY(
|
|
protobuild.Message{"optional_nested_enum": "FOO"},
|
|
protobuild.Message{"optional_nested_enum": "FOO"},
|
|
))...)
|
|
|
|
// Presence.
|
|
|
|
tests = append(tests, makeTest(test{desc: "Presence"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_int32": 0},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Presence"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_int64": 0},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Presence"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_uint32": 0},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Presence"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_uint64": 0},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Presence"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_sint32": 0},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Presence"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_sint64": 0},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Presence"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_fixed32": 0},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Presence"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_fixed64": 0},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Presence"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_sfixed32": 0},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Presence"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_sfixed64": 0},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Presence"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_float": 0},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Presence"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_double": 0},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Presence"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_bool": false},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Presence"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_string": ""},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Presence"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_bytes": []byte{}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Presence"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_nested_enum": "FOO"},
|
|
))...)
|
|
|
|
// Proto2 default values are not considered by Equal, so the following are still unequal.
|
|
|
|
allTypesNoProto3 := []proto.Message{
|
|
&testpb.TestAllTypes{},
|
|
// test3pb.TestAllTypes is intentionally missing:
|
|
// proto3 does not support default values.
|
|
// proto3 does not support groups.
|
|
&testpb.TestAllExtensions{},
|
|
&testeditionspb.TestAllTypes{},
|
|
}
|
|
|
|
tests = append(tests, makeTest(test{desc: "Default"}, makeXY(
|
|
protobuild.Message{"default_int32": 81},
|
|
protobuild.Message{},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Default"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"default_int32": 81},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Default"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"default_int64": 82},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Default"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"default_uint32": 83},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Default"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"default_uint64": 84},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Default"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"default_sint32": -85},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Default"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"default_sint64": 86},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Default"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"default_fixed32": 87},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Default"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"default_fixed64": 87},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Default"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"default_sfixed32": 89},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Default"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"default_sfixed64": -90},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Default"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"default_float": 91.5},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Default"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"default_double": 92e3},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Default"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"default_bool": true},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Default"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"default_string": "hello"},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Default"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"default_bytes": []byte("world")},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Default"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"default_nested_enum": "BAR"},
|
|
&testpb.TestAllTypes{},
|
|
// test3pb.TestAllTypes is intentionally missing:
|
|
// proto3 does not support default values.
|
|
// testpb.TestAllExtensions is intentionally missing:
|
|
// extensions cannot declare nested enums.
|
|
&testeditionspb.TestAllTypes{},
|
|
))...)
|
|
|
|
// Groups.
|
|
|
|
tests = append(tests, makeTest(test{desc: "Groups"}, makeXY(
|
|
protobuild.Message{"optionalgroup": protobuild.Message{
|
|
"a": 1,
|
|
}},
|
|
protobuild.Message{"optionalgroup": protobuild.Message{
|
|
"a": 2,
|
|
}},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Groups"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optionalgroup": protobuild.Message{}},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
// Messages.
|
|
|
|
tests = append(tests, makeTest(test{desc: "Messages"}, makeXY(
|
|
protobuild.Message{"optional_nested_message": protobuild.Message{
|
|
"a": 1,
|
|
}},
|
|
protobuild.Message{"optional_nested_message": protobuild.Message{
|
|
"a": 2,
|
|
}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Messages"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_nested_message": protobuild.Message{}},
|
|
))...)
|
|
|
|
// Lists.
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_int32": []int32{1}},
|
|
protobuild.Message{"repeated_int32": []int32{1, 2}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_int32": []int32{1, 2}},
|
|
protobuild.Message{"repeated_int32": []int32{1, 3}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_int64": []int64{1, 2}},
|
|
protobuild.Message{"repeated_int64": []int64{1, 3}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_uint32": []uint32{1, 2}},
|
|
protobuild.Message{"repeated_uint32": []uint32{1, 3}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_uint64": []uint64{1, 2}},
|
|
protobuild.Message{"repeated_uint64": []uint64{1, 3}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_sint32": []int32{1, 2}},
|
|
protobuild.Message{"repeated_sint32": []int32{1, 3}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_sint64": []int64{1, 2}},
|
|
protobuild.Message{"repeated_sint64": []int64{1, 3}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_fixed32": []uint32{1, 2}},
|
|
protobuild.Message{"repeated_fixed32": []uint32{1, 3}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_fixed64": []uint64{1, 2}},
|
|
protobuild.Message{"repeated_fixed64": []uint64{1, 3}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_sfixed32": []int32{1, 2}},
|
|
protobuild.Message{"repeated_sfixed32": []int32{1, 3}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_sfixed64": []int32{1, 2}},
|
|
protobuild.Message{"repeated_sfixed64": []int32{1, 3}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_float": []float32{1, 2}},
|
|
protobuild.Message{"repeated_float": []float32{1, 3}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_double": []float64{1, 2}},
|
|
protobuild.Message{"repeated_double": []float64{1, 3}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_bool": []bool{true, false}},
|
|
protobuild.Message{"repeated_bool": []bool{true, true}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_string": []string{"a", "b"}},
|
|
protobuild.Message{"repeated_string": []string{"a", "c"}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_bytes": [][]byte{[]byte("a"), []byte("b")}},
|
|
protobuild.Message{"repeated_bytes": [][]byte{[]byte("a"), []byte("c")}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_nested_enum": []string{"FOO"}},
|
|
protobuild.Message{"repeated_nested_enum": []string{"BAR"}},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeatedgroup": []protobuild.Message{
|
|
{"a": 1},
|
|
{"a": 2},
|
|
}},
|
|
protobuild.Message{"repeatedgroup": []protobuild.Message{
|
|
{"a": 1},
|
|
{"a": 3},
|
|
}},
|
|
allTypesNoProto3...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Lists"}, makeXY(
|
|
protobuild.Message{"repeated_nested_message": []protobuild.Message{
|
|
{"a": 1},
|
|
{"a": 2},
|
|
}},
|
|
protobuild.Message{"repeated_nested_message": []protobuild.Message{
|
|
{"a": 1},
|
|
{"a": 3},
|
|
}},
|
|
))...)
|
|
|
|
// Maps: various configurations.
|
|
|
|
allTypesNoExt := []proto.Message{
|
|
&testpb.TestAllTypes{},
|
|
&test3pb.TestAllTypes{},
|
|
// TestAllExtensions is intentionally missing:
|
|
// protoc prevents adding a map field to an extension:
|
|
// Map fields are not allowed to be extensions.
|
|
&testeditionspb.TestAllTypes{},
|
|
}
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsDifferent"}, makeXY(
|
|
protobuild.Message{"map_int32_int32": map[int32]int32{1: 2}},
|
|
protobuild.Message{"map_int32_int32": map[int32]int32{3: 4}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsAdditionalY"}, makeXY(
|
|
protobuild.Message{"map_int32_int32": map[int32]int32{1: 2}},
|
|
protobuild.Message{"map_int32_int32": map[int32]int32{1: 2, 3: 4}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsAdditionalX"}, makeXY(
|
|
protobuild.Message{"map_int32_int32": map[int32]int32{1: 2, 3: 4}},
|
|
protobuild.Message{"map_int32_int32": map[int32]int32{1: 2}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
// Maps: various types.
|
|
tests = append(tests, makeTest(test{desc: "MapsTypes"}, makeXY(
|
|
protobuild.Message{"map_int32_int32": map[int32]int32{1: 2, 3: 4}},
|
|
protobuild.Message{"map_int32_int32": map[int32]int32{1: 2, 3: 5}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsTypes"}, makeXY(
|
|
protobuild.Message{"map_int64_int64": map[int64]int64{1: 2, 3: 4}},
|
|
protobuild.Message{"map_int64_int64": map[int64]int64{1: 2, 3: 5}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsTypes"}, makeXY(
|
|
protobuild.Message{"map_uint32_uint32": map[uint32]uint32{1: 2, 3: 4}},
|
|
protobuild.Message{"map_uint32_uint32": map[uint32]uint32{1: 2, 3: 5}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsTypes"}, makeXY(
|
|
protobuild.Message{"map_uint64_uint64": map[uint64]uint64{1: 2, 3: 4}},
|
|
protobuild.Message{"map_uint64_uint64": map[uint64]uint64{1: 2, 3: 5}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsTypes"}, makeXY(
|
|
protobuild.Message{"map_sint32_sint32": map[int32]int32{1: 2, 3: 4}},
|
|
protobuild.Message{"map_sint32_sint32": map[int32]int32{1: 2, 3: 5}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsTypes"}, makeXY(
|
|
protobuild.Message{"map_sint64_sint64": map[int64]int64{1: 2, 3: 4}},
|
|
protobuild.Message{"map_sint64_sint64": map[int64]int64{1: 2, 3: 5}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsTypes"}, makeXY(
|
|
protobuild.Message{"map_fixed32_fixed32": map[uint32]uint32{1: 2, 3: 4}},
|
|
protobuild.Message{"map_fixed32_fixed32": map[uint32]uint32{1: 2, 3: 5}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsTypes"}, makeXY(
|
|
protobuild.Message{"map_fixed64_fixed64": map[uint64]uint64{1: 2, 3: 4}},
|
|
protobuild.Message{"map_fixed64_fixed64": map[uint64]uint64{1: 2, 3: 5}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsTypes"}, makeXY(
|
|
protobuild.Message{"map_sfixed32_sfixed32": map[int32]int32{1: 2, 3: 4}},
|
|
protobuild.Message{"map_sfixed32_sfixed32": map[int32]int32{1: 2, 3: 5}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsTypes"}, makeXY(
|
|
protobuild.Message{"map_sfixed64_sfixed64": map[int64]int64{1: 2, 3: 4}},
|
|
protobuild.Message{"map_sfixed64_sfixed64": map[int64]int64{1: 2, 3: 5}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsTypes"}, makeXY(
|
|
protobuild.Message{"map_int32_float": map[int32]float32{1: 2, 3: 4}},
|
|
protobuild.Message{"map_int32_float": map[int32]float32{1: 2, 3: 5}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsTypes"}, makeXY(
|
|
protobuild.Message{"map_int32_double": map[int32]float64{1: 2, 3: 4}},
|
|
protobuild.Message{"map_int32_double": map[int32]float64{1: 2, 3: 5}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsTypes"}, makeXY(
|
|
protobuild.Message{"map_bool_bool": map[bool]bool{true: false, false: true}},
|
|
protobuild.Message{"map_bool_bool": map[bool]bool{true: false, false: false}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsTypes"}, makeXY(
|
|
protobuild.Message{"map_string_string": map[string]string{"a": "b", "c": "d"}},
|
|
protobuild.Message{"map_string_string": map[string]string{"a": "b", "c": "e"}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsTypes"}, makeXY(
|
|
protobuild.Message{"map_string_bytes": map[string][]byte{"a": []byte("b"), "c": []byte("d")}},
|
|
protobuild.Message{"map_string_bytes": map[string][]byte{"a": []byte("b"), "c": []byte("e")}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsTypes"}, makeXY(
|
|
protobuild.Message{"map_string_nested_message": map[string]protobuild.Message{
|
|
"a": {"a": int32(1)},
|
|
"b": {"a": int32(2)},
|
|
}},
|
|
protobuild.Message{"map_string_nested_message": map[string]protobuild.Message{
|
|
"a": {"a": int32(1)},
|
|
"b": {"a": int32(3)},
|
|
}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "MapsTypes"}, makeXY(
|
|
protobuild.Message{"map_string_nested_enum": map[string]string{
|
|
"a": "FOO",
|
|
"b": "BAR",
|
|
}},
|
|
protobuild.Message{"map_string_nested_enum": map[string]string{
|
|
"a": "FOO",
|
|
"b": "BAZ",
|
|
}},
|
|
allTypesNoExt...,
|
|
))...)
|
|
|
|
// Unknown fields.
|
|
|
|
tests = append(tests, makeTest(test{desc: "Unknown"}, makeXY(
|
|
protobuild.Message{protobuild.Unknown: protopack.Message{
|
|
protopack.Tag{100000, protopack.VarintType}, protopack.Varint(1),
|
|
}.Marshal()},
|
|
protobuild.Message{protobuild.Unknown: protopack.Message{
|
|
protopack.Tag{100000, protopack.VarintType}, protopack.Varint(2),
|
|
}.Marshal()},
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Unknown"}, makeXY(
|
|
protobuild.Message{protobuild.Unknown: protopack.Message{
|
|
protopack.Tag{100000, protopack.VarintType}, protopack.Varint(1),
|
|
}.Marshal()},
|
|
protobuild.Message{},
|
|
))...)
|
|
|
|
// Extensions.
|
|
onlyExts := []proto.Message{
|
|
&testpb.TestAllExtensions{},
|
|
&testeditionspb.TestAllExtensions{},
|
|
}
|
|
|
|
tests = append(tests, makeTest(test{desc: "Extensions"}, makeXY(
|
|
protobuild.Message{"optional_int32": 1},
|
|
protobuild.Message{"optional_int32": 2},
|
|
onlyExts...,
|
|
))...)
|
|
|
|
tests = append(tests, makeTest(test{desc: "Extensions"}, makeXY(
|
|
protobuild.Message{},
|
|
protobuild.Message{"optional_int32": 2},
|
|
onlyExts...,
|
|
))...)
|
|
|
|
for _, tt := range tests {
|
|
desc := tt.desc
|
|
if desc == "" {
|
|
desc = "Untitled"
|
|
}
|
|
desc += fmt.Sprintf("/x=%T y=%T", tt.x, tt.y)
|
|
t.Run(desc, func(t *testing.T) {
|
|
if !tt.eq && !proto.Equal(tt.x, tt.x) {
|
|
t.Errorf("Equal(x, x) = false, want true\n==== x ====\n%v", prototext.Format(tt.x))
|
|
}
|
|
if !tt.eq && !proto.Equal(tt.y, tt.y) {
|
|
t.Errorf("Equal(y, y) = false, want true\n==== y ====\n%v", prototext.Format(tt.y))
|
|
}
|
|
if eq := proto.Equal(tt.x, tt.y); eq != tt.eq {
|
|
t.Errorf("Equal(x, y) = %v, want %v\n==== x ====\n%v==== y ====\n%v", eq, tt.eq, prototext.Format(tt.x), prototext.Format(tt.y))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func BenchmarkEqualWithSmallEmpty(b *testing.B) {
|
|
b.ReportAllocs()
|
|
x := &testpb.ForeignMessage{}
|
|
y := &testpb.ForeignMessage{}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
proto.Equal(x, y)
|
|
}
|
|
}
|
|
|
|
func BenchmarkEqualWithIdenticalPtrEmpty(b *testing.B) {
|
|
b.ReportAllocs()
|
|
x := &testpb.ForeignMessage{}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
proto.Equal(x, x)
|
|
}
|
|
}
|
|
|
|
func BenchmarkEqualWithLargeEmpty(b *testing.B) {
|
|
b.ReportAllocs()
|
|
x := &testpb.TestManyMessageFieldsMessage{
|
|
F1: makeNested(2),
|
|
F10: makeNested(2),
|
|
F20: makeNested(2),
|
|
F30: makeNested(2),
|
|
F40: makeNested(2),
|
|
F50: makeNested(2),
|
|
F60: makeNested(2),
|
|
F70: makeNested(2),
|
|
F80: makeNested(2),
|
|
F90: makeNested(2),
|
|
}
|
|
y := &testpb.TestManyMessageFieldsMessage{
|
|
F1: makeNested(2),
|
|
F10: makeNested(2),
|
|
F20: makeNested(2),
|
|
F30: makeNested(2),
|
|
F40: makeNested(2),
|
|
F50: makeNested(2),
|
|
F60: makeNested(2),
|
|
F70: makeNested(2),
|
|
F80: makeNested(2),
|
|
F90: makeNested(2),
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
proto.Equal(x, y)
|
|
}
|
|
}
|
|
|
|
func makeNested(depth int) *testpb.TestAllTypes {
|
|
if depth <= 0 {
|
|
return nil
|
|
}
|
|
return &testpb.TestAllTypes{
|
|
OptionalNestedMessage: &testpb.TestAllTypes_NestedMessage{
|
|
Corecursive: makeNested(depth - 1),
|
|
},
|
|
}
|
|
}
|
|
|
|
func BenchmarkEqualWithDeeplyNestedEqual(b *testing.B) {
|
|
b.ReportAllocs()
|
|
x := makeNested(20)
|
|
y := makeNested(20)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
proto.Equal(x, y)
|
|
}
|
|
}
|
|
|
|
func BenchmarkEqualWithDeeplyNestedDifferent(b *testing.B) {
|
|
b.ReportAllocs()
|
|
x := makeNested(20)
|
|
y := makeNested(21)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
proto.Equal(x, y)
|
|
}
|
|
}
|
|
|
|
func BenchmarkEqualWithDeeplyNestedIdenticalPtr(b *testing.B) {
|
|
b.ReportAllocs()
|
|
x := makeNested(20)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
proto.Equal(x, x)
|
|
}
|
|
}
|