2018-11-28 18:25:20 -08:00
|
|
|
// Copyright 2018 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 textpb_test
|
|
|
|
|
|
|
|
import (
|
2019-01-03 15:39:58 -08:00
|
|
|
"encoding/hex"
|
2018-11-28 18:25:20 -08:00
|
|
|
"math"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/golang/protobuf/v2/encoding/textpb"
|
|
|
|
"github.com/golang/protobuf/v2/internal/detrand"
|
2018-12-11 21:08:58 -08:00
|
|
|
"github.com/golang/protobuf/v2/internal/encoding/pack"
|
2018-12-17 17:13:07 -08:00
|
|
|
"github.com/golang/protobuf/v2/internal/encoding/wire"
|
2018-11-28 18:25:20 -08:00
|
|
|
"github.com/golang/protobuf/v2/internal/scalar"
|
|
|
|
"github.com/golang/protobuf/v2/proto"
|
2019-01-02 15:46:07 -08:00
|
|
|
preg "github.com/golang/protobuf/v2/reflect/protoregistry"
|
all: move v1 types over to the v2 repository
As a goal, v2 should not depend on v1. As another step towards that end,
we move all the types that used to be in the v1 protoapi package over to v2.
For now, we place MessageV1, ExtensionRangeV1, and ExtensionDescV1
in runtime/protoiface since these are types that generated messages will
probably have to reference forever. An alternative location could be
reflect/protoreflect, but it seems unfortunate to have to dirty the
namespace of that package with these types.
We move ExtensionFieldV1, ExtensionFieldsV1, and ExtensionFieldsOf
to internal/impl, since these are related to the implementation of a
generated message.
Since moving these types from v1 to v2 implies that the v1 protoapi
package is useless, we update all usages of v1 protoapi in the v2
repository to point to the relevant v2 type or functionality.
CL/168538 is the corresponding change to alter v1.
There will be a temporary build failure as it is not possible
to submit CL/168519 and CL/168538 atomically.
Change-Id: Ide4025c1b6af5b7f0696f4b65b988b4d10a50f0b
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/168519
Reviewed-by: Herbie Ong <herbie@google.com>
2019-03-20 18:29:32 -07:00
|
|
|
"github.com/golang/protobuf/v2/runtime/protoiface"
|
2018-11-28 18:25:20 -08:00
|
|
|
"github.com/google/go-cmp/cmp"
|
|
|
|
"github.com/google/go-cmp/cmp/cmpopts"
|
|
|
|
|
2019-02-13 14:13:21 -08:00
|
|
|
"github.com/golang/protobuf/v2/encoding/testprotos/pb2"
|
|
|
|
"github.com/golang/protobuf/v2/encoding/testprotos/pb3"
|
2019-02-27 21:46:29 -08:00
|
|
|
knownpb "github.com/golang/protobuf/v2/types/known"
|
2018-11-28 18:25:20 -08:00
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
// Disable detrand to enable direct comparisons on outputs.
|
|
|
|
detrand.Disable()
|
|
|
|
}
|
|
|
|
|
|
|
|
// splitLines is a cmpopts.Option for comparing strings with line breaks.
|
|
|
|
var splitLines = cmpopts.AcyclicTransformer("SplitLines", func(s string) []string {
|
|
|
|
return strings.Split(s, "\n")
|
|
|
|
})
|
|
|
|
|
2018-12-06 15:28:53 -08:00
|
|
|
func pb2Enum(i int32) *pb2.Enum {
|
|
|
|
p := new(pb2.Enum)
|
|
|
|
*p = pb2.Enum(i)
|
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
|
|
|
func pb2Enums_NestedEnum(i int32) *pb2.Enums_NestedEnum {
|
|
|
|
p := new(pb2.Enums_NestedEnum)
|
|
|
|
*p = pb2.Enums_NestedEnum(i)
|
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
all: move v1 types over to the v2 repository
As a goal, v2 should not depend on v1. As another step towards that end,
we move all the types that used to be in the v1 protoapi package over to v2.
For now, we place MessageV1, ExtensionRangeV1, and ExtensionDescV1
in runtime/protoiface since these are types that generated messages will
probably have to reference forever. An alternative location could be
reflect/protoreflect, but it seems unfortunate to have to dirty the
namespace of that package with these types.
We move ExtensionFieldV1, ExtensionFieldsV1, and ExtensionFieldsOf
to internal/impl, since these are related to the implementation of a
generated message.
Since moving these types from v1 to v2 implies that the v1 protoapi
package is useless, we update all usages of v1 protoapi in the v2
repository to point to the relevant v2 type or functionality.
CL/168538 is the corresponding change to alter v1.
There will be a temporary build failure as it is not possible
to submit CL/168519 and CL/168538 atomically.
Change-Id: Ide4025c1b6af5b7f0696f4b65b988b4d10a50f0b
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/168519
Reviewed-by: Herbie Ong <herbie@google.com>
2019-03-20 18:29:32 -07:00
|
|
|
func setExtension(m proto.Message, xd *protoiface.ExtensionDescV1, val interface{}) {
|
2018-12-17 17:13:07 -08:00
|
|
|
knownFields := m.ProtoReflect().KnownFields()
|
|
|
|
extTypes := knownFields.ExtensionTypes()
|
2019-03-14 16:08:22 -07:00
|
|
|
extTypes.Register(xd.Type)
|
2018-12-17 17:13:07 -08:00
|
|
|
if val == nil {
|
|
|
|
return
|
|
|
|
}
|
2019-03-14 16:08:22 -07:00
|
|
|
pval := xd.Type.ValueOf(val)
|
2018-12-17 17:13:07 -08:00
|
|
|
knownFields.Set(wire.Number(xd.Field), pval)
|
|
|
|
}
|
|
|
|
|
2019-01-03 15:39:58 -08:00
|
|
|
// dhex decodes a hex-string and returns the bytes and panics if s is invalid.
|
|
|
|
func dhex(s string) []byte {
|
|
|
|
b, err := hex.DecodeString(s)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
2018-11-28 18:25:20 -08:00
|
|
|
func TestMarshal(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
|
|
desc string
|
2019-01-02 15:46:07 -08:00
|
|
|
mo textpb.MarshalOptions
|
2018-12-13 14:19:50 -08:00
|
|
|
input proto.Message
|
2018-11-28 18:25:20 -08:00
|
|
|
want string
|
2019-03-20 18:05:16 -07:00
|
|
|
wantErr bool // TODO: Verify error message content.
|
2018-11-28 18:25:20 -08:00
|
|
|
}{{
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "proto2 optional scalars not set",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb2.Scalars{},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: "\n",
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "proto3 scalars not set",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb3.Scalars{},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: "\n",
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "proto2 optional scalars set to zero values",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb2.Scalars{
|
2018-11-28 18:25:20 -08:00
|
|
|
OptBool: scalar.Bool(false),
|
|
|
|
OptInt32: scalar.Int32(0),
|
|
|
|
OptInt64: scalar.Int64(0),
|
|
|
|
OptUint32: scalar.Uint32(0),
|
|
|
|
OptUint64: scalar.Uint64(0),
|
|
|
|
OptSint32: scalar.Int32(0),
|
|
|
|
OptSint64: scalar.Int64(0),
|
|
|
|
OptFixed32: scalar.Uint32(0),
|
|
|
|
OptFixed64: scalar.Uint64(0),
|
|
|
|
OptSfixed32: scalar.Int32(0),
|
|
|
|
OptSfixed64: scalar.Int64(0),
|
|
|
|
OptFloat: scalar.Float32(0),
|
|
|
|
OptDouble: scalar.Float64(0),
|
|
|
|
OptBytes: []byte{},
|
|
|
|
OptString: scalar.String(""),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: `opt_bool: false
|
|
|
|
opt_int32: 0
|
|
|
|
opt_int64: 0
|
|
|
|
opt_uint32: 0
|
|
|
|
opt_uint64: 0
|
|
|
|
opt_sint32: 0
|
|
|
|
opt_sint64: 0
|
|
|
|
opt_fixed32: 0
|
|
|
|
opt_fixed64: 0
|
|
|
|
opt_sfixed32: 0
|
|
|
|
opt_sfixed64: 0
|
|
|
|
opt_float: 0
|
|
|
|
opt_double: 0
|
|
|
|
opt_bytes: ""
|
|
|
|
opt_string: ""
|
|
|
|
`,
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "proto3 scalars set to zero values",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb3.Scalars{
|
2018-11-28 18:25:20 -08:00
|
|
|
SBool: false,
|
|
|
|
SInt32: 0,
|
|
|
|
SInt64: 0,
|
|
|
|
SUint32: 0,
|
|
|
|
SUint64: 0,
|
|
|
|
SSint32: 0,
|
|
|
|
SSint64: 0,
|
|
|
|
SFixed32: 0,
|
|
|
|
SFixed64: 0,
|
|
|
|
SSfixed32: 0,
|
|
|
|
SSfixed64: 0,
|
|
|
|
SFloat: 0,
|
|
|
|
SDouble: 0,
|
|
|
|
SBytes: []byte{},
|
|
|
|
SString: "",
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: "\n",
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "proto2 optional scalars set to some values",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb2.Scalars{
|
2018-11-28 18:25:20 -08:00
|
|
|
OptBool: scalar.Bool(true),
|
|
|
|
OptInt32: scalar.Int32(0xff),
|
|
|
|
OptInt64: scalar.Int64(0xdeadbeef),
|
|
|
|
OptUint32: scalar.Uint32(47),
|
|
|
|
OptUint64: scalar.Uint64(0xdeadbeef),
|
|
|
|
OptSint32: scalar.Int32(-1001),
|
|
|
|
OptSint64: scalar.Int64(-0xffff),
|
|
|
|
OptFixed64: scalar.Uint64(64),
|
|
|
|
OptSfixed32: scalar.Int32(-32),
|
2019-01-17 19:31:47 -08:00
|
|
|
OptFloat: scalar.Float32(1.02),
|
|
|
|
OptDouble: scalar.Float64(1.0199999809265137),
|
2019-02-13 14:13:21 -08:00
|
|
|
OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
|
|
|
|
OptString: scalar.String("谷歌"),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: `opt_bool: true
|
|
|
|
opt_int32: 255
|
|
|
|
opt_int64: 3735928559
|
|
|
|
opt_uint32: 47
|
|
|
|
opt_uint64: 3735928559
|
|
|
|
opt_sint32: -1001
|
|
|
|
opt_sint64: -65535
|
|
|
|
opt_fixed64: 64
|
|
|
|
opt_sfixed32: -32
|
2019-01-17 19:31:47 -08:00
|
|
|
opt_float: 1.02
|
|
|
|
opt_double: 1.0199999809265137
|
2018-11-28 18:25:20 -08:00
|
|
|
opt_bytes: "谷歌"
|
|
|
|
opt_string: "谷歌"
|
|
|
|
`,
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "float nan",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb3.Scalars{
|
2018-11-28 18:25:20 -08:00
|
|
|
SFloat: float32(math.NaN()),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: "s_float: nan\n",
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "float positive infinity",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb3.Scalars{
|
2018-11-28 18:25:20 -08:00
|
|
|
SFloat: float32(math.Inf(1)),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: "s_float: inf\n",
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "float negative infinity",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb3.Scalars{
|
2018-11-28 18:25:20 -08:00
|
|
|
SFloat: float32(math.Inf(-1)),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: "s_float: -inf\n",
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "double nan",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb3.Scalars{
|
2018-11-28 18:25:20 -08:00
|
|
|
SDouble: math.NaN(),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: "s_double: nan\n",
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "double positive infinity",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb3.Scalars{
|
2018-11-28 18:25:20 -08:00
|
|
|
SDouble: math.Inf(1),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: "s_double: inf\n",
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "double negative infinity",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb3.Scalars{
|
2018-11-28 18:25:20 -08:00
|
|
|
SDouble: math.Inf(-1),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: "s_double: -inf\n",
|
|
|
|
}, {
|
2018-12-06 15:28:53 -08:00
|
|
|
desc: "proto2 enum not set",
|
|
|
|
input: &pb2.Enums{},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: "\n",
|
|
|
|
}, {
|
2018-12-06 15:28:53 -08:00
|
|
|
desc: "proto2 enum set to zero value",
|
|
|
|
input: &pb2.Enums{
|
2019-02-13 14:13:21 -08:00
|
|
|
OptEnum: pb2Enum(0),
|
2018-12-06 15:28:53 -08:00
|
|
|
OptNestedEnum: pb2Enums_NestedEnum(0),
|
|
|
|
},
|
2019-02-13 14:13:21 -08:00
|
|
|
want: `opt_enum: 0
|
2018-12-06 15:28:53 -08:00
|
|
|
opt_nested_enum: 0
|
2018-11-28 18:25:20 -08:00
|
|
|
`,
|
|
|
|
}, {
|
2018-12-06 15:28:53 -08:00
|
|
|
desc: "proto2 enum",
|
|
|
|
input: &pb2.Enums{
|
2019-02-13 14:13:21 -08:00
|
|
|
OptEnum: pb2.Enum_ONE.Enum(),
|
2018-11-28 18:25:20 -08:00
|
|
|
OptNestedEnum: pb2.Enums_UNO.Enum(),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2019-02-13 14:13:21 -08:00
|
|
|
want: `opt_enum: ONE
|
2018-11-28 18:25:20 -08:00
|
|
|
opt_nested_enum: UNO
|
|
|
|
`,
|
|
|
|
}, {
|
2018-12-06 15:28:53 -08:00
|
|
|
desc: "proto2 enum set to numeric values",
|
|
|
|
input: &pb2.Enums{
|
2019-02-13 14:13:21 -08:00
|
|
|
OptEnum: pb2Enum(2),
|
2018-12-06 15:28:53 -08:00
|
|
|
OptNestedEnum: pb2Enums_NestedEnum(2),
|
|
|
|
},
|
2019-02-13 14:13:21 -08:00
|
|
|
want: `opt_enum: TWO
|
2018-12-06 15:28:53 -08:00
|
|
|
opt_nested_enum: DOS
|
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "proto2 enum set to unnamed numeric values",
|
|
|
|
input: &pb2.Enums{
|
|
|
|
OptEnum: pb2Enum(101),
|
|
|
|
OptNestedEnum: pb2Enums_NestedEnum(-101),
|
|
|
|
},
|
|
|
|
want: `opt_enum: 101
|
|
|
|
opt_nested_enum: -101
|
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "proto3 enum not set",
|
|
|
|
input: &pb3.Enums{},
|
|
|
|
want: "\n",
|
|
|
|
}, {
|
|
|
|
desc: "proto3 enum set to zero value",
|
|
|
|
input: &pb3.Enums{
|
|
|
|
SEnum: pb3.Enum_ZERO,
|
|
|
|
SNestedEnum: pb3.Enums_CERO,
|
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: "\n",
|
|
|
|
}, {
|
2018-12-06 15:28:53 -08:00
|
|
|
desc: "proto3 enum",
|
|
|
|
input: &pb3.Enums{
|
|
|
|
SEnum: pb3.Enum_ONE,
|
2019-02-13 14:13:21 -08:00
|
|
|
SNestedEnum: pb3.Enums_UNO,
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
want: `s_enum: ONE
|
2019-02-13 14:13:21 -08:00
|
|
|
s_nested_enum: UNO
|
2018-12-06 15:28:53 -08:00
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "proto3 enum set to numeric values",
|
|
|
|
input: &pb3.Enums{
|
|
|
|
SEnum: 2,
|
2019-02-13 14:13:21 -08:00
|
|
|
SNestedEnum: 2,
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: `s_enum: TWO
|
2019-02-13 14:13:21 -08:00
|
|
|
s_nested_enum: DOS
|
2018-12-06 15:28:53 -08:00
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "proto3 enum set to unnamed numeric values",
|
|
|
|
input: &pb3.Enums{
|
|
|
|
SEnum: -47,
|
|
|
|
SNestedEnum: 47,
|
|
|
|
},
|
|
|
|
want: `s_enum: -47
|
|
|
|
s_nested_enum: 47
|
2018-11-28 18:25:20 -08:00
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "proto2 nested message not set",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb2.Nests{},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: "\n",
|
|
|
|
}, {
|
|
|
|
desc: "proto2 nested message set to empty",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb2.Nests{
|
2018-11-28 18:25:20 -08:00
|
|
|
OptNested: &pb2.Nested{},
|
|
|
|
Optgroup: &pb2.Nests_OptGroup{},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: `opt_nested: {}
|
2019-01-14 15:32:26 -08:00
|
|
|
OptGroup: {}
|
2018-11-28 18:25:20 -08:00
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "proto2 nested messages",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb2.Nests{
|
2018-11-28 18:25:20 -08:00
|
|
|
OptNested: &pb2.Nested{
|
|
|
|
OptString: scalar.String("nested message"),
|
|
|
|
OptNested: &pb2.Nested{
|
|
|
|
OptString: scalar.String("another nested message"),
|
|
|
|
},
|
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: `opt_nested: {
|
|
|
|
opt_string: "nested message"
|
|
|
|
opt_nested: {
|
|
|
|
opt_string: "another nested message"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "proto2 groups",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb2.Nests{
|
2018-11-28 18:25:20 -08:00
|
|
|
Optgroup: &pb2.Nests_OptGroup{
|
|
|
|
OptString: scalar.String("inside a group"),
|
|
|
|
OptNested: &pb2.Nested{
|
|
|
|
OptString: scalar.String("nested message inside a group"),
|
|
|
|
},
|
|
|
|
Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
|
2019-02-13 14:13:21 -08:00
|
|
|
OptFixed32: scalar.Uint32(47),
|
2018-11-28 18:25:20 -08:00
|
|
|
},
|
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2019-01-14 15:32:26 -08:00
|
|
|
want: `OptGroup: {
|
2018-11-28 18:25:20 -08:00
|
|
|
opt_string: "inside a group"
|
|
|
|
opt_nested: {
|
|
|
|
opt_string: "nested message inside a group"
|
|
|
|
}
|
2019-01-14 15:32:26 -08:00
|
|
|
OptNestedGroup: {
|
2019-02-13 14:13:21 -08:00
|
|
|
opt_fixed32: 47
|
2018-11-28 18:25:20 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "proto3 nested message not set",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb3.Nests{},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: "\n",
|
2019-02-13 14:13:21 -08:00
|
|
|
}, {
|
|
|
|
desc: "proto3 nested message set to empty",
|
|
|
|
input: &pb3.Nests{
|
|
|
|
SNested: &pb3.Nested{},
|
|
|
|
},
|
|
|
|
want: "s_nested: {}\n",
|
2018-11-28 18:25:20 -08:00
|
|
|
}, {
|
|
|
|
desc: "proto3 nested message",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb3.Nests{
|
2018-11-28 18:25:20 -08:00
|
|
|
SNested: &pb3.Nested{
|
|
|
|
SString: "nested message",
|
|
|
|
SNested: &pb3.Nested{
|
|
|
|
SString: "another nested message",
|
|
|
|
},
|
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: `s_nested: {
|
|
|
|
s_string: "nested message"
|
|
|
|
s_nested: {
|
|
|
|
s_string: "another nested message"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "oneof not set",
|
|
|
|
input: &pb3.Oneofs{},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: "\n",
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "oneof set to empty string",
|
|
|
|
input: &pb3.Oneofs{
|
|
|
|
Union: &pb3.Oneofs_OneofString{},
|
|
|
|
},
|
|
|
|
want: `oneof_string: ""
|
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "oneof set to string",
|
|
|
|
input: &pb3.Oneofs{
|
|
|
|
Union: &pb3.Oneofs_OneofString{
|
|
|
|
OneofString: "hello",
|
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2019-02-13 14:13:21 -08:00
|
|
|
want: `oneof_string: "hello"
|
|
|
|
`,
|
2018-11-28 18:25:20 -08:00
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "oneof set to enum",
|
|
|
|
input: &pb3.Oneofs{
|
|
|
|
Union: &pb3.Oneofs_OneofEnum{
|
|
|
|
OneofEnum: pb3.Enum_ZERO,
|
2018-11-28 18:25:20 -08:00
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2019-02-13 14:13:21 -08:00
|
|
|
want: `oneof_enum: ZERO
|
|
|
|
`,
|
2018-11-28 18:25:20 -08:00
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "oneof set to empty message",
|
|
|
|
input: &pb3.Oneofs{
|
|
|
|
Union: &pb3.Oneofs_OneofNested{
|
|
|
|
OneofNested: &pb3.Nested{},
|
2018-11-28 18:25:20 -08:00
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2019-02-13 14:13:21 -08:00
|
|
|
want: "oneof_nested: {}\n",
|
2018-11-28 18:25:20 -08:00
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "oneof set to message",
|
|
|
|
input: &pb3.Oneofs{
|
|
|
|
Union: &pb3.Oneofs_OneofNested{
|
|
|
|
OneofNested: &pb3.Nested{
|
|
|
|
SString: "nested message",
|
2018-11-28 18:25:20 -08:00
|
|
|
},
|
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2019-02-13 14:13:21 -08:00
|
|
|
want: `oneof_nested: {
|
|
|
|
s_string: "nested message"
|
2018-11-28 18:25:20 -08:00
|
|
|
}
|
2018-12-06 15:28:53 -08:00
|
|
|
`,
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "repeated fields not set",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb2.Repeats{},
|
|
|
|
want: "\n",
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "repeated fields set to empty slices",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb2.Repeats{
|
|
|
|
RptBool: []bool{},
|
|
|
|
RptInt32: []int32{},
|
|
|
|
RptInt64: []int64{},
|
|
|
|
RptUint32: []uint32{},
|
|
|
|
RptUint64: []uint64{},
|
|
|
|
RptFloat: []float32{},
|
|
|
|
RptDouble: []float64{},
|
|
|
|
RptBytes: [][]byte{},
|
|
|
|
},
|
|
|
|
want: "\n",
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "repeated fields set to some values",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb2.Repeats{
|
|
|
|
RptBool: []bool{true, false, true, true},
|
|
|
|
RptInt32: []int32{1, 6, 0, 0},
|
|
|
|
RptInt64: []int64{-64, 47},
|
|
|
|
RptUint32: []uint32{0xff, 0xffff},
|
|
|
|
RptUint64: []uint64{0xdeadbeef},
|
2019-01-17 19:31:47 -08:00
|
|
|
RptFloat: []float32{float32(math.NaN()), float32(math.Inf(1)), float32(math.Inf(-1)), 1.034},
|
2018-12-06 15:28:53 -08:00
|
|
|
RptDouble: []float64{math.NaN(), math.Inf(1), math.Inf(-1), 1.23e-308},
|
|
|
|
RptString: []string{"hello", "世界"},
|
|
|
|
RptBytes: [][]byte{
|
|
|
|
[]byte("hello"),
|
|
|
|
[]byte("\xe4\xb8\x96\xe7\x95\x8c"),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
want: `rpt_bool: true
|
|
|
|
rpt_bool: false
|
|
|
|
rpt_bool: true
|
|
|
|
rpt_bool: true
|
|
|
|
rpt_int32: 1
|
|
|
|
rpt_int32: 6
|
|
|
|
rpt_int32: 0
|
|
|
|
rpt_int32: 0
|
|
|
|
rpt_int64: -64
|
|
|
|
rpt_int64: 47
|
|
|
|
rpt_uint32: 255
|
|
|
|
rpt_uint32: 65535
|
|
|
|
rpt_uint64: 3735928559
|
2019-01-17 19:31:47 -08:00
|
|
|
rpt_float: nan
|
|
|
|
rpt_float: inf
|
|
|
|
rpt_float: -inf
|
|
|
|
rpt_float: 1.034
|
2018-12-06 15:28:53 -08:00
|
|
|
rpt_double: nan
|
|
|
|
rpt_double: inf
|
|
|
|
rpt_double: -inf
|
|
|
|
rpt_double: 1.23e-308
|
|
|
|
rpt_string: "hello"
|
|
|
|
rpt_string: "世界"
|
|
|
|
rpt_bytes: "hello"
|
|
|
|
rpt_bytes: "世界"
|
|
|
|
`,
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "repeated enums",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb2.Enums{
|
2019-02-13 14:13:21 -08:00
|
|
|
RptEnum: []pb2.Enum{pb2.Enum_ONE, 2, pb2.Enum_TEN, 42},
|
2018-12-06 15:28:53 -08:00
|
|
|
RptNestedEnum: []pb2.Enums_NestedEnum{2, 47, 10},
|
|
|
|
},
|
2019-02-13 14:13:21 -08:00
|
|
|
want: `rpt_enum: ONE
|
|
|
|
rpt_enum: TWO
|
|
|
|
rpt_enum: TEN
|
2018-12-06 15:28:53 -08:00
|
|
|
rpt_enum: 42
|
|
|
|
rpt_nested_enum: DOS
|
|
|
|
rpt_nested_enum: 47
|
|
|
|
rpt_nested_enum: DIEZ
|
|
|
|
`,
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "repeated messages set to empty",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb2.Nests{
|
|
|
|
RptNested: []*pb2.Nested{},
|
|
|
|
Rptgroup: []*pb2.Nests_RptGroup{},
|
|
|
|
},
|
|
|
|
want: "\n",
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "repeated messages",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb2.Nests{
|
|
|
|
RptNested: []*pb2.Nested{
|
|
|
|
{
|
|
|
|
OptString: scalar.String("repeat nested one"),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
OptString: scalar.String("repeat nested two"),
|
|
|
|
OptNested: &pb2.Nested{
|
|
|
|
OptString: scalar.String("inside repeat nested two"),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
want: `rpt_nested: {
|
|
|
|
opt_string: "repeat nested one"
|
|
|
|
}
|
|
|
|
rpt_nested: {
|
|
|
|
opt_string: "repeat nested two"
|
|
|
|
opt_nested: {
|
|
|
|
opt_string: "inside repeat nested two"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rpt_nested: {}
|
2019-02-07 20:17:45 -08:00
|
|
|
`,
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "repeated messages contains nil value",
|
2019-02-07 20:17:45 -08:00
|
|
|
input: &pb2.Nests{
|
|
|
|
RptNested: []*pb2.Nested{nil, {}},
|
|
|
|
},
|
|
|
|
want: `rpt_nested: {}
|
|
|
|
rpt_nested: {}
|
2018-12-06 15:28:53 -08:00
|
|
|
`,
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "repeated groups",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb2.Nests{
|
|
|
|
Rptgroup: []*pb2.Nests_RptGroup{
|
|
|
|
{
|
2019-02-13 14:13:21 -08:00
|
|
|
RptString: []string{"hello", "world"},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
{},
|
2019-02-13 14:13:21 -08:00
|
|
|
nil,
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
},
|
2019-01-14 19:26:50 -08:00
|
|
|
want: `RptGroup: {
|
2019-02-13 14:13:21 -08:00
|
|
|
rpt_string: "hello"
|
|
|
|
rpt_string: "world"
|
2018-12-06 15:28:53 -08:00
|
|
|
}
|
2019-01-14 19:26:50 -08:00
|
|
|
RptGroup: {}
|
2019-02-13 14:13:21 -08:00
|
|
|
RptGroup: {}
|
2018-11-28 18:25:20 -08:00
|
|
|
`,
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "map fields not set",
|
|
|
|
input: &pb3.Maps{},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: "\n",
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "map fields set to empty",
|
|
|
|
input: &pb3.Maps{
|
|
|
|
Int32ToStr: map[int32]string{},
|
|
|
|
BoolToUint32: map[bool]uint32{},
|
|
|
|
Uint64ToEnum: map[uint64]pb3.Enum{},
|
|
|
|
StrToNested: map[string]*pb3.Nested{},
|
|
|
|
StrToOneofs: map[string]*pb3.Oneofs{},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: "\n",
|
|
|
|
}, {
|
|
|
|
desc: "map fields 1",
|
2019-02-13 14:13:21 -08:00
|
|
|
input: &pb3.Maps{
|
2018-11-28 18:25:20 -08:00
|
|
|
Int32ToStr: map[int32]string{
|
|
|
|
-101: "-101",
|
|
|
|
0xff: "0xff",
|
|
|
|
0: "zero",
|
|
|
|
},
|
|
|
|
BoolToUint32: map[bool]uint32{
|
|
|
|
true: 42,
|
|
|
|
false: 101,
|
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: `int32_to_str: {
|
|
|
|
key: -101
|
|
|
|
value: "-101"
|
|
|
|
}
|
|
|
|
int32_to_str: {
|
|
|
|
key: 0
|
|
|
|
value: "zero"
|
|
|
|
}
|
|
|
|
int32_to_str: {
|
|
|
|
key: 255
|
|
|
|
value: "0xff"
|
|
|
|
}
|
|
|
|
bool_to_uint32: {
|
|
|
|
key: false
|
|
|
|
value: 101
|
|
|
|
}
|
|
|
|
bool_to_uint32: {
|
|
|
|
key: true
|
|
|
|
value: 42
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "map fields 2",
|
2019-02-13 14:13:21 -08:00
|
|
|
input: &pb3.Maps{
|
|
|
|
Uint64ToEnum: map[uint64]pb3.Enum{
|
|
|
|
1: pb3.Enum_ONE,
|
|
|
|
2: pb3.Enum_TWO,
|
|
|
|
10: pb3.Enum_TEN,
|
|
|
|
47: 47,
|
2018-11-28 18:25:20 -08:00
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: `uint64_to_enum: {
|
|
|
|
key: 1
|
2019-02-13 14:13:21 -08:00
|
|
|
value: ONE
|
2018-11-28 18:25:20 -08:00
|
|
|
}
|
|
|
|
uint64_to_enum: {
|
|
|
|
key: 2
|
2019-02-13 14:13:21 -08:00
|
|
|
value: TWO
|
2018-11-28 18:25:20 -08:00
|
|
|
}
|
|
|
|
uint64_to_enum: {
|
|
|
|
key: 10
|
2019-02-13 14:13:21 -08:00
|
|
|
value: TEN
|
|
|
|
}
|
|
|
|
uint64_to_enum: {
|
|
|
|
key: 47
|
|
|
|
value: 47
|
2018-11-28 18:25:20 -08:00
|
|
|
}
|
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "map fields 3",
|
2019-02-13 14:13:21 -08:00
|
|
|
input: &pb3.Maps{
|
|
|
|
StrToNested: map[string]*pb3.Nested{
|
|
|
|
"nested": &pb3.Nested{
|
|
|
|
SString: "nested in a map",
|
2018-11-28 18:25:20 -08:00
|
|
|
},
|
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: `str_to_nested: {
|
2019-02-13 14:13:21 -08:00
|
|
|
key: "nested"
|
2018-11-28 18:25:20 -08:00
|
|
|
value: {
|
2019-02-13 14:13:21 -08:00
|
|
|
s_string: "nested in a map"
|
2018-11-28 18:25:20 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "map fields 4",
|
2019-02-13 14:13:21 -08:00
|
|
|
input: &pb3.Maps{
|
|
|
|
StrToOneofs: map[string]*pb3.Oneofs{
|
|
|
|
"string": &pb3.Oneofs{
|
|
|
|
Union: &pb3.Oneofs_OneofString{
|
|
|
|
OneofString: "hello",
|
2018-11-28 18:25:20 -08:00
|
|
|
},
|
|
|
|
},
|
2019-02-13 14:13:21 -08:00
|
|
|
"nested": &pb3.Oneofs{
|
|
|
|
Union: &pb3.Oneofs_OneofNested{
|
|
|
|
OneofNested: &pb3.Nested{
|
|
|
|
SString: "nested oneof in map field value",
|
2018-11-28 18:25:20 -08:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2018-11-28 18:25:20 -08:00
|
|
|
want: `str_to_oneofs: {
|
|
|
|
key: "nested"
|
|
|
|
value: {
|
2019-02-13 14:13:21 -08:00
|
|
|
oneof_nested: {
|
|
|
|
s_string: "nested oneof in map field value"
|
2018-11-28 18:25:20 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
str_to_oneofs: {
|
|
|
|
key: "string"
|
|
|
|
value: {
|
2019-02-13 14:13:21 -08:00
|
|
|
oneof_string: "hello"
|
2018-11-28 18:25:20 -08:00
|
|
|
}
|
|
|
|
}
|
2019-02-07 20:17:45 -08:00
|
|
|
`,
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "map field contains nil value",
|
|
|
|
input: &pb3.Maps{
|
|
|
|
StrToNested: map[string]*pb3.Nested{
|
2019-02-07 20:17:45 -08:00
|
|
|
"nil": nil,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
want: `str_to_nested: {
|
|
|
|
key: "nil"
|
|
|
|
value: {}
|
|
|
|
}
|
2018-11-28 18:25:20 -08:00
|
|
|
`,
|
|
|
|
}, {
|
2019-03-26 16:26:22 -07:00
|
|
|
desc: "required fields not set",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb2.Requireds{},
|
|
|
|
want: "\n",
|
|
|
|
wantErr: true,
|
2018-11-28 18:25:20 -08:00
|
|
|
}, {
|
2019-03-26 16:26:22 -07:00
|
|
|
desc: "required fields partially set",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb2.Requireds{
|
|
|
|
ReqBool: scalar.Bool(false),
|
|
|
|
ReqSfixed64: scalar.Int64(0xbeefcafe),
|
|
|
|
ReqDouble: scalar.Float64(math.NaN()),
|
|
|
|
ReqString: scalar.String("hello"),
|
2019-02-13 14:13:21 -08:00
|
|
|
ReqEnum: pb2.Enum_ONE.Enum(),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
want: `req_bool: false
|
|
|
|
req_sfixed64: 3203386110
|
|
|
|
req_double: nan
|
|
|
|
req_string: "hello"
|
2019-02-13 14:13:21 -08:00
|
|
|
req_enum: ONE
|
2018-11-28 18:25:20 -08:00
|
|
|
`,
|
2018-12-06 15:28:53 -08:00
|
|
|
wantErr: true,
|
2018-11-28 18:25:20 -08:00
|
|
|
}, {
|
2019-03-26 16:26:22 -07:00
|
|
|
desc: "required fields not set with AllowPartial",
|
|
|
|
mo: textpb.MarshalOptions{AllowPartial: true},
|
|
|
|
input: &pb2.Requireds{
|
|
|
|
ReqBool: scalar.Bool(false),
|
|
|
|
ReqSfixed64: scalar.Int64(0xbeefcafe),
|
|
|
|
ReqDouble: scalar.Float64(math.NaN()),
|
|
|
|
ReqString: scalar.String("hello"),
|
|
|
|
ReqEnum: pb2.Enum_ONE.Enum(),
|
|
|
|
},
|
|
|
|
want: `req_bool: false
|
|
|
|
req_sfixed64: 3203386110
|
|
|
|
req_double: nan
|
|
|
|
req_string: "hello"
|
|
|
|
req_enum: ONE
|
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "required fields all set",
|
2018-12-06 15:28:53 -08:00
|
|
|
input: &pb2.Requireds{
|
|
|
|
ReqBool: scalar.Bool(false),
|
|
|
|
ReqSfixed64: scalar.Int64(0),
|
2019-02-13 14:13:21 -08:00
|
|
|
ReqDouble: scalar.Float64(1.23),
|
2018-12-06 15:28:53 -08:00
|
|
|
ReqString: scalar.String(""),
|
2019-02-13 14:13:21 -08:00
|
|
|
ReqEnum: pb2.Enum_ONE.Enum(),
|
2018-12-06 15:28:53 -08:00
|
|
|
ReqNested: &pb2.Nested{},
|
|
|
|
},
|
|
|
|
want: `req_bool: false
|
|
|
|
req_sfixed64: 0
|
2019-02-13 14:13:21 -08:00
|
|
|
req_double: 1.23
|
2018-12-06 15:28:53 -08:00
|
|
|
req_string: ""
|
2019-02-13 14:13:21 -08:00
|
|
|
req_enum: ONE
|
2018-12-06 15:28:53 -08:00
|
|
|
req_nested: {}
|
2018-11-28 18:25:20 -08:00
|
|
|
`,
|
|
|
|
}, {
|
2018-12-06 15:28:53 -08:00
|
|
|
desc: "indirect required field",
|
|
|
|
input: &pb2.IndirectRequired{
|
|
|
|
OptNested: &pb2.NestedWithRequired{},
|
|
|
|
},
|
|
|
|
want: "opt_nested: {}\n",
|
|
|
|
wantErr: true,
|
2019-03-26 16:26:22 -07:00
|
|
|
}, {
|
|
|
|
desc: "indirect required field with AllowPartial",
|
|
|
|
mo: textpb.MarshalOptions{AllowPartial: true},
|
|
|
|
input: &pb2.IndirectRequired{
|
|
|
|
OptNested: &pb2.NestedWithRequired{},
|
|
|
|
},
|
|
|
|
want: "opt_nested: {}\n",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "indirect required field in empty repeated",
|
|
|
|
input: &pb2.IndirectRequired{
|
|
|
|
RptNested: []*pb2.NestedWithRequired{},
|
|
|
|
},
|
|
|
|
want: "\n",
|
|
|
|
}, {
|
|
|
|
desc: "indirect required field in repeated",
|
|
|
|
input: &pb2.IndirectRequired{
|
|
|
|
RptNested: []*pb2.NestedWithRequired{
|
|
|
|
&pb2.NestedWithRequired{},
|
2018-11-28 18:25:20 -08:00
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
want: "rpt_nested: {}\n",
|
|
|
|
wantErr: true,
|
2019-03-26 16:26:22 -07:00
|
|
|
}, {
|
|
|
|
desc: "indirect required field in repeated with AllowPartial",
|
|
|
|
mo: textpb.MarshalOptions{AllowPartial: true},
|
|
|
|
input: &pb2.IndirectRequired{
|
|
|
|
RptNested: []*pb2.NestedWithRequired{
|
|
|
|
&pb2.NestedWithRequired{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
want: "rpt_nested: {}\n",
|
2018-11-28 18:25:20 -08:00
|
|
|
}, {
|
2018-12-06 15:28:53 -08:00
|
|
|
desc: "indirect required field in empty map",
|
|
|
|
input: &pb2.IndirectRequired{
|
|
|
|
StrToNested: map[string]*pb2.NestedWithRequired{},
|
|
|
|
},
|
|
|
|
want: "\n",
|
|
|
|
}, {
|
|
|
|
desc: "indirect required field in map",
|
|
|
|
input: &pb2.IndirectRequired{
|
|
|
|
StrToNested: map[string]*pb2.NestedWithRequired{
|
|
|
|
"fail": &pb2.NestedWithRequired{},
|
2018-11-28 18:25:20 -08:00
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
want: `str_to_nested: {
|
|
|
|
key: "fail"
|
|
|
|
value: {}
|
2018-11-28 18:25:20 -08:00
|
|
|
}
|
|
|
|
`,
|
2018-12-06 15:28:53 -08:00
|
|
|
wantErr: true,
|
2019-03-26 16:26:22 -07:00
|
|
|
}, {
|
|
|
|
desc: "indirect required field in map with AllowPartial",
|
|
|
|
mo: textpb.MarshalOptions{AllowPartial: true},
|
|
|
|
input: &pb2.IndirectRequired{
|
|
|
|
StrToNested: map[string]*pb2.NestedWithRequired{
|
|
|
|
"fail": &pb2.NestedWithRequired{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
want: `str_to_nested: {
|
|
|
|
key: "fail"
|
|
|
|
value: {}
|
|
|
|
}
|
|
|
|
`,
|
2019-02-13 14:13:21 -08:00
|
|
|
}, {
|
|
|
|
desc: "indirect required field in oneof",
|
|
|
|
input: &pb2.IndirectRequired{
|
|
|
|
Union: &pb2.IndirectRequired_OneofNested{
|
|
|
|
OneofNested: &pb2.NestedWithRequired{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
want: "oneof_nested: {}\n",
|
|
|
|
wantErr: true,
|
2019-03-26 16:26:22 -07:00
|
|
|
}, {
|
|
|
|
desc: "indirect required field in oneof with AllowPartial",
|
|
|
|
mo: textpb.MarshalOptions{AllowPartial: true},
|
|
|
|
input: &pb2.IndirectRequired{
|
|
|
|
Union: &pb2.IndirectRequired_OneofNested{
|
|
|
|
OneofNested: &pb2.NestedWithRequired{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
want: "oneof_nested: {}\n",
|
2018-12-11 21:08:58 -08:00
|
|
|
}, {
|
|
|
|
desc: "unknown varint and fixed types",
|
|
|
|
input: &pb2.Scalars{
|
|
|
|
OptString: scalar.String("this message contains unknown fields"),
|
|
|
|
XXX_unrecognized: pack.Message{
|
|
|
|
pack.Tag{101, pack.VarintType}, pack.Bool(true),
|
|
|
|
pack.Tag{102, pack.VarintType}, pack.Varint(0xff),
|
|
|
|
pack.Tag{103, pack.Fixed32Type}, pack.Uint32(47),
|
|
|
|
pack.Tag{104, pack.Fixed64Type}, pack.Int64(0xdeadbeef),
|
|
|
|
}.Marshal(),
|
|
|
|
},
|
|
|
|
want: `opt_string: "this message contains unknown fields"
|
|
|
|
101: 1
|
|
|
|
102: 255
|
|
|
|
103: 47
|
|
|
|
104: 3735928559
|
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "unknown length-delimited",
|
|
|
|
input: &pb2.Scalars{
|
|
|
|
XXX_unrecognized: pack.Message{
|
|
|
|
pack.Tag{101, pack.BytesType}, pack.LengthPrefix{pack.Bool(true), pack.Bool(false)},
|
|
|
|
pack.Tag{102, pack.BytesType}, pack.String("hello world"),
|
|
|
|
pack.Tag{103, pack.BytesType}, pack.Bytes("\xe4\xb8\x96\xe7\x95\x8c"),
|
|
|
|
}.Marshal(),
|
|
|
|
},
|
|
|
|
want: `101: "\x01\x00"
|
|
|
|
102: "hello world"
|
|
|
|
103: "世界"
|
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "unknown group type",
|
|
|
|
input: &pb2.Scalars{
|
|
|
|
XXX_unrecognized: pack.Message{
|
|
|
|
pack.Tag{101, pack.StartGroupType}, pack.Tag{101, pack.EndGroupType},
|
|
|
|
pack.Tag{102, pack.StartGroupType},
|
|
|
|
pack.Tag{101, pack.VarintType}, pack.Bool(false),
|
|
|
|
pack.Tag{102, pack.BytesType}, pack.String("inside a group"),
|
|
|
|
pack.Tag{102, pack.EndGroupType},
|
|
|
|
}.Marshal(),
|
|
|
|
},
|
|
|
|
want: `101: {}
|
|
|
|
102: {
|
|
|
|
101: 0
|
|
|
|
102: "inside a group"
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "unknown unpack repeated field",
|
|
|
|
input: &pb2.Scalars{
|
|
|
|
XXX_unrecognized: pack.Message{
|
|
|
|
pack.Tag{101, pack.BytesType}, pack.LengthPrefix{pack.Bool(true), pack.Bool(false), pack.Bool(true)},
|
|
|
|
pack.Tag{102, pack.BytesType}, pack.String("hello"),
|
|
|
|
pack.Tag{101, pack.VarintType}, pack.Bool(true),
|
|
|
|
pack.Tag{102, pack.BytesType}, pack.String("世界"),
|
|
|
|
}.Marshal(),
|
|
|
|
},
|
|
|
|
want: `101: "\x01\x00\x01"
|
|
|
|
101: 1
|
|
|
|
102: "hello"
|
|
|
|
102: "世界"
|
|
|
|
`,
|
2018-12-17 17:13:07 -08:00
|
|
|
}, {
|
|
|
|
desc: "extensions of non-repeated fields",
|
|
|
|
input: func() proto.Message {
|
|
|
|
m := &pb2.Extensions{
|
|
|
|
OptString: scalar.String("non-extension field"),
|
|
|
|
OptBool: scalar.Bool(true),
|
|
|
|
OptInt32: scalar.Int32(42),
|
|
|
|
}
|
|
|
|
setExtension(m, pb2.E_OptExtBool, true)
|
|
|
|
setExtension(m, pb2.E_OptExtString, "extension field")
|
2019-02-13 14:13:21 -08:00
|
|
|
setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
|
2018-12-17 17:13:07 -08:00
|
|
|
setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
|
|
|
|
OptString: scalar.String("nested in an extension"),
|
|
|
|
OptNested: &pb2.Nested{
|
|
|
|
OptString: scalar.String("another nested in an extension"),
|
|
|
|
},
|
|
|
|
})
|
|
|
|
return m
|
|
|
|
}(),
|
|
|
|
want: `opt_string: "non-extension field"
|
|
|
|
opt_bool: true
|
|
|
|
opt_int32: 42
|
|
|
|
[pb2.opt_ext_bool]: true
|
2019-02-13 14:13:21 -08:00
|
|
|
[pb2.opt_ext_enum]: TEN
|
2018-12-17 17:13:07 -08:00
|
|
|
[pb2.opt_ext_nested]: {
|
|
|
|
opt_string: "nested in an extension"
|
|
|
|
opt_nested: {
|
|
|
|
opt_string: "another nested in an extension"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[pb2.opt_ext_string]: "extension field"
|
|
|
|
`,
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "extension message field set to nil",
|
2018-12-17 17:13:07 -08:00
|
|
|
input: func() proto.Message {
|
|
|
|
m := &pb2.Extensions{}
|
|
|
|
setExtension(m, pb2.E_OptExtNested, nil)
|
|
|
|
return m
|
|
|
|
}(),
|
|
|
|
want: "\n",
|
|
|
|
}, {
|
|
|
|
desc: "extensions of repeated fields",
|
|
|
|
input: func() proto.Message {
|
|
|
|
m := &pb2.Extensions{}
|
2019-02-13 14:13:21 -08:00
|
|
|
setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
|
2018-12-17 17:13:07 -08:00
|
|
|
setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
|
|
|
|
setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
|
|
|
|
&pb2.Nested{OptString: scalar.String("one")},
|
|
|
|
&pb2.Nested{OptString: scalar.String("two")},
|
|
|
|
&pb2.Nested{OptString: scalar.String("three")},
|
|
|
|
})
|
|
|
|
return m
|
|
|
|
}(),
|
2019-02-13 14:13:21 -08:00
|
|
|
want: `[pb2.rpt_ext_enum]: TEN
|
2018-12-17 17:13:07 -08:00
|
|
|
[pb2.rpt_ext_enum]: 101
|
2019-02-13 14:13:21 -08:00
|
|
|
[pb2.rpt_ext_enum]: ONE
|
2018-12-17 17:13:07 -08:00
|
|
|
[pb2.rpt_ext_fixed32]: 42
|
|
|
|
[pb2.rpt_ext_fixed32]: 47
|
|
|
|
[pb2.rpt_ext_nested]: {
|
|
|
|
opt_string: "one"
|
|
|
|
}
|
|
|
|
[pb2.rpt_ext_nested]: {
|
|
|
|
opt_string: "two"
|
|
|
|
}
|
|
|
|
[pb2.rpt_ext_nested]: {
|
|
|
|
opt_string: "three"
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "extensions of non-repeated fields in another message",
|
|
|
|
input: func() proto.Message {
|
|
|
|
m := &pb2.Extensions{}
|
|
|
|
setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
|
|
|
|
setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
|
2019-02-13 14:13:21 -08:00
|
|
|
setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
|
2018-12-17 17:13:07 -08:00
|
|
|
setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
|
|
|
|
OptString: scalar.String("nested in an extension"),
|
|
|
|
OptNested: &pb2.Nested{
|
|
|
|
OptString: scalar.String("another nested in an extension"),
|
|
|
|
},
|
|
|
|
})
|
|
|
|
return m
|
|
|
|
}(),
|
|
|
|
want: `[pb2.ExtensionsContainer.opt_ext_bool]: true
|
2019-02-13 14:13:21 -08:00
|
|
|
[pb2.ExtensionsContainer.opt_ext_enum]: TEN
|
2018-12-17 17:13:07 -08:00
|
|
|
[pb2.ExtensionsContainer.opt_ext_nested]: {
|
|
|
|
opt_string: "nested in an extension"
|
|
|
|
opt_nested: {
|
|
|
|
opt_string: "another nested in an extension"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
|
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "extensions of repeated fields in another message",
|
|
|
|
input: func() proto.Message {
|
|
|
|
m := &pb2.Extensions{
|
|
|
|
OptString: scalar.String("non-extension field"),
|
|
|
|
OptBool: scalar.Bool(true),
|
|
|
|
OptInt32: scalar.Int32(42),
|
|
|
|
}
|
2019-02-13 14:13:21 -08:00
|
|
|
setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
|
2018-12-17 17:13:07 -08:00
|
|
|
setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
|
|
|
|
setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
|
|
|
|
&pb2.Nested{OptString: scalar.String("one")},
|
|
|
|
&pb2.Nested{OptString: scalar.String("two")},
|
|
|
|
&pb2.Nested{OptString: scalar.String("three")},
|
|
|
|
})
|
|
|
|
return m
|
|
|
|
}(),
|
|
|
|
want: `opt_string: "non-extension field"
|
|
|
|
opt_bool: true
|
|
|
|
opt_int32: 42
|
2019-02-13 14:13:21 -08:00
|
|
|
[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
|
2018-12-17 17:13:07 -08:00
|
|
|
[pb2.ExtensionsContainer.rpt_ext_enum]: 101
|
2019-02-13 14:13:21 -08:00
|
|
|
[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
|
2018-12-17 17:13:07 -08:00
|
|
|
[pb2.ExtensionsContainer.rpt_ext_nested]: {
|
|
|
|
opt_string: "one"
|
|
|
|
}
|
|
|
|
[pb2.ExtensionsContainer.rpt_ext_nested]: {
|
|
|
|
opt_string: "two"
|
|
|
|
}
|
|
|
|
[pb2.ExtensionsContainer.rpt_ext_nested]: {
|
|
|
|
opt_string: "three"
|
|
|
|
}
|
|
|
|
[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
|
|
|
|
[pb2.ExtensionsContainer.rpt_ext_string]: "world"
|
|
|
|
`,
|
2019-01-07 18:56:57 -08:00
|
|
|
}, {
|
|
|
|
desc: "MessageSet",
|
|
|
|
input: func() proto.Message {
|
|
|
|
m := &pb2.MessageSet{}
|
|
|
|
setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
|
|
|
|
OptString: scalar.String("a messageset extension"),
|
|
|
|
})
|
|
|
|
setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
|
|
|
|
OptString: scalar.String("not a messageset extension"),
|
|
|
|
})
|
|
|
|
setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
|
|
|
|
OptString: scalar.String("just a regular extension"),
|
|
|
|
})
|
|
|
|
return m
|
|
|
|
}(),
|
|
|
|
want: `[pb2.MessageSetExtension]: {
|
|
|
|
opt_string: "a messageset extension"
|
|
|
|
}
|
|
|
|
[pb2.MessageSetExtension.ext_nested]: {
|
|
|
|
opt_string: "just a regular extension"
|
|
|
|
}
|
|
|
|
[pb2.MessageSetExtension.not_message_set_extension]: {
|
|
|
|
opt_string: "not a messageset extension"
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "not real MessageSet 1",
|
|
|
|
input: func() proto.Message {
|
|
|
|
m := &pb2.FakeMessageSet{}
|
|
|
|
setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
|
|
|
|
OptString: scalar.String("not a messageset extension"),
|
|
|
|
})
|
|
|
|
return m
|
|
|
|
}(),
|
|
|
|
want: `[pb2.FakeMessageSetExtension.message_set_extension]: {
|
|
|
|
opt_string: "not a messageset extension"
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
}, {
|
|
|
|
desc: "not real MessageSet 2",
|
|
|
|
input: func() proto.Message {
|
|
|
|
m := &pb2.MessageSet{}
|
|
|
|
setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
|
|
|
|
OptString: scalar.String("another not a messageset extension"),
|
|
|
|
})
|
|
|
|
return m
|
|
|
|
}(),
|
|
|
|
want: `[pb2.message_set_extension]: {
|
|
|
|
opt_string: "another not a messageset extension"
|
|
|
|
}
|
|
|
|
`,
|
2019-01-02 15:46:07 -08:00
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "Any not expanded",
|
2019-01-04 14:08:41 -08:00
|
|
|
mo: textpb.MarshalOptions{
|
|
|
|
Resolver: preg.NewTypes(),
|
|
|
|
},
|
2019-01-02 15:46:07 -08:00
|
|
|
input: func() proto.Message {
|
|
|
|
m := &pb2.Nested{
|
|
|
|
OptString: scalar.String("embedded inside Any"),
|
|
|
|
OptNested: &pb2.Nested{
|
|
|
|
OptString: scalar.String("inception"),
|
|
|
|
},
|
|
|
|
}
|
2019-03-15 18:22:36 -07:00
|
|
|
b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
|
2019-01-02 15:46:07 -08:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error in binary marshaling message for Any.value: %v", err)
|
|
|
|
}
|
2019-03-20 18:05:16 -07:00
|
|
|
return &knownpb.Any{
|
2019-01-04 14:08:41 -08:00
|
|
|
TypeUrl: "pb2.Nested",
|
2019-01-02 15:46:07 -08:00
|
|
|
Value: b,
|
2019-03-20 18:05:16 -07:00
|
|
|
}
|
2019-01-02 15:46:07 -08:00
|
|
|
}(),
|
|
|
|
want: `type_url: "pb2.Nested"
|
|
|
|
value: "\n\x13embedded inside Any\x12\x0b\n\tinception"
|
|
|
|
`,
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "Any expanded",
|
2019-01-04 14:08:41 -08:00
|
|
|
mo: textpb.MarshalOptions{
|
|
|
|
Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
|
|
|
|
},
|
2019-01-02 15:46:07 -08:00
|
|
|
input: func() proto.Message {
|
|
|
|
m := &pb2.Nested{
|
|
|
|
OptString: scalar.String("embedded inside Any"),
|
|
|
|
OptNested: &pb2.Nested{
|
|
|
|
OptString: scalar.String("inception"),
|
|
|
|
},
|
|
|
|
}
|
2019-03-15 18:22:36 -07:00
|
|
|
b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
|
2019-01-02 15:46:07 -08:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error in binary marshaling message for Any.value: %v", err)
|
|
|
|
}
|
2019-03-20 18:05:16 -07:00
|
|
|
return &knownpb.Any{
|
2019-01-04 14:08:41 -08:00
|
|
|
TypeUrl: "foo/pb2.Nested",
|
2019-01-02 15:46:07 -08:00
|
|
|
Value: b,
|
2019-03-20 18:05:16 -07:00
|
|
|
}
|
2019-01-02 15:46:07 -08:00
|
|
|
}(),
|
2019-01-04 14:08:41 -08:00
|
|
|
want: `[foo/pb2.Nested]: {
|
2019-01-02 15:46:07 -08:00
|
|
|
opt_string: "embedded inside Any"
|
|
|
|
opt_nested: {
|
|
|
|
opt_string: "inception"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "Any expanded with missing required error",
|
2019-01-04 14:08:41 -08:00
|
|
|
mo: textpb.MarshalOptions{
|
|
|
|
Resolver: preg.NewTypes((&pb2.PartialRequired{}).ProtoReflect().Type()),
|
|
|
|
},
|
2019-01-02 15:46:07 -08:00
|
|
|
input: func() proto.Message {
|
|
|
|
m := &pb2.PartialRequired{
|
|
|
|
OptString: scalar.String("embedded inside Any"),
|
|
|
|
}
|
2019-03-20 18:05:16 -07:00
|
|
|
b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
|
|
|
|
// TODO: Marshal may fail due to required field not set at some
|
|
|
|
// point. Need to ignore required not set error here.
|
|
|
|
if err != nil {
|
2019-01-02 15:46:07 -08:00
|
|
|
t.Fatalf("error in binary marshaling message for Any.value: %v", err)
|
|
|
|
}
|
2019-03-20 18:05:16 -07:00
|
|
|
return &knownpb.Any{
|
2019-01-02 15:46:07 -08:00
|
|
|
TypeUrl: string(m.ProtoReflect().Type().FullName()),
|
|
|
|
Value: b,
|
2019-03-20 18:05:16 -07:00
|
|
|
}
|
2019-01-02 15:46:07 -08:00
|
|
|
}(),
|
|
|
|
want: `[pb2.PartialRequired]: {
|
|
|
|
opt_string: "embedded inside Any"
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
wantErr: true,
|
2019-01-03 15:39:58 -08:00
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "Any with invalid value",
|
2019-01-04 14:08:41 -08:00
|
|
|
mo: textpb.MarshalOptions{
|
|
|
|
Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
|
|
|
|
},
|
2019-03-20 18:05:16 -07:00
|
|
|
input: &knownpb.Any{
|
2019-01-04 14:08:41 -08:00
|
|
|
TypeUrl: "foo/pb2.Nested",
|
|
|
|
Value: dhex("80"),
|
2019-03-20 18:05:16 -07:00
|
|
|
},
|
2019-01-04 14:08:41 -08:00
|
|
|
want: `type_url: "foo/pb2.Nested"
|
2019-01-03 15:39:58 -08:00
|
|
|
value: "\x80"
|
2019-01-02 15:46:07 -08:00
|
|
|
`,
|
2018-11-28 18:25:20 -08:00
|
|
|
}}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
tt := tt
|
|
|
|
t.Run(tt.desc, func(t *testing.T) {
|
2019-03-20 14:04:24 -07:00
|
|
|
// Use 2-space indentation on all MarshalOptions.
|
|
|
|
tt.mo.Indent = " "
|
2019-01-02 15:46:07 -08:00
|
|
|
b, err := tt.mo.Marshal(tt.input)
|
2018-11-28 18:25:20 -08:00
|
|
|
if err != nil && !tt.wantErr {
|
2019-01-02 15:46:07 -08:00
|
|
|
t.Errorf("Marshal() returned error: %v\n", err)
|
2018-11-28 18:25:20 -08:00
|
|
|
}
|
2018-12-06 15:28:53 -08:00
|
|
|
if err == nil && tt.wantErr {
|
2019-01-02 15:46:07 -08:00
|
|
|
t.Error("Marshal() got nil error, want error\n")
|
2018-11-28 18:25:20 -08:00
|
|
|
}
|
2018-12-06 15:28:53 -08:00
|
|
|
got := string(b)
|
|
|
|
if tt.want != "" && got != tt.want {
|
|
|
|
t.Errorf("Marshal()\n<got>\n%v\n<want>\n%v\n", got, tt.want)
|
|
|
|
if diff := cmp.Diff(tt.want, got, splitLines); diff != "" {
|
2018-11-28 18:25:20 -08:00
|
|
|
t.Errorf("Marshal() diff -want +got\n%v\n", diff)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|