1package funk
2
3import (
4	"strings"
5	"testing"
6
7	"github.com/stretchr/testify/require"
8)
9
10func TestAllPredicates(t *testing.T) {
11	type args struct {
12		value      interface{}
13		predicates interface{}
14	}
15	tests := []struct {
16		name string
17		args args
18		want bool
19	}{
20		{
21			name: "Sanity string predicates",
22			args: args{
23				value: "test",
24				predicates: []func(string) bool{
25					func(v string) bool { return strings.Contains(v, "est") },
26					func(v string) bool { return len(v) < 10 },
27					func(v string) bool { return len(v) > 2 },
28				},
29			},
30			want: true,
31		},
32		{
33			name: "Sanity int predicates",
34			args: args{
35				value: 4,
36				predicates: []func(int) bool{
37					func(v int) bool { return v < 5 },
38					func(v int) bool { return v > 2 },
39				},
40			},
41			want: true,
42		},
43		{
44			name: "Failed predicate",
45			args: args{
46				value: "test",
47				predicates: []func(string) bool{
48					func(v string) bool { return strings.Contains(v, "est") },
49					func(v string) bool { return len(v) > 10 },
50					func(v string) bool { return len(v) > 2 },
51				},
52			},
53			want: false,
54		},
55	}
56	for _, tt := range tests {
57		t.Run(tt.name, func(t *testing.T) {
58			if got := AllPredicates(tt.args.value, tt.args.predicates); got != tt.want {
59				t.Errorf("AllPredicates() = %v, want %v", got, tt.want)
60			}
61		})
62	}
63}
64
65func TestAnyPredicates(t *testing.T) {
66	type args struct {
67		value      interface{}
68		predicates interface{}
69	}
70	tests := []struct {
71		name string
72		args args
73		want bool
74	}{
75		{
76			name: "Sanity string predicates",
77			args: args{
78				value: "test",
79				predicates: []func(string) bool{
80					func(v string) bool { return strings.Contains(v, "est") },
81					func(v string) bool { return len(v) > 10 },
82					func(v string) bool { return len(v) < 2 },
83				},
84			},
85			want: true,
86		},
87		{
88			name: "Sanity int predicates",
89			args: args{
90				value: 4,
91				predicates: []func(int) bool{
92					func(v int) bool { return v > 5 },
93					func(v int) bool { return v > 2 },
94				},
95			},
96			want: true,
97		},
98		{
99			name: "All failed predicate",
100			args: args{
101				value: "test",
102				predicates: []func(string) bool{
103					func(v string) bool { return !strings.Contains(v, "est") },
104					func(v string) bool { return len(v) > 10 },
105					func(v string) bool { return len(v) < 2 },
106				},
107			},
108			want: false,
109		},
110	}
111	for _, tt := range tests {
112		t.Run(tt.name, func(t *testing.T) {
113			if got := AnyPredicates(tt.args.value, tt.args.predicates); got != tt.want {
114				t.Errorf("AnyPredicates() = %v, want %v", got, tt.want)
115			}
116		})
117	}
118}
119
120func TestPredicatesImplPanics(t *testing.T) {
121	type args struct {
122		value        interface{}
123		wantedAnswer bool
124		predicates   interface{}
125	}
126	tests := []struct {
127		name string
128		args args
129	}{
130		{
131			name: "predicates are not collection",
132			args: args{
133				value:        nil,
134				wantedAnswer: false,
135				predicates:   nil,
136			},
137		},
138		{
139			name: "predicates are collection of strings",
140			args: args{
141				value:        nil,
142				wantedAnswer: false,
143				predicates:   []string{"hey"},
144			},
145		},
146		{
147			name: "predicate has 2 out parameters",
148			args: args{
149				value:        nil,
150				wantedAnswer: false,
151				predicates:   []func(string) (bool, error){ func(string) (bool, error){return true, nil}},
152			},
153		},
154		{
155			name: "predicate has out parameter of type string",
156			args: args{
157				value:        nil,
158				wantedAnswer: false,
159				predicates:   []func(string) string{ func(string) string{return ""}},
160			},
161		},
162		{
163			name: "predicate has 2 in parameters",
164			args: args{
165				value:        nil,
166				wantedAnswer: false,
167				predicates:   []func(string, bool) bool{ func(string, bool) bool{return true}},
168			},
169		},
170		{
171			name: "predicate has 0 in parameters",
172			args: args{
173				value:        nil,
174				wantedAnswer: false,
175				predicates:   []func() bool{ func() bool{return true}},
176			},
177		},
178		{
179			name: "value is not convertible to in parameter",
180			args: args{
181				value:        1,
182				wantedAnswer: false,
183				predicates:   []func(string) bool{ func(string) bool{return true}},
184			},
185		},
186	}
187	for _, tt := range tests {
188		t.Run(tt.name, func(t *testing.T) {
189			require.Panics(t, func() {predicatesImpl(tt.args.value, tt.args.wantedAnswer, tt.args.predicates)})
190		})
191	}
192}
193