1package funk
2
3import (
4	"errors"
5	"os"
6	"reflect"
7	"testing"
8	"time"
9
10	"github.com/stretchr/testify/assert"
11)
12
13var (
14	i     interface{}
15	zeros = []interface{}{
16		false,
17		byte(0),
18		complex64(0),
19		complex128(0),
20		float32(0),
21		float64(0),
22		int(0),
23		int8(0),
24		int16(0),
25		int32(0),
26		int64(0),
27		rune(0),
28		uint(0),
29		uint8(0),
30		uint16(0),
31		uint32(0),
32		uint64(0),
33		uintptr(0),
34		"",
35		[0]interface{}{},
36		[]interface{}(nil),
37		struct{ x int }{},
38		(*interface{})(nil),
39		(func())(nil),
40		nil,
41		interface{}(nil),
42		map[interface{}]interface{}(nil),
43		(chan interface{})(nil),
44		(<-chan interface{})(nil),
45		(chan<- interface{})(nil),
46	}
47	nonZeros = []interface{}{
48		true,
49		byte(1),
50		complex64(1),
51		complex128(1),
52		float32(1),
53		float64(1),
54		int(1),
55		int8(1),
56		int16(1),
57		int32(1),
58		int64(1),
59		rune(1),
60		uint(1),
61		uint8(1),
62		uint16(1),
63		uint32(1),
64		uint64(1),
65		uintptr(1),
66		"s",
67		[1]interface{}{1},
68		[]interface{}{},
69		struct{ x int }{1},
70		(*interface{})(&i),
71		(func())(func() {}),
72		interface{}(1),
73		map[interface{}]interface{}{},
74		(chan interface{})(make(chan interface{})),
75		(<-chan interface{})(make(chan interface{})),
76		(chan<- interface{})(make(chan interface{})),
77	}
78)
79
80func TestPtrOf(t *testing.T) {
81	is := assert.New(t)
82
83	type embedType struct {
84		value int
85	}
86
87	type anyType struct {
88		value    int
89		embed    embedType
90		embedPtr *embedType
91	}
92
93	any := anyType{value: 1}
94	anyPtr := &anyType{value: 1}
95
96	results := []interface{}{
97		PtrOf(any),
98		PtrOf(anyPtr),
99	}
100
101	for _, r := range results {
102		is.Equal(1, r.(*anyType).value)
103		is.Equal(reflect.ValueOf(r).Kind(), reflect.Ptr)
104		is.Equal(reflect.ValueOf(r).Type().Elem(), reflect.TypeOf(anyType{}))
105	}
106
107	anyWithEmbed := anyType{value: 1, embed: embedType{value: 2}}
108	anyWithEmbedPtr := anyType{value: 1, embedPtr: &embedType{value: 2}}
109
110	results = []interface{}{
111		PtrOf(anyWithEmbed.embed),
112		PtrOf(anyWithEmbedPtr.embedPtr),
113	}
114
115	for _, r := range results {
116		is.Equal(2, r.(*embedType).value)
117		is.Equal(reflect.ValueOf(r).Kind(), reflect.Ptr)
118		is.Equal(reflect.ValueOf(r).Type().Elem(), reflect.TypeOf(embedType{}))
119	}
120}
121
122func TestSliceOf(t *testing.T) {
123	is := assert.New(t)
124
125	f := &Foo{
126		ID:        1,
127		FirstName: "Dark",
128		LastName:  "Vador",
129		Age:       30,
130		Bar: &Bar{
131			Name: "Test",
132		},
133	}
134
135	result := SliceOf(f)
136
137	resultType := reflect.TypeOf(result)
138
139	is.True(resultType.Kind() == reflect.Slice)
140	is.True(resultType.Elem().Kind() == reflect.Ptr)
141
142	elemType := resultType.Elem().Elem()
143
144	is.True(elemType.Kind() == reflect.Struct)
145
146	value := reflect.ValueOf(result)
147
148	is.Equal(value.Len(), 1)
149
150	_, ok := value.Index(0).Interface().(*Foo)
151
152	is.True(ok)
153}
154
155func TestRandomInt(t *testing.T) {
156	is := assert.New(t)
157
158	is.True(RandomInt(0, 10) <= 10)
159}
160
161func TestShard(t *testing.T) {
162	is := assert.New(t)
163
164	tokey := "e89d66bdfdd4dd26b682cc77e23a86eb"
165
166	is.Equal(Shard(tokey, 1, 2, false), []string{"e", "8", "e89d66bdfdd4dd26b682cc77e23a86eb"})
167	is.Equal(Shard(tokey, 2, 2, false), []string{"e8", "9d", "e89d66bdfdd4dd26b682cc77e23a86eb"})
168	is.Equal(Shard(tokey, 2, 3, true), []string{"e8", "9d", "66", "bdfdd4dd26b682cc77e23a86eb"})
169}
170
171func TestRandomString(t *testing.T) {
172	is := assert.New(t)
173
174	is.Len(RandomString(10), 10)
175
176	result := RandomString(10, []rune("abcdefg"))
177
178	is.Len(result, 10)
179
180	for _, char := range result {
181		is.True(char >= []rune("a")[0] && char <= []rune("g")[0])
182	}
183}
184
185func TestIsEmpty(t *testing.T) {
186	is := assert.New(t)
187
188	chWithValue := make(chan struct{}, 1)
189	chWithValue <- struct{}{}
190	var tiP *time.Time
191	var tiNP time.Time
192	var s *string
193	var f *os.File
194	ptrs := new(string)
195	*ptrs = ""
196
197	is.True(IsEmpty(ptrs), "Nil string pointer is empty")
198	is.True(IsEmpty(""), "Empty string is empty")
199	is.True(IsEmpty(nil), "Nil is empty")
200	is.True(IsEmpty([]string{}), "Empty string array is empty")
201	is.True(IsEmpty(0), "Zero int value is empty")
202	is.True(IsEmpty(false), "False value is empty")
203	is.True(IsEmpty(make(chan struct{})), "Channel without values is empty")
204	is.True(IsEmpty(s), "Nil string pointer is empty")
205	is.True(IsEmpty(f), "Nil os.File pointer is empty")
206	is.True(IsEmpty(tiP), "Nil time.Time pointer is empty")
207	is.True(IsEmpty(tiNP), "time.Time is empty")
208
209	is.False(NotEmpty(ptrs), "Nil string pointer is empty")
210	is.False(NotEmpty(""), "Empty string is empty")
211	is.False(NotEmpty(nil), "Nil is empty")
212	is.False(NotEmpty([]string{}), "Empty string array is empty")
213	is.False(NotEmpty(0), "Zero int value is empty")
214	is.False(NotEmpty(false), "False value is empty")
215	is.False(NotEmpty(make(chan struct{})), "Channel without values is empty")
216	is.False(NotEmpty(s), "Nil string pointer is empty")
217	is.False(NotEmpty(f), "Nil os.File pointer is empty")
218	is.False(NotEmpty(tiP), "Nil time.Time pointer is empty")
219	is.False(NotEmpty(tiNP), "time.Time is empty")
220
221	is.False(IsEmpty("something"), "Non Empty string is not empty")
222	is.False(IsEmpty(errors.New("something")), "Non nil object is not empty")
223	is.False(IsEmpty([]string{"something"}), "Non empty string array is not empty")
224	is.False(IsEmpty(1), "Non-zero int value is not empty")
225	is.False(IsEmpty(true), "True value is not empty")
226	is.False(IsEmpty(chWithValue), "Channel with values is not empty")
227
228	is.True(NotEmpty("something"), "Non Empty string is not empty")
229	is.True(NotEmpty(errors.New("something")), "Non nil object is not empty")
230	is.True(NotEmpty([]string{"something"}), "Non empty string array is not empty")
231	is.True(NotEmpty(1), "Non-zero int value is not empty")
232	is.True(NotEmpty(true), "True value is not empty")
233	is.True(NotEmpty(chWithValue), "Channel with values is not empty")
234}
235
236func TestIsZero(t *testing.T) {
237	is := assert.New(t)
238
239	for _, test := range zeros {
240		is.True(IsZero(test))
241	}
242
243	for _, test := range nonZeros {
244		is.False(IsZero(test))
245	}
246}
247
248func TestAny(t *testing.T) {
249	is := assert.New(t)
250
251	is.True(Any(true, false))
252	is.True(Any(true, true))
253	is.False(Any(false, false))
254	is.False(Any("", nil, false))
255}
256
257func TestAll(t *testing.T) {
258	is := assert.New(t)
259
260	is.False(All(true, false))
261	is.True(All(true, true))
262	is.False(All(false, false))
263	is.False(All("", nil, false))
264	is.True(All("foo", true, 3))
265}
266
267func TestIsIteratee(t *testing.T) {
268	is := assert.New(t)
269
270	is.False(IsIteratee(nil))
271}
272
273func TestIsFunction(t *testing.T) {
274	is := assert.New(t)
275
276	is.False(IsFunction(nil))
277	is.False(IsFunction(""))
278	is.True(IsFunction(func() {}))
279	is.True(IsFunction(func(string, string, string) bool { return false }, 3))
280	is.False(IsFunction(func(string, string, string) bool { return false }, 3, 0))
281	is.True(IsFunction(func(string, string, string) (bool, error) { return false, nil }, 3, 2))
282}
283
284func TestIsPredicate(t *testing.T) {
285	is := assert.New(t)
286
287	is.False(IsPredicate(nil))
288	is.False(IsPredicate(""))
289	is.False(IsPredicate(func() {}))
290	is.False(IsPredicate(func() bool { return false}))
291	is.True(IsPredicate(func(int) bool { return false}))
292	is.True(IsPredicate(func(int) bool { return false}, nil))
293	is.False(IsPredicate(func(int) bool { return false}, reflect.TypeOf("")))
294	is.True(IsPredicate(func(int) bool { return false}, reflect.TypeOf(0)))
295	is.False(IsPredicate(func(int, string) bool { return false}, reflect.TypeOf("")))
296	is.False(IsPredicate(func(int, string) bool { return false}, reflect.TypeOf(""), reflect.TypeOf(0)))
297	is.True(IsPredicate(func(int, string) bool { return false}, reflect.TypeOf(0), reflect.TypeOf("")))
298	is.False(IsPredicate(func(struct{}, string) bool { return false}, reflect.TypeOf(0), reflect.TypeOf("")))
299	is.True(IsPredicate(func(struct{}, string) bool { return false}, nil, reflect.TypeOf("")))
300}
301