1// Go support for Protocol Buffers - Google's data interchange format 2// 3// Copyright 2011 The Go Authors. All rights reserved. 4// https://github.com/golang/protobuf 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are 8// met: 9// 10// * Redistributions of source code must retain the above copyright 11// notice, this list of conditions and the following disclaimer. 12// * Redistributions in binary form must reproduce the above 13// copyright notice, this list of conditions and the following disclaimer 14// in the documentation and/or other materials provided with the 15// distribution. 16// * Neither the name of Google Inc. nor the names of its 17// contributors may be used to endorse or promote products derived from 18// this software without specific prior written permission. 19// 20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 32package proto_test 33 34import ( 35 "testing" 36 37 . "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto" 38 proto3pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto" 39 pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata" 40) 41 42// Four identical base messages. 43// The init function adds extensions to some of them. 44var messageWithoutExtension = &pb.MyMessage{Count: Int32(7)} 45var messageWithExtension1a = &pb.MyMessage{Count: Int32(7)} 46var messageWithExtension1b = &pb.MyMessage{Count: Int32(7)} 47var messageWithExtension2 = &pb.MyMessage{Count: Int32(7)} 48 49// Two messages with non-message extensions. 50var messageWithInt32Extension1 = &pb.MyMessage{Count: Int32(8)} 51var messageWithInt32Extension2 = &pb.MyMessage{Count: Int32(8)} 52 53func init() { 54 ext1 := &pb.Ext{Data: String("Kirk")} 55 ext2 := &pb.Ext{Data: String("Picard")} 56 57 // messageWithExtension1a has ext1, but never marshals it. 58 if err := SetExtension(messageWithExtension1a, pb.E_Ext_More, ext1); err != nil { 59 panic("SetExtension on 1a failed: " + err.Error()) 60 } 61 62 // messageWithExtension1b is the unmarshaled form of messageWithExtension1a. 63 if err := SetExtension(messageWithExtension1b, pb.E_Ext_More, ext1); err != nil { 64 panic("SetExtension on 1b failed: " + err.Error()) 65 } 66 buf, err := Marshal(messageWithExtension1b) 67 if err != nil { 68 panic("Marshal of 1b failed: " + err.Error()) 69 } 70 messageWithExtension1b.Reset() 71 if err := Unmarshal(buf, messageWithExtension1b); err != nil { 72 panic("Unmarshal of 1b failed: " + err.Error()) 73 } 74 75 // messageWithExtension2 has ext2. 76 if err := SetExtension(messageWithExtension2, pb.E_Ext_More, ext2); err != nil { 77 panic("SetExtension on 2 failed: " + err.Error()) 78 } 79 80 if err := SetExtension(messageWithInt32Extension1, pb.E_Ext_Number, Int32(23)); err != nil { 81 panic("SetExtension on Int32-1 failed: " + err.Error()) 82 } 83 if err := SetExtension(messageWithInt32Extension1, pb.E_Ext_Number, Int32(24)); err != nil { 84 panic("SetExtension on Int32-2 failed: " + err.Error()) 85 } 86} 87 88var EqualTests = []struct { 89 desc string 90 a, b Message 91 exp bool 92}{ 93 {"different types", &pb.GoEnum{}, &pb.GoTestField{}, false}, 94 {"equal empty", &pb.GoEnum{}, &pb.GoEnum{}, true}, 95 {"nil vs nil", nil, nil, true}, 96 {"typed nil vs typed nil", (*pb.GoEnum)(nil), (*pb.GoEnum)(nil), true}, 97 {"typed nil vs empty", (*pb.GoEnum)(nil), &pb.GoEnum{}, false}, 98 {"different typed nil", (*pb.GoEnum)(nil), (*pb.GoTestField)(nil), false}, 99 100 {"one set field, one unset field", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{}, false}, 101 {"one set field zero, one unset field", &pb.GoTest{Param: Int32(0)}, &pb.GoTest{}, false}, 102 {"different set fields", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{Label: String("bar")}, false}, 103 {"equal set", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{Label: String("foo")}, true}, 104 105 {"repeated, one set", &pb.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb.GoTest{}, false}, 106 {"repeated, different length", &pb.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb.GoTest{F_Int32Repeated: []int32{2}}, false}, 107 {"repeated, different value", &pb.GoTest{F_Int32Repeated: []int32{2}}, &pb.GoTest{F_Int32Repeated: []int32{3}}, false}, 108 {"repeated, equal", &pb.GoTest{F_Int32Repeated: []int32{2, 4}}, &pb.GoTest{F_Int32Repeated: []int32{2, 4}}, true}, 109 {"repeated, nil equal nil", &pb.GoTest{F_Int32Repeated: nil}, &pb.GoTest{F_Int32Repeated: nil}, true}, 110 {"repeated, nil equal empty", &pb.GoTest{F_Int32Repeated: nil}, &pb.GoTest{F_Int32Repeated: []int32{}}, true}, 111 {"repeated, empty equal nil", &pb.GoTest{F_Int32Repeated: []int32{}}, &pb.GoTest{F_Int32Repeated: nil}, true}, 112 113 { 114 "nested, different", 115 &pb.GoTest{RequiredField: &pb.GoTestField{Label: String("foo")}}, 116 &pb.GoTest{RequiredField: &pb.GoTestField{Label: String("bar")}}, 117 false, 118 }, 119 { 120 "nested, equal", 121 &pb.GoTest{RequiredField: &pb.GoTestField{Label: String("wow")}}, 122 &pb.GoTest{RequiredField: &pb.GoTestField{Label: String("wow")}}, 123 true, 124 }, 125 126 {"bytes", &pb.OtherMessage{Value: []byte("foo")}, &pb.OtherMessage{Value: []byte("foo")}, true}, 127 {"bytes, empty", &pb.OtherMessage{Value: []byte{}}, &pb.OtherMessage{Value: []byte{}}, true}, 128 {"bytes, empty vs nil", &pb.OtherMessage{Value: []byte{}}, &pb.OtherMessage{Value: nil}, false}, 129 { 130 "repeated bytes", 131 &pb.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}}, 132 &pb.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}}, 133 true, 134 }, 135 // In proto3, []byte{} and []byte(nil) are equal. 136 {"proto3 bytes, empty vs nil", &proto3pb.Message{Data: []byte{}}, &proto3pb.Message{Data: nil}, true}, 137 138 {"extension vs. no extension", messageWithoutExtension, messageWithExtension1a, false}, 139 {"extension vs. same extension", messageWithExtension1a, messageWithExtension1b, true}, 140 {"extension vs. different extension", messageWithExtension1a, messageWithExtension2, false}, 141 142 {"int32 extension vs. itself", messageWithInt32Extension1, messageWithInt32Extension1, true}, 143 {"int32 extension vs. a different int32", messageWithInt32Extension1, messageWithInt32Extension2, false}, 144 145 { 146 "message with group", 147 &pb.MyMessage{ 148 Count: Int32(1), 149 Somegroup: &pb.MyMessage_SomeGroup{ 150 GroupField: Int32(5), 151 }, 152 }, 153 &pb.MyMessage{ 154 Count: Int32(1), 155 Somegroup: &pb.MyMessage_SomeGroup{ 156 GroupField: Int32(5), 157 }, 158 }, 159 true, 160 }, 161 162 { 163 "map same", 164 &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, 165 &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, 166 true, 167 }, 168 { 169 "map different entry", 170 &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, 171 &pb.MessageWithMap{NameMapping: map[int32]string{2: "Rob"}}, 172 false, 173 }, 174 { 175 "map different key only", 176 &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, 177 &pb.MessageWithMap{NameMapping: map[int32]string{2: "Ken"}}, 178 false, 179 }, 180 { 181 "map different value only", 182 &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, 183 &pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}}, 184 false, 185 }, 186 { 187 "oneof same", 188 &pb.Communique{Union: &pb.Communique_Number{41}}, 189 &pb.Communique{Union: &pb.Communique_Number{41}}, 190 true, 191 }, 192 { 193 "oneof one nil", 194 &pb.Communique{Union: &pb.Communique_Number{41}}, 195 &pb.Communique{}, 196 false, 197 }, 198 { 199 "oneof different", 200 &pb.Communique{Union: &pb.Communique_Number{41}}, 201 &pb.Communique{Union: &pb.Communique_Name{"Bobby Tables"}}, 202 false, 203 }, 204} 205 206func TestEqual(t *testing.T) { 207 for _, tc := range EqualTests { 208 if res := Equal(tc.a, tc.b); res != tc.exp { 209 t.Errorf("%v: Equal(%v, %v) = %v, want %v", tc.desc, tc.a, tc.b, res, tc.exp) 210 } 211 } 212} 213