1// Copyright 2009 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 file.
4
5package quick
6
7import (
8	"math/rand"
9	"reflect"
10	"testing"
11)
12
13func fArray(a [4]byte) [4]byte { return a }
14
15type TestArrayAlias [4]byte
16
17func fArrayAlias(a TestArrayAlias) TestArrayAlias { return a }
18
19func fBool(a bool) bool { return a }
20
21type TestBoolAlias bool
22
23func fBoolAlias(a TestBoolAlias) TestBoolAlias { return a }
24
25func fFloat32(a float32) float32 { return a }
26
27type TestFloat32Alias float32
28
29func fFloat32Alias(a TestFloat32Alias) TestFloat32Alias { return a }
30
31func fFloat64(a float64) float64 { return a }
32
33type TestFloat64Alias float64
34
35func fFloat64Alias(a TestFloat64Alias) TestFloat64Alias { return a }
36
37func fComplex64(a complex64) complex64 { return a }
38
39type TestComplex64Alias complex64
40
41func fComplex64Alias(a TestComplex64Alias) TestComplex64Alias { return a }
42
43func fComplex128(a complex128) complex128 { return a }
44
45type TestComplex128Alias complex128
46
47func fComplex128Alias(a TestComplex128Alias) TestComplex128Alias { return a }
48
49func fInt16(a int16) int16 { return a }
50
51type TestInt16Alias int16
52
53func fInt16Alias(a TestInt16Alias) TestInt16Alias { return a }
54
55func fInt32(a int32) int32 { return a }
56
57type TestInt32Alias int32
58
59func fInt32Alias(a TestInt32Alias) TestInt32Alias { return a }
60
61func fInt64(a int64) int64 { return a }
62
63type TestInt64Alias int64
64
65func fInt64Alias(a TestInt64Alias) TestInt64Alias { return a }
66
67func fInt8(a int8) int8 { return a }
68
69type TestInt8Alias int8
70
71func fInt8Alias(a TestInt8Alias) TestInt8Alias { return a }
72
73func fInt(a int) int { return a }
74
75type TestIntAlias int
76
77func fIntAlias(a TestIntAlias) TestIntAlias { return a }
78
79func fMap(a map[int]int) map[int]int { return a }
80
81type TestMapAlias map[int]int
82
83func fMapAlias(a TestMapAlias) TestMapAlias { return a }
84
85func fPtr(a *int) *int {
86	if a == nil {
87		return nil
88	}
89	b := *a
90	return &b
91}
92
93type TestPtrAlias *int
94
95func fPtrAlias(a TestPtrAlias) TestPtrAlias { return a }
96
97func fSlice(a []byte) []byte { return a }
98
99type TestSliceAlias []byte
100
101func fSliceAlias(a TestSliceAlias) TestSliceAlias { return a }
102
103func fString(a string) string { return a }
104
105type TestStringAlias string
106
107func fStringAlias(a TestStringAlias) TestStringAlias { return a }
108
109type TestStruct struct {
110	A int
111	B string
112}
113
114func fStruct(a TestStruct) TestStruct { return a }
115
116type TestStructAlias TestStruct
117
118func fStructAlias(a TestStructAlias) TestStructAlias { return a }
119
120func fUint16(a uint16) uint16 { return a }
121
122type TestUint16Alias uint16
123
124func fUint16Alias(a TestUint16Alias) TestUint16Alias { return a }
125
126func fUint32(a uint32) uint32 { return a }
127
128type TestUint32Alias uint32
129
130func fUint32Alias(a TestUint32Alias) TestUint32Alias { return a }
131
132func fUint64(a uint64) uint64 { return a }
133
134type TestUint64Alias uint64
135
136func fUint64Alias(a TestUint64Alias) TestUint64Alias { return a }
137
138func fUint8(a uint8) uint8 { return a }
139
140type TestUint8Alias uint8
141
142func fUint8Alias(a TestUint8Alias) TestUint8Alias { return a }
143
144func fUint(a uint) uint { return a }
145
146type TestUintAlias uint
147
148func fUintAlias(a TestUintAlias) TestUintAlias { return a }
149
150func fUintptr(a uintptr) uintptr { return a }
151
152type TestUintptrAlias uintptr
153
154func fUintptrAlias(a TestUintptrAlias) TestUintptrAlias { return a }
155
156func reportError(property string, err error, t *testing.T) {
157	if err != nil {
158		t.Errorf("%s: %s", property, err)
159	}
160}
161
162func TestCheckEqual(t *testing.T) {
163	reportError("fArray", CheckEqual(fArray, fArray, nil), t)
164	reportError("fArrayAlias", CheckEqual(fArrayAlias, fArrayAlias, nil), t)
165	reportError("fBool", CheckEqual(fBool, fBool, nil), t)
166	reportError("fBoolAlias", CheckEqual(fBoolAlias, fBoolAlias, nil), t)
167	reportError("fFloat32", CheckEqual(fFloat32, fFloat32, nil), t)
168	reportError("fFloat32Alias", CheckEqual(fFloat32Alias, fFloat32Alias, nil), t)
169	reportError("fFloat64", CheckEqual(fFloat64, fFloat64, nil), t)
170	reportError("fFloat64Alias", CheckEqual(fFloat64Alias, fFloat64Alias, nil), t)
171	reportError("fComplex64", CheckEqual(fComplex64, fComplex64, nil), t)
172	reportError("fComplex64Alias", CheckEqual(fComplex64Alias, fComplex64Alias, nil), t)
173	reportError("fComplex128", CheckEqual(fComplex128, fComplex128, nil), t)
174	reportError("fComplex128Alias", CheckEqual(fComplex128Alias, fComplex128Alias, nil), t)
175	reportError("fInt16", CheckEqual(fInt16, fInt16, nil), t)
176	reportError("fInt16Alias", CheckEqual(fInt16Alias, fInt16Alias, nil), t)
177	reportError("fInt32", CheckEqual(fInt32, fInt32, nil), t)
178	reportError("fInt32Alias", CheckEqual(fInt32Alias, fInt32Alias, nil), t)
179	reportError("fInt64", CheckEqual(fInt64, fInt64, nil), t)
180	reportError("fInt64Alias", CheckEqual(fInt64Alias, fInt64Alias, nil), t)
181	reportError("fInt8", CheckEqual(fInt8, fInt8, nil), t)
182	reportError("fInt8Alias", CheckEqual(fInt8Alias, fInt8Alias, nil), t)
183	reportError("fInt", CheckEqual(fInt, fInt, nil), t)
184	reportError("fIntAlias", CheckEqual(fIntAlias, fIntAlias, nil), t)
185	reportError("fInt32", CheckEqual(fInt32, fInt32, nil), t)
186	reportError("fInt32Alias", CheckEqual(fInt32Alias, fInt32Alias, nil), t)
187	reportError("fMap", CheckEqual(fMap, fMap, nil), t)
188	reportError("fMapAlias", CheckEqual(fMapAlias, fMapAlias, nil), t)
189	reportError("fPtr", CheckEqual(fPtr, fPtr, nil), t)
190	reportError("fPtrAlias", CheckEqual(fPtrAlias, fPtrAlias, nil), t)
191	reportError("fSlice", CheckEqual(fSlice, fSlice, nil), t)
192	reportError("fSliceAlias", CheckEqual(fSliceAlias, fSliceAlias, nil), t)
193	reportError("fString", CheckEqual(fString, fString, nil), t)
194	reportError("fStringAlias", CheckEqual(fStringAlias, fStringAlias, nil), t)
195	reportError("fStruct", CheckEqual(fStruct, fStruct, nil), t)
196	reportError("fStructAlias", CheckEqual(fStructAlias, fStructAlias, nil), t)
197	reportError("fUint16", CheckEqual(fUint16, fUint16, nil), t)
198	reportError("fUint16Alias", CheckEqual(fUint16Alias, fUint16Alias, nil), t)
199	reportError("fUint32", CheckEqual(fUint32, fUint32, nil), t)
200	reportError("fUint32Alias", CheckEqual(fUint32Alias, fUint32Alias, nil), t)
201	reportError("fUint64", CheckEqual(fUint64, fUint64, nil), t)
202	reportError("fUint64Alias", CheckEqual(fUint64Alias, fUint64Alias, nil), t)
203	reportError("fUint8", CheckEqual(fUint8, fUint8, nil), t)
204	reportError("fUint8Alias", CheckEqual(fUint8Alias, fUint8Alias, nil), t)
205	reportError("fUint", CheckEqual(fUint, fUint, nil), t)
206	reportError("fUintAlias", CheckEqual(fUintAlias, fUintAlias, nil), t)
207	reportError("fUintptr", CheckEqual(fUintptr, fUintptr, nil), t)
208	reportError("fUintptrAlias", CheckEqual(fUintptrAlias, fUintptrAlias, nil), t)
209}
210
211// This tests that ArbitraryValue is working by checking that all the arbitrary
212// values of type MyStruct have x = 42.
213type myStruct struct {
214	x int
215}
216
217func (m myStruct) Generate(r *rand.Rand, _ int) reflect.Value {
218	return reflect.ValueOf(myStruct{x: 42})
219}
220
221func myStructProperty(in myStruct) bool { return in.x == 42 }
222
223func TestCheckProperty(t *testing.T) {
224	reportError("myStructProperty", Check(myStructProperty, nil), t)
225}
226
227func TestFailure(t *testing.T) {
228	f := func(x int) bool { return false }
229	err := Check(f, nil)
230	if err == nil {
231		t.Errorf("Check didn't return an error")
232	}
233	if _, ok := err.(*CheckError); !ok {
234		t.Errorf("Error was not a CheckError: %s", err)
235	}
236
237	err = CheckEqual(fUint, fUint32, nil)
238	if err == nil {
239		t.Errorf("#1 CheckEqual didn't return an error")
240	}
241	if _, ok := err.(SetupError); !ok {
242		t.Errorf("#1 Error was not a SetupError: %s", err)
243	}
244
245	err = CheckEqual(func(x, y int) {}, func(x int) {}, nil)
246	if err == nil {
247		t.Errorf("#2 CheckEqual didn't return an error")
248	}
249	if _, ok := err.(SetupError); !ok {
250		t.Errorf("#2 Error was not a SetupError: %s", err)
251	}
252
253	err = CheckEqual(func(x int) int { return 0 }, func(x int) int32 { return 0 }, nil)
254	if err == nil {
255		t.Errorf("#3 CheckEqual didn't return an error")
256	}
257	if _, ok := err.(SetupError); !ok {
258		t.Errorf("#3 Error was not a SetupError: %s", err)
259	}
260}
261
262// Recursive data structures didn't terminate.
263// Issues 8818 and 11148.
264func TestRecursive(t *testing.T) {
265	type R struct {
266		Ptr      *R
267		SliceP   []*R
268		Slice    []R
269		Map      map[int]R
270		MapP     map[int]*R
271		MapR     map[*R]*R
272		SliceMap []map[int]R
273	}
274
275	f := func(r R) bool { return true }
276	Check(f, nil)
277}
278
279func TestEmptyStruct(t *testing.T) {
280	f := func(struct{}) bool { return true }
281	Check(f, nil)
282}
283
284type (
285	A struct{ B *B }
286	B struct{ A *A }
287)
288
289func TestMutuallyRecursive(t *testing.T) {
290	f := func(a A) bool { return true }
291	Check(f, nil)
292}
293
294// Some serialization formats (e.g. encoding/pem) cannot distinguish
295// between a nil and an empty map or slice, so avoid generating the
296// zero value for these.
297func TestNonZeroSliceAndMap(t *testing.T) {
298	type Q struct {
299		M map[int]int
300		S []int
301	}
302	f := func(q Q) bool {
303		return q.M != nil && q.S != nil
304	}
305	err := Check(f, nil)
306	if err != nil {
307		t.Fatal(err)
308	}
309}
310
311func TestInt64(t *testing.T) {
312	var lo, hi int64
313	f := func(x int64) bool {
314		if x < lo {
315			lo = x
316		}
317		if x > hi {
318			hi = x
319		}
320		return true
321	}
322	cfg := &Config{MaxCount: 10000}
323	Check(f, cfg)
324	if uint64(lo)>>62 == 0 || uint64(hi)>>62 == 0 {
325		t.Errorf("int64 returned range %#016x,%#016x; does not look like full range", lo, hi)
326	}
327}
328