1// Copyright 2017, The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE.md file. 4 5package teststructs 6 7import ( 8 "time" 9 10 pb "github.com/google/go-cmp/cmp/internal/testprotos" 11) 12 13// This is an sanitized example of equality from a real use-case. 14// The original equality function was as follows: 15/* 16func equalEagle(x, y Eagle) bool { 17 if x.Name != y.Name && 18 !reflect.DeepEqual(x.Hounds, y.Hounds) && 19 x.Desc != y.Desc && 20 x.DescLong != y.DescLong && 21 x.Prong != y.Prong && 22 x.StateGoverner != y.StateGoverner && 23 x.PrankRating != y.PrankRating && 24 x.FunnyPrank != y.FunnyPrank && 25 !pb.Equal(x.Immutable.Proto(), y.Immutable.Proto()) { 26 return false 27 } 28 29 if len(x.Dreamers) != len(y.Dreamers) { 30 return false 31 } 32 for i := range x.Dreamers { 33 if !equalDreamer(x.Dreamers[i], y.Dreamers[i]) { 34 return false 35 } 36 } 37 if len(x.Slaps) != len(y.Slaps) { 38 return false 39 } 40 for i := range x.Slaps { 41 if !equalSlap(x.Slaps[i], y.Slaps[i]) { 42 return false 43 } 44 } 45 return true 46} 47func equalDreamer(x, y Dreamer) bool { 48 if x.Name != y.Name || 49 x.Desc != y.Desc || 50 x.DescLong != y.DescLong || 51 x.ContSlapsInterval != y.ContSlapsInterval || 52 x.Ornamental != y.Ornamental || 53 x.Amoeba != y.Amoeba || 54 x.Heroes != y.Heroes || 55 x.FloppyDisk != y.FloppyDisk || 56 x.MightiestDuck != y.MightiestDuck || 57 x.FunnyPrank != y.FunnyPrank || 58 !pb.Equal(x.Immutable.Proto(), y.Immutable.Proto()) { 59 60 return false 61 } 62 if len(x.Animal) != len(y.Animal) { 63 return false 64 } 65 for i := range x.Animal { 66 vx := x.Animal[i] 67 vy := y.Animal[i] 68 if reflect.TypeOf(x.Animal) != reflect.TypeOf(y.Animal) { 69 return false 70 } 71 switch vx.(type) { 72 case Goat: 73 if !equalGoat(vx.(Goat), vy.(Goat)) { 74 return false 75 } 76 case Donkey: 77 if !equalDonkey(vx.(Donkey), vy.(Donkey)) { 78 return false 79 } 80 default: 81 panic(fmt.Sprintf("unknown type: %T", vx)) 82 } 83 } 84 if len(x.PreSlaps) != len(y.PreSlaps) { 85 return false 86 } 87 for i := range x.PreSlaps { 88 if !equalSlap(x.PreSlaps[i], y.PreSlaps[i]) { 89 return false 90 } 91 } 92 if len(x.ContSlaps) != len(y.ContSlaps) { 93 return false 94 } 95 for i := range x.ContSlaps { 96 if !equalSlap(x.ContSlaps[i], y.ContSlaps[i]) { 97 return false 98 } 99 } 100 return true 101} 102func equalSlap(x, y Slap) bool { 103 return x.Name == y.Name && 104 x.Desc == y.Desc && 105 x.DescLong == y.DescLong && 106 pb.Equal(x.Args, y.Args) && 107 x.Tense == y.Tense && 108 x.Interval == y.Interval && 109 x.Homeland == y.Homeland && 110 x.FunnyPrank == y.FunnyPrank && 111 pb.Equal(x.Immutable.Proto(), y.Immutable.Proto()) 112} 113func equalGoat(x, y Goat) bool { 114 if x.Target != y.Target || 115 x.FunnyPrank != y.FunnyPrank || 116 !pb.Equal(x.Immutable.Proto(), y.Immutable.Proto()) { 117 return false 118 } 119 if len(x.Slaps) != len(y.Slaps) { 120 return false 121 } 122 for i := range x.Slaps { 123 if !equalSlap(x.Slaps[i], y.Slaps[i]) { 124 return false 125 } 126 } 127 return true 128} 129func equalDonkey(x, y Donkey) bool { 130 return x.Pause == y.Pause && 131 x.Sleep == y.Sleep && 132 x.FunnyPrank == y.FunnyPrank && 133 pb.Equal(x.Immutable.Proto(), y.Immutable.Proto()) 134} 135*/ 136 137type Eagle struct { 138 Name string 139 Hounds []string 140 Desc string 141 DescLong string 142 Dreamers []Dreamer 143 Prong int64 144 Slaps []Slap 145 StateGoverner string 146 PrankRating string 147 FunnyPrank string 148 Immutable *EagleImmutable 149} 150 151type EagleImmutable struct { 152 ID string 153 State *pb.Eagle_States 154 MissingCall *pb.Eagle_MissingCalls 155 Birthday time.Time 156 Death time.Time 157 Started time.Time 158 LastUpdate time.Time 159 Creator string 160 empty bool 161} 162 163type Dreamer struct { 164 Name string 165 Desc string 166 DescLong string 167 PreSlaps []Slap 168 ContSlaps []Slap 169 ContSlapsInterval int32 170 Animal []interface{} // Could be either Goat or Donkey 171 Ornamental bool 172 Amoeba int64 173 Heroes int32 174 FloppyDisk int32 175 MightiestDuck bool 176 FunnyPrank string 177 Immutable *DreamerImmutable 178} 179 180type DreamerImmutable struct { 181 ID string 182 State *pb.Dreamer_States 183 MissingCall *pb.Dreamer_MissingCalls 184 Calls int32 185 Started time.Time 186 Stopped time.Time 187 LastUpdate time.Time 188 empty bool 189} 190 191type Slap struct { 192 Name string 193 Desc string 194 DescLong string 195 Args pb.Message 196 Tense int32 197 Interval int32 198 Homeland uint32 199 FunnyPrank string 200 Immutable *SlapImmutable 201} 202 203type SlapImmutable struct { 204 ID string 205 Out pb.Message 206 MildSlap bool 207 PrettyPrint string 208 State *pb.Slap_States 209 Started time.Time 210 Stopped time.Time 211 LastUpdate time.Time 212 LoveRadius *LoveRadius 213 empty bool 214} 215 216type Goat struct { 217 Target string 218 Slaps []Slap 219 FunnyPrank string 220 Immutable *GoatImmutable 221} 222 223type GoatImmutable struct { 224 ID string 225 State *pb.Goat_States 226 Started time.Time 227 Stopped time.Time 228 LastUpdate time.Time 229 empty bool 230} 231type Donkey struct { 232 Pause bool 233 Sleep int32 234 FunnyPrank string 235 Immutable *DonkeyImmutable 236} 237 238type DonkeyImmutable struct { 239 ID string 240 State *pb.Donkey_States 241 Started time.Time 242 Stopped time.Time 243 LastUpdate time.Time 244 empty bool 245} 246 247type LoveRadius struct { 248 Summer *SummerLove 249 empty bool 250} 251 252type SummerLove struct { 253 Summary *SummerLoveSummary 254 empty bool 255} 256 257type SummerLoveSummary struct { 258 Devices []string 259 ChangeType []pb.SummerType 260 empty bool 261} 262 263func (EagleImmutable) Proto() *pb.Eagle { return nil } 264func (DreamerImmutable) Proto() *pb.Dreamer { return nil } 265func (SlapImmutable) Proto() *pb.Slap { return nil } 266func (GoatImmutable) Proto() *pb.Goat { return nil } 267func (DonkeyImmutable) Proto() *pb.Donkey { return nil } 268