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/gogo/protobuf/proto" 38 pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata" 39) 40 41// Four identical base messages. 42// The init function adds extensions to some of them. 43var messageWithoutExtension = &pb.MyMessage{Count: Int32(7)} 44var messageWithExtension1a = &pb.MyMessage{Count: Int32(7)} 45var messageWithExtension1b = &pb.MyMessage{Count: Int32(7)} 46var messageWithExtension2 = &pb.MyMessage{Count: Int32(7)} 47 48// Two messages with non-message extensions. 49var messageWithInt32Extension1 = &pb.MyMessage{Count: Int32(8)} 50var messageWithInt32Extension2 = &pb.MyMessage{Count: Int32(8)} 51 52func init() { 53 ext1 := &pb.Ext{Data: String("Kirk")} 54 ext2 := &pb.Ext{Data: String("Picard")} 55 56 // messageWithExtension1a has ext1, but never marshals it. 57 if err := SetExtension(messageWithExtension1a, pb.E_Ext_More, ext1); err != nil { 58 panic("SetExtension on 1a failed: " + err.Error()) 59 } 60 61 // messageWithExtension1b is the unmarshaled form of messageWithExtension1a. 62 if err := SetExtension(messageWithExtension1b, pb.E_Ext_More, ext1); err != nil { 63 panic("SetExtension on 1b failed: " + err.Error()) 64 } 65 buf, err := Marshal(messageWithExtension1b) 66 if err != nil { 67 panic("Marshal of 1b failed: " + err.Error()) 68 } 69 messageWithExtension1b.Reset() 70 if err := Unmarshal(buf, messageWithExtension1b); err != nil { 71 panic("Unmarshal of 1b failed: " + err.Error()) 72 } 73 74 // messageWithExtension2 has ext2. 75 if err := SetExtension(messageWithExtension2, pb.E_Ext_More, ext2); err != nil { 76 panic("SetExtension on 2 failed: " + err.Error()) 77 } 78 79 if err := SetExtension(messageWithInt32Extension1, pb.E_Ext_Number, Int32(23)); err != nil { 80 panic("SetExtension on Int32-1 failed: " + err.Error()) 81 } 82 if err := SetExtension(messageWithInt32Extension1, pb.E_Ext_Number, Int32(24)); err != nil { 83 panic("SetExtension on Int32-2 failed: " + err.Error()) 84 } 85} 86 87var EqualTests = []struct { 88 desc string 89 a, b Message 90 exp bool 91}{ 92 {"different types", &pb.GoEnum{}, &pb.GoTestField{}, false}, 93 {"equal empty", &pb.GoEnum{}, &pb.GoEnum{}, true}, 94 {"nil vs nil", nil, nil, true}, 95 {"typed nil vs typed nil", (*pb.GoEnum)(nil), (*pb.GoEnum)(nil), true}, 96 {"typed nil vs empty", (*pb.GoEnum)(nil), &pb.GoEnum{}, false}, 97 {"different typed nil", (*pb.GoEnum)(nil), (*pb.GoTestField)(nil), false}, 98 99 {"one set field, one unset field", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{}, false}, 100 {"one set field zero, one unset field", &pb.GoTest{Param: Int32(0)}, &pb.GoTest{}, false}, 101 {"different set fields", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{Label: String("bar")}, false}, 102 {"equal set", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{Label: String("foo")}, true}, 103 104 {"repeated, one set", &pb.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb.GoTest{}, false}, 105 {"repeated, different length", &pb.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb.GoTest{F_Int32Repeated: []int32{2}}, false}, 106 {"repeated, different value", &pb.GoTest{F_Int32Repeated: []int32{2}}, &pb.GoTest{F_Int32Repeated: []int32{3}}, false}, 107 {"repeated, equal", &pb.GoTest{F_Int32Repeated: []int32{2, 4}}, &pb.GoTest{F_Int32Repeated: []int32{2, 4}}, true}, 108 {"repeated, nil equal nil", &pb.GoTest{F_Int32Repeated: nil}, &pb.GoTest{F_Int32Repeated: nil}, true}, 109 {"repeated, nil equal empty", &pb.GoTest{F_Int32Repeated: nil}, &pb.GoTest{F_Int32Repeated: []int32{}}, true}, 110 {"repeated, empty equal nil", &pb.GoTest{F_Int32Repeated: []int32{}}, &pb.GoTest{F_Int32Repeated: nil}, true}, 111 112 { 113 "nested, different", 114 &pb.GoTest{RequiredField: &pb.GoTestField{Label: String("foo")}}, 115 &pb.GoTest{RequiredField: &pb.GoTestField{Label: String("bar")}}, 116 false, 117 }, 118 { 119 "nested, equal", 120 &pb.GoTest{RequiredField: &pb.GoTestField{Label: String("wow")}}, 121 &pb.GoTest{RequiredField: &pb.GoTestField{Label: String("wow")}}, 122 true, 123 }, 124 125 {"bytes", &pb.OtherMessage{Value: []byte("foo")}, &pb.OtherMessage{Value: []byte("foo")}, true}, 126 {"bytes, empty", &pb.OtherMessage{Value: []byte{}}, &pb.OtherMessage{Value: []byte{}}, true}, 127 {"bytes, empty vs nil", &pb.OtherMessage{Value: []byte{}}, &pb.OtherMessage{Value: nil}, false}, 128 { 129 "repeated bytes", 130 &pb.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}}, 131 &pb.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}}, 132 true, 133 }, 134 135 {"extension vs. no extension", messageWithoutExtension, messageWithExtension1a, false}, 136 {"extension vs. same extension", messageWithExtension1a, messageWithExtension1b, true}, 137 {"extension vs. different extension", messageWithExtension1a, messageWithExtension2, false}, 138 139 {"int32 extension vs. itself", messageWithInt32Extension1, messageWithInt32Extension1, true}, 140 {"int32 extension vs. a different int32", messageWithInt32Extension1, messageWithInt32Extension2, false}, 141 142 { 143 "message with group", 144 &pb.MyMessage{ 145 Count: Int32(1), 146 Somegroup: &pb.MyMessage_SomeGroup{ 147 GroupField: Int32(5), 148 }, 149 }, 150 &pb.MyMessage{ 151 Count: Int32(1), 152 Somegroup: &pb.MyMessage_SomeGroup{ 153 GroupField: Int32(5), 154 }, 155 }, 156 true, 157 }, 158 159 { 160 "map same", 161 &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, 162 &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, 163 true, 164 }, 165 { 166 "map different entry", 167 &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, 168 &pb.MessageWithMap{NameMapping: map[int32]string{2: "Rob"}}, 169 false, 170 }, 171 { 172 "map different key only", 173 &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, 174 &pb.MessageWithMap{NameMapping: map[int32]string{2: "Ken"}}, 175 false, 176 }, 177 { 178 "map different value only", 179 &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, 180 &pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}}, 181 false, 182 }, 183 { 184 "oneof same", 185 &pb.Communique{Union: &pb.Communique_Number{Number: 41}}, 186 &pb.Communique{Union: &pb.Communique_Number{Number: 41}}, 187 true, 188 }, 189 { 190 "oneof one nil", 191 &pb.Communique{Union: &pb.Communique_Number{Number: 41}}, 192 &pb.Communique{}, 193 false, 194 }, 195 { 196 "oneof different", 197 &pb.Communique{Union: &pb.Communique_Number{Number: 41}}, 198 &pb.Communique{Union: &pb.Communique_Name{Name: "Bobby Tables"}}, 199 false, 200 }, 201} 202 203func TestEqual(t *testing.T) { 204 for _, tc := range EqualTests { 205 if res := Equal(tc.a, tc.b); res != tc.exp { 206 t.Errorf("%v: Equal(%v, %v) = %v, want %v", tc.desc, tc.a, tc.b, res, tc.exp) 207 } 208 } 209} 210