OSDN Git Service

add package
[bytom/vapor.git] / vendor / github.com / gogo / protobuf / proto / clone_test.go
diff --git a/vendor/github.com/gogo/protobuf/proto/clone_test.go b/vendor/github.com/gogo/protobuf/proto/clone_test.go
new file mode 100644 (file)
index 0000000..ac4b919
--- /dev/null
@@ -0,0 +1,397 @@
+// 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/gogo/protobuf/proto"
+
+       proto3pb "github.com/gogo/protobuf/proto/proto3_proto"
+       pb "github.com/gogo/protobuf/proto/test_proto"
+)
+
+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.Fatalf("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: {F: proto.Float64(2.0)},
+                               0x4002: {
+                                       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: {
+                                       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: {F: proto.Float64(2.0)},
+                               0x4002: {
+                                       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{Number: 41},
+               },
+               dst: &pb.Communique{
+                       Union: &pb.Communique_Name{Name: "Bobby Tables"},
+               },
+               want: &pb.Communique{
+                       Union: &pb.Communique_Number{Number: 41},
+               },
+       },
+       { // Oneof nil is the same as not set.
+               src:  &pb.Communique{},
+               dst:  &pb.Communique{Union: &pb.Communique_Name{Name: "Bobby Tables"}},
+               want: &pb.Communique{Union: &pb.Communique_Name{Name: "Bobby Tables"}},
+       },
+       {
+               src:  &pb.Communique{Union: &pb.Communique_Number{Number: 1337}},
+               dst:  &pb.Communique{},
+               want: &pb.Communique{Union: &pb.Communique_Number{Number: 1337}},
+       },
+       {
+               src:  &pb.Communique{Union: &pb.Communique_Col{Col: pb.MyMessage_RED}},
+               dst:  &pb.Communique{},
+               want: &pb.Communique{Union: &pb.Communique_Col{Col: pb.MyMessage_RED}},
+       },
+       {
+               src:  &pb.Communique{Union: &pb.Communique_Data{Data: []byte("hello")}},
+               dst:  &pb.Communique{},
+               want: &pb.Communique{Union: &pb.Communique_Data{Data: []byte("hello")}},
+       },
+       {
+               src:  &pb.Communique{Union: &pb.Communique_Msg{Msg: &pb.Strings{BytesField: []byte{1, 2, 3}}}},
+               dst:  &pb.Communique{},
+               want: &pb.Communique{Union: &pb.Communique_Msg{Msg: &pb.Strings{BytesField: []byte{1, 2, 3}}}},
+       },
+       {
+               src:  &pb.Communique{Union: &pb.Communique_Msg{}},
+               dst:  &pb.Communique{},
+               want: &pb.Communique{Union: &pb.Communique_Msg{}},
+       },
+       {
+               src:  &pb.Communique{Union: &pb.Communique_Msg{Msg: &pb.Strings{StringField: proto.String("123")}}},
+               dst:  &pb.Communique{Union: &pb.Communique_Msg{Msg: &pb.Strings{BytesField: []byte{1, 2, 3}}}},
+               want: &pb.Communique{Union: &pb.Communique_Msg{Msg: &pb.Strings{StringField: proto.String("123"), BytesField: []byte{1, 2, 3}}}},
+       },
+       {
+               src: &proto3pb.Message{
+                       Terrain: map[string]*proto3pb.Nested{
+                               "kay_a": {Cute: true},      // replace
+                               "kay_b": {Bunny: "rabbit"}, // insert
+                       },
+               },
+               dst: &proto3pb.Message{
+                       Terrain: map[string]*proto3pb.Nested{
+                               "kay_a": {Bunny: "lost"},  // replaced
+                               "kay_c": {Bunny: "bunny"}, // keep
+                       },
+               },
+               want: &proto3pb.Message{
+                       Terrain: map[string]*proto3pb.Nested{
+                               "kay_a": {Cute: true},
+                               "kay_b": {Bunny: "rabbit"},
+                               "kay_c": {Bunny: "bunny"},
+                       },
+               },
+       },
+       {
+               src: &pb.GoTest{
+                       F_BoolRepeated:   []bool{},
+                       F_Int32Repeated:  []int32{},
+                       F_Int64Repeated:  []int64{},
+                       F_Uint32Repeated: []uint32{},
+                       F_Uint64Repeated: []uint64{},
+                       F_FloatRepeated:  []float32{},
+                       F_DoubleRepeated: []float64{},
+                       F_StringRepeated: []string{},
+                       F_BytesRepeated:  [][]byte{},
+               },
+               dst: &pb.GoTest{},
+               want: &pb.GoTest{
+                       F_BoolRepeated:   []bool{},
+                       F_Int32Repeated:  []int32{},
+                       F_Int64Repeated:  []int64{},
+                       F_Uint32Repeated: []uint32{},
+                       F_Uint64Repeated: []uint64{},
+                       F_FloatRepeated:  []float32{},
+                       F_DoubleRepeated: []float64{},
+                       F_StringRepeated: []string{},
+                       F_BytesRepeated:  [][]byte{},
+               },
+       },
+       {
+               src: &pb.GoTest{},
+               dst: &pb.GoTest{
+                       F_BoolRepeated:   []bool{},
+                       F_Int32Repeated:  []int32{},
+                       F_Int64Repeated:  []int64{},
+                       F_Uint32Repeated: []uint32{},
+                       F_Uint64Repeated: []uint64{},
+                       F_FloatRepeated:  []float32{},
+                       F_DoubleRepeated: []float64{},
+                       F_StringRepeated: []string{},
+                       F_BytesRepeated:  [][]byte{},
+               },
+               want: &pb.GoTest{
+                       F_BoolRepeated:   []bool{},
+                       F_Int32Repeated:  []int32{},
+                       F_Int64Repeated:  []int64{},
+                       F_Uint32Repeated: []uint32{},
+                       F_Uint64Repeated: []uint64{},
+                       F_FloatRepeated:  []float32{},
+                       F_DoubleRepeated: []float64{},
+                       F_StringRepeated: []string{},
+                       F_BytesRepeated:  [][]byte{},
+               },
+       },
+       {
+               src: &pb.GoTest{
+                       F_BytesRepeated: [][]byte{nil, {}, {0}},
+               },
+               dst: &pb.GoTest{},
+               want: &pb.GoTest{
+                       F_BytesRepeated: [][]byte{nil, {}, {0}},
+               },
+       },
+       {
+               src: &pb.MyMessage{
+                       Others: []*pb.OtherMessage{},
+               },
+               dst: &pb.MyMessage{},
+               want: &pb.MyMessage{
+                       Others: []*pb.OtherMessage{},
+               },
+       },
+}
+
+func TestMerge(t *testing.T) {
+       for _, m := range mergeTests {
+               got := proto.Clone(m.dst)
+               if !proto.Equal(got, m.dst) {
+                       t.Errorf("Clone()\ngot  %v\nwant %v", got, m.dst)
+                       continue
+               }
+               proto.Merge(got, m.src)
+               if !proto.Equal(got, m.want) {
+                       t.Errorf("Merge(%v, %v)\ngot  %v\nwant %v", m.dst, m.src, got, m.want)
+               }
+       }
+}