| // Copyright 2017, The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package teststructs | |
| import ( | |
| "time" | |
| pb "github.com/google/go-cmp/cmp/internal/testprotos" | |
| ) | |
| // This is an sanitized example of equality from a real use-case. | |
| // The original equality function was as follows: | |
| /* | |
| func equalEagle(x, y Eagle) bool { | |
| if x.Name != y.Name && | |
| !reflect.DeepEqual(x.Hounds, y.Hounds) && | |
| x.Desc != y.Desc && | |
| x.DescLong != y.DescLong && | |
| x.Prong != y.Prong && | |
| x.StateGoverner != y.StateGoverner && | |
| x.PrankRating != y.PrankRating && | |
| x.FunnyPrank != y.FunnyPrank && | |
| !pb.Equal(x.Immutable.Proto(), y.Immutable.Proto()) { | |
| return false | |
| } | |
| if len(x.Dreamers) != len(y.Dreamers) { | |
| return false | |
| } | |
| for i := range x.Dreamers { | |
| if !equalDreamer(x.Dreamers[i], y.Dreamers[i]) { | |
| return false | |
| } | |
| } | |
| if len(x.Slaps) != len(y.Slaps) { | |
| return false | |
| } | |
| for i := range x.Slaps { | |
| if !equalSlap(x.Slaps[i], y.Slaps[i]) { | |
| return false | |
| } | |
| } | |
| return true | |
| } | |
| func equalDreamer(x, y Dreamer) bool { | |
| if x.Name != y.Name || | |
| x.Desc != y.Desc || | |
| x.DescLong != y.DescLong || | |
| x.ContSlapsInterval != y.ContSlapsInterval || | |
| x.Ornamental != y.Ornamental || | |
| x.Amoeba != y.Amoeba || | |
| x.Heroes != y.Heroes || | |
| x.FloppyDisk != y.FloppyDisk || | |
| x.MightiestDuck != y.MightiestDuck || | |
| x.FunnyPrank != y.FunnyPrank || | |
| !pb.Equal(x.Immutable.Proto(), y.Immutable.Proto()) { | |
| return false | |
| } | |
| if len(x.Animal) != len(y.Animal) { | |
| return false | |
| } | |
| for i := range x.Animal { | |
| vx := x.Animal[i] | |
| vy := y.Animal[i] | |
| if reflect.TypeOf(x.Animal) != reflect.TypeOf(y.Animal) { | |
| return false | |
| } | |
| switch vx.(type) { | |
| case Goat: | |
| if !equalGoat(vx.(Goat), vy.(Goat)) { | |
| return false | |
| } | |
| case Donkey: | |
| if !equalDonkey(vx.(Donkey), vy.(Donkey)) { | |
| return false | |
| } | |
| default: | |
| panic(fmt.Sprintf("unknown type: %T", vx)) | |
| } | |
| } | |
| if len(x.PreSlaps) != len(y.PreSlaps) { | |
| return false | |
| } | |
| for i := range x.PreSlaps { | |
| if !equalSlap(x.PreSlaps[i], y.PreSlaps[i]) { | |
| return false | |
| } | |
| } | |
| if len(x.ContSlaps) != len(y.ContSlaps) { | |
| return false | |
| } | |
| for i := range x.ContSlaps { | |
| if !equalSlap(x.ContSlaps[i], y.ContSlaps[i]) { | |
| return false | |
| } | |
| } | |
| return true | |
| } | |
| func equalSlap(x, y Slap) bool { | |
| return x.Name == y.Name && | |
| x.Desc == y.Desc && | |
| x.DescLong == y.DescLong && | |
| pb.Equal(x.Args, y.Args) && | |
| x.Tense == y.Tense && | |
| x.Interval == y.Interval && | |
| x.Homeland == y.Homeland && | |
| x.FunnyPrank == y.FunnyPrank && | |
| pb.Equal(x.Immutable.Proto(), y.Immutable.Proto()) | |
| } | |
| func equalGoat(x, y Goat) bool { | |
| if x.Target != y.Target || | |
| x.FunnyPrank != y.FunnyPrank || | |
| !pb.Equal(x.Immutable.Proto(), y.Immutable.Proto()) { | |
| return false | |
| } | |
| if len(x.Slaps) != len(y.Slaps) { | |
| return false | |
| } | |
| for i := range x.Slaps { | |
| if !equalSlap(x.Slaps[i], y.Slaps[i]) { | |
| return false | |
| } | |
| } | |
| return true | |
| } | |
| func equalDonkey(x, y Donkey) bool { | |
| return x.Pause == y.Pause && | |
| x.Sleep == y.Sleep && | |
| x.FunnyPrank == y.FunnyPrank && | |
| pb.Equal(x.Immutable.Proto(), y.Immutable.Proto()) | |
| } | |
| */ | |
| type Eagle struct { | |
| Name string | |
| Hounds []string | |
| Desc string | |
| DescLong string | |
| Dreamers []Dreamer | |
| Prong int64 | |
| Slaps []Slap | |
| StateGoverner string | |
| PrankRating string | |
| FunnyPrank string | |
| Immutable *EagleImmutable | |
| } | |
| type EagleImmutable struct { | |
| ID string | |
| State *pb.Eagle_States | |
| MissingCall *pb.Eagle_MissingCalls | |
| Birthday time.Time | |
| Death time.Time | |
| Started time.Time | |
| LastUpdate time.Time | |
| Creator string | |
| empty bool | |
| } | |
| type Dreamer struct { | |
| Name string | |
| Desc string | |
| DescLong string | |
| PreSlaps []Slap | |
| ContSlaps []Slap | |
| ContSlapsInterval int32 | |
| Animal []interface{} // Could be either Goat or Donkey | |
| Ornamental bool | |
| Amoeba int64 | |
| Heroes int32 | |
| FloppyDisk int32 | |
| MightiestDuck bool | |
| FunnyPrank string | |
| Immutable *DreamerImmutable | |
| } | |
| type DreamerImmutable struct { | |
| ID string | |
| State *pb.Dreamer_States | |
| MissingCall *pb.Dreamer_MissingCalls | |
| Calls int32 | |
| Started time.Time | |
| Stopped time.Time | |
| LastUpdate time.Time | |
| empty bool | |
| } | |
| type Slap struct { | |
| Name string | |
| Desc string | |
| DescLong string | |
| Args pb.Message | |
| Tense int32 | |
| Interval int32 | |
| Homeland uint32 | |
| FunnyPrank string | |
| Immutable *SlapImmutable | |
| } | |
| type SlapImmutable struct { | |
| ID string | |
| Out pb.Message | |
| MildSlap bool | |
| PrettyPrint string | |
| State *pb.Slap_States | |
| Started time.Time | |
| Stopped time.Time | |
| LastUpdate time.Time | |
| LoveRadius *LoveRadius | |
| empty bool | |
| } | |
| type Goat struct { | |
| Target string | |
| Slaps []Slap | |
| FunnyPrank string | |
| Immutable *GoatImmutable | |
| } | |
| type GoatImmutable struct { | |
| ID string | |
| State *pb.Goat_States | |
| Started time.Time | |
| Stopped time.Time | |
| LastUpdate time.Time | |
| empty bool | |
| } | |
| type Donkey struct { | |
| Pause bool | |
| Sleep int32 | |
| FunnyPrank string | |
| Immutable *DonkeyImmutable | |
| } | |
| type DonkeyImmutable struct { | |
| ID string | |
| State *pb.Donkey_States | |
| Started time.Time | |
| Stopped time.Time | |
| LastUpdate time.Time | |
| empty bool | |
| } | |
| type LoveRadius struct { | |
| Summer *SummerLove | |
| empty bool | |
| } | |
| type SummerLove struct { | |
| Summary *SummerLoveSummary | |
| empty bool | |
| } | |
| type SummerLoveSummary struct { | |
| Devices []string | |
| ChangeType []pb.SummerType | |
| empty bool | |
| } | |
| func (EagleImmutable) Proto() *pb.Eagle { return nil } | |
| func (DreamerImmutable) Proto() *pb.Dreamer { return nil } | |
| func (SlapImmutable) Proto() *pb.Slap { return nil } | |
| func (GoatImmutable) Proto() *pb.Goat { return nil } | |
| func (DonkeyImmutable) Proto() *pb.Donkey { return nil } |