--- /dev/null
+// 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 }