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