// 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.md 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 }