aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/golang/protobuf/proto/clone_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/golang/protobuf/proto/clone_test.go')
-rw-r--r--vendor/github.com/golang/protobuf/proto/clone_test.go300
1 files changed, 300 insertions, 0 deletions
diff --git a/vendor/github.com/golang/protobuf/proto/clone_test.go b/vendor/github.com/golang/protobuf/proto/clone_test.go
new file mode 100644
index 0000000..f607ff4
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/proto/clone_test.go
@@ -0,0 +1,300 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 The Go Authors. All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto_test
+
+import (
+ "testing"
+
+ "github.com/golang/protobuf/proto"
+
+ proto3pb "github.com/golang/protobuf/proto/proto3_proto"
+ pb "github.com/golang/protobuf/proto/testdata"
+)
+
+var cloneTestMessage = &pb.MyMessage{
+ Count: proto.Int32(42),
+ Name: proto.String("Dave"),
+ Pet: []string{"bunny", "kitty", "horsey"},
+ Inner: &pb.InnerMessage{
+ Host: proto.String("niles"),
+ Port: proto.Int32(9099),
+ Connected: proto.Bool(true),
+ },
+ Others: []*pb.OtherMessage{
+ {
+ Value: []byte("some bytes"),
+ },
+ },
+ Somegroup: &pb.MyMessage_SomeGroup{
+ GroupField: proto.Int32(6),
+ },
+ RepBytes: [][]byte{[]byte("sham"), []byte("wow")},
+}
+
+func init() {
+ ext := &pb.Ext{
+ Data: proto.String("extension"),
+ }
+ if err := proto.SetExtension(cloneTestMessage, pb.E_Ext_More, ext); err != nil {
+ panic("SetExtension: " + err.Error())
+ }
+}
+
+func TestClone(t *testing.T) {
+ m := proto.Clone(cloneTestMessage).(*pb.MyMessage)
+ if !proto.Equal(m, cloneTestMessage) {
+ t.Errorf("Clone(%v) = %v", cloneTestMessage, m)
+ }
+
+ // Verify it was a deep copy.
+ *m.Inner.Port++
+ if proto.Equal(m, cloneTestMessage) {
+ t.Error("Mutating clone changed the original")
+ }
+ // Byte fields and repeated fields should be copied.
+ if &m.Pet[0] == &cloneTestMessage.Pet[0] {
+ t.Error("Pet: repeated field not copied")
+ }
+ if &m.Others[0] == &cloneTestMessage.Others[0] {
+ t.Error("Others: repeated field not copied")
+ }
+ if &m.Others[0].Value[0] == &cloneTestMessage.Others[0].Value[0] {
+ t.Error("Others[0].Value: bytes field not copied")
+ }
+ if &m.RepBytes[0] == &cloneTestMessage.RepBytes[0] {
+ t.Error("RepBytes: repeated field not copied")
+ }
+ if &m.RepBytes[0][0] == &cloneTestMessage.RepBytes[0][0] {
+ t.Error("RepBytes[0]: bytes field not copied")
+ }
+}
+
+func TestCloneNil(t *testing.T) {
+ var m *pb.MyMessage
+ if c := proto.Clone(m); !proto.Equal(m, c) {
+ t.Errorf("Clone(%v) = %v", m, c)
+ }
+}
+
+var mergeTests = []struct {
+ src, dst, want proto.Message
+}{
+ {
+ src: &pb.MyMessage{
+ Count: proto.Int32(42),
+ },
+ dst: &pb.MyMessage{
+ Name: proto.String("Dave"),
+ },
+ want: &pb.MyMessage{
+ Count: proto.Int32(42),
+ Name: proto.String("Dave"),
+ },
+ },
+ {
+ src: &pb.MyMessage{
+ Inner: &pb.InnerMessage{
+ Host: proto.String("hey"),
+ Connected: proto.Bool(true),
+ },
+ Pet: []string{"horsey"},
+ Others: []*pb.OtherMessage{
+ {
+ Value: []byte("some bytes"),
+ },
+ },
+ },
+ dst: &pb.MyMessage{
+ Inner: &pb.InnerMessage{
+ Host: proto.String("niles"),
+ Port: proto.Int32(9099),
+ },
+ Pet: []string{"bunny", "kitty"},
+ Others: []*pb.OtherMessage{
+ {
+ Key: proto.Int64(31415926535),
+ },
+ {
+ // Explicitly test a src=nil field
+ Inner: nil,
+ },
+ },
+ },
+ want: &pb.MyMessage{
+ Inner: &pb.InnerMessage{
+ Host: proto.String("hey"),
+ Connected: proto.Bool(true),
+ Port: proto.Int32(9099),
+ },
+ Pet: []string{"bunny", "kitty", "horsey"},
+ Others: []*pb.OtherMessage{
+ {
+ Key: proto.Int64(31415926535),
+ },
+ {},
+ {
+ Value: []byte("some bytes"),
+ },
+ },
+ },
+ },
+ {
+ src: &pb.MyMessage{
+ RepBytes: [][]byte{[]byte("wow")},
+ },
+ dst: &pb.MyMessage{
+ Somegroup: &pb.MyMessage_SomeGroup{
+ GroupField: proto.Int32(6),
+ },
+ RepBytes: [][]byte{[]byte("sham")},
+ },
+ want: &pb.MyMessage{
+ Somegroup: &pb.MyMessage_SomeGroup{
+ GroupField: proto.Int32(6),
+ },
+ RepBytes: [][]byte{[]byte("sham"), []byte("wow")},
+ },
+ },
+ // Check that a scalar bytes field replaces rather than appends.
+ {
+ src: &pb.OtherMessage{Value: []byte("foo")},
+ dst: &pb.OtherMessage{Value: []byte("bar")},
+ want: &pb.OtherMessage{Value: []byte("foo")},
+ },
+ {
+ src: &pb.MessageWithMap{
+ NameMapping: map[int32]string{6: "Nigel"},
+ MsgMapping: map[int64]*pb.FloatingPoint{
+ 0x4001: &pb.FloatingPoint{F: proto.Float64(2.0)},
+ 0x4002: &pb.FloatingPoint{
+ F: proto.Float64(2.0),
+ },
+ },
+ ByteMapping: map[bool][]byte{true: []byte("wowsa")},
+ },
+ dst: &pb.MessageWithMap{
+ NameMapping: map[int32]string{
+ 6: "Bruce", // should be overwritten
+ 7: "Andrew",
+ },
+ MsgMapping: map[int64]*pb.FloatingPoint{
+ 0x4002: &pb.FloatingPoint{
+ F: proto.Float64(3.0),
+ Exact: proto.Bool(true),
+ }, // the entire message should be overwritten
+ },
+ },
+ want: &pb.MessageWithMap{
+ NameMapping: map[int32]string{
+ 6: "Nigel",
+ 7: "Andrew",
+ },
+ MsgMapping: map[int64]*pb.FloatingPoint{
+ 0x4001: &pb.FloatingPoint{F: proto.Float64(2.0)},
+ 0x4002: &pb.FloatingPoint{
+ F: proto.Float64(2.0),
+ },
+ },
+ ByteMapping: map[bool][]byte{true: []byte("wowsa")},
+ },
+ },
+ // proto3 shouldn't merge zero values,
+ // in the same way that proto2 shouldn't merge nils.
+ {
+ src: &proto3pb.Message{
+ Name: "Aaron",
+ Data: []byte(""), // zero value, but not nil
+ },
+ dst: &proto3pb.Message{
+ HeightInCm: 176,
+ Data: []byte("texas!"),
+ },
+ want: &proto3pb.Message{
+ Name: "Aaron",
+ HeightInCm: 176,
+ Data: []byte("texas!"),
+ },
+ },
+ // Oneof fields should merge by assignment.
+ {
+ src: &pb.Communique{
+ Union: &pb.Communique_Number{41},
+ },
+ dst: &pb.Communique{
+ Union: &pb.Communique_Name{"Bobby Tables"},
+ },
+ want: &pb.Communique{
+ Union: &pb.Communique_Number{41},
+ },
+ },
+ // Oneof nil is the same as not set.
+ {
+ src: &pb.Communique{},
+ dst: &pb.Communique{
+ Union: &pb.Communique_Name{"Bobby Tables"},
+ },
+ want: &pb.Communique{
+ Union: &pb.Communique_Name{"Bobby Tables"},
+ },
+ },
+ {
+ src: &proto3pb.Message{
+ Terrain: map[string]*proto3pb.Nested{
+ "kay_a": &proto3pb.Nested{Cute: true}, // replace
+ "kay_b": &proto3pb.Nested{Bunny: "rabbit"}, // insert
+ },
+ },
+ dst: &proto3pb.Message{
+ Terrain: map[string]*proto3pb.Nested{
+ "kay_a": &proto3pb.Nested{Bunny: "lost"}, // replaced
+ "kay_c": &proto3pb.Nested{Bunny: "bunny"}, // keep
+ },
+ },
+ want: &proto3pb.Message{
+ Terrain: map[string]*proto3pb.Nested{
+ "kay_a": &proto3pb.Nested{Cute: true},
+ "kay_b": &proto3pb.Nested{Bunny: "rabbit"},
+ "kay_c": &proto3pb.Nested{Bunny: "bunny"},
+ },
+ },
+ },
+}
+
+func TestMerge(t *testing.T) {
+ for _, m := range mergeTests {
+ got := proto.Clone(m.dst)
+ proto.Merge(got, m.src)
+ if !proto.Equal(got, m.want) {
+ t.Errorf("Merge(%v, %v)\n got %v\nwant %v\n", m.dst, m.src, got, m.want)
+ }
+ }
+}