1// Copyright 2024 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 reflect_test
6
7import (
8	"iter"
9	"maps"
10	. "reflect"
11	"testing"
12)
13
14func TestValueSeq(t *testing.T) {
15	m := map[string]int{
16		"1": 1,
17		"2": 2,
18		"3": 3,
19		"4": 4,
20	}
21	c := make(chan int, 3)
22	for i := range 3 {
23		c <- i
24	}
25	close(c)
26	tests := []struct {
27		name  string
28		val   Value
29		check func(*testing.T, iter.Seq[Value])
30	}{
31		{"int", ValueOf(4), func(t *testing.T, s iter.Seq[Value]) {
32			i := int64(0)
33			for v := range s {
34				if v.Int() != i {
35					t.Fatalf("got %d, want %d", v.Int(), i)
36				}
37				i++
38			}
39			if i != 4 {
40				t.Fatalf("should loop four times")
41			}
42		}},
43		{"int8", ValueOf(int8(4)), func(t *testing.T, s iter.Seq[Value]) {
44			i := int8(0)
45			for v := range s {
46				if v.Interface().(int8) != i {
47					t.Fatalf("got %d, want %d", v.Int(), i)
48				}
49				i++
50			}
51			if i != 4 {
52				t.Fatalf("should loop four times")
53			}
54		}},
55		{"uint", ValueOf(uint64(4)), func(t *testing.T, s iter.Seq[Value]) {
56			i := uint64(0)
57			for v := range s {
58				if v.Uint() != i {
59					t.Fatalf("got %d, want %d", v.Uint(), i)
60				}
61				i++
62			}
63			if i != 4 {
64				t.Fatalf("should loop four times")
65			}
66		}},
67		{"uint8", ValueOf(uint8(4)), func(t *testing.T, s iter.Seq[Value]) {
68			i := uint8(0)
69			for v := range s {
70				if v.Interface().(uint8) != i {
71					t.Fatalf("got %d, want %d", v.Int(), i)
72				}
73				i++
74			}
75			if i != 4 {
76				t.Fatalf("should loop four times")
77			}
78		}},
79		{"*[4]int", ValueOf(&[4]int{1, 2, 3, 4}), func(t *testing.T, s iter.Seq[Value]) {
80			i := int64(0)
81			for v := range s {
82				if v.Int() != i {
83					t.Fatalf("got %d, want %d", v.Int(), i)
84				}
85				i++
86			}
87			if i != 4 {
88				t.Fatalf("should loop four times")
89			}
90		}},
91		{"[4]int", ValueOf([4]int{1, 2, 3, 4}), func(t *testing.T, s iter.Seq[Value]) {
92			i := int64(0)
93			for v := range s {
94				if v.Int() != i {
95					t.Fatalf("got %d, want %d", v.Int(), i)
96				}
97				i++
98			}
99			if i != 4 {
100				t.Fatalf("should loop four times")
101			}
102		}},
103		{"[]int", ValueOf([]int{1, 2, 3, 4}), func(t *testing.T, s iter.Seq[Value]) {
104			i := int64(0)
105			for v := range s {
106				if v.Int() != i {
107					t.Fatalf("got %d, want %d", v.Int(), i)
108				}
109				i++
110			}
111			if i != 4 {
112				t.Fatalf("should loop four times")
113			}
114		}},
115		{"string", ValueOf("12语言"), func(t *testing.T, s iter.Seq[Value]) {
116			i := int64(0)
117			indexs := []int64{0, 1, 2, 5}
118			for v := range s {
119				if v.Int() != indexs[i] {
120					t.Fatalf("got %d, want %d", v.Int(), indexs[i])
121				}
122				i++
123			}
124			if i != 4 {
125				t.Fatalf("should loop four times")
126			}
127		}},
128		{"map[string]int", ValueOf(m), func(t *testing.T, s iter.Seq[Value]) {
129			i := int64(0)
130			copy := maps.Clone(m)
131			for v := range s {
132				if _, ok := copy[v.String()]; !ok {
133					t.Fatalf("unexpected %v", v.Interface())
134				}
135				delete(copy, v.String())
136				i++
137			}
138			if len(copy) != 0 {
139				t.Fatalf("should loop four times")
140			}
141		}},
142		{"chan int", ValueOf(c), func(t *testing.T, s iter.Seq[Value]) {
143			i := 0
144			m := map[int64]bool{
145				0: false,
146				1: false,
147				2: false,
148			}
149			for v := range s {
150				if b, ok := m[v.Int()]; !ok || b {
151					t.Fatalf("unexpected %v", v.Interface())
152				}
153				m[v.Int()] = true
154				i++
155			}
156			if i != 3 {
157				t.Fatalf("should loop three times")
158			}
159		}},
160		{"func", ValueOf(func(yield func(int) bool) {
161			for i := range 4 {
162				if !yield(i) {
163					return
164				}
165			}
166		}), func(t *testing.T, s iter.Seq[Value]) {
167			i := int64(0)
168			for v := range s {
169				if v.Int() != i {
170					t.Fatalf("got %d, want %d", v.Int(), i)
171				}
172				i++
173			}
174			if i != 4 {
175				t.Fatalf("should loop four times")
176			}
177		}},
178	}
179	for _, tc := range tests {
180		seq := tc.val.Seq()
181		tc.check(t, seq)
182	}
183}
184
185func TestValueSeq2(t *testing.T) {
186	m := map[string]int{
187		"1": 1,
188		"2": 2,
189		"3": 3,
190		"4": 4,
191	}
192	tests := []struct {
193		name  string
194		val   Value
195		check func(*testing.T, iter.Seq2[Value, Value])
196	}{
197		{"*[4]int", ValueOf(&[4]int{1, 2, 3, 4}), func(t *testing.T, s iter.Seq2[Value, Value]) {
198			i := int64(0)
199			for v1, v2 := range s {
200				if v1.Int() != i {
201					t.Fatalf("got %d, want %d", v1.Int(), i)
202				}
203				i++
204				if v2.Int() != i {
205					t.Fatalf("got %d, want %d", v2.Int(), i)
206				}
207			}
208			if i != 4 {
209				t.Fatalf("should loop four times")
210			}
211		}},
212		{"[4]int", ValueOf([4]int{1, 2, 3, 4}), func(t *testing.T, s iter.Seq2[Value, Value]) {
213			i := int64(0)
214			for v1, v2 := range s {
215				if v1.Int() != i {
216					t.Fatalf("got %d, want %d", v1.Int(), i)
217				}
218				i++
219				if v2.Int() != i {
220					t.Fatalf("got %d, want %d", v2.Int(), i)
221				}
222			}
223			if i != 4 {
224				t.Fatalf("should loop four times")
225			}
226		}},
227		{"[]int", ValueOf([]int{1, 2, 3, 4}), func(t *testing.T, s iter.Seq2[Value, Value]) {
228			i := int64(0)
229			for v1, v2 := range s {
230				if v1.Int() != i {
231					t.Fatalf("got %d, want %d", v1.Int(), i)
232				}
233				i++
234				if v2.Int() != i {
235					t.Fatalf("got %d, want %d", v2.Int(), i)
236				}
237			}
238			if i != 4 {
239				t.Fatalf("should loop four times")
240			}
241		}},
242		{"string", ValueOf("12语言"), func(t *testing.T, s iter.Seq2[Value, Value]) {
243			i := int64(0)
244			str := "12语言"
245			next, stop := iter.Pull2(s)
246			defer stop()
247			for j, s := range str {
248				v1, v2, ok := next()
249				if !ok {
250					t.Fatalf("should loop four times")
251				}
252				if v1.Int() != int64(j) {
253					t.Fatalf("got %d, want %d", v1.Int(), j)
254				}
255				if v2.Interface() != s {
256					t.Fatalf("got %v, want %v", v2.Interface(), s)
257				}
258				i++
259			}
260			if i != 4 {
261				t.Fatalf("should loop four times")
262			}
263		}},
264		{"map[string]int", ValueOf(m), func(t *testing.T, s iter.Seq2[Value, Value]) {
265			copy := maps.Clone(m)
266			for v1, v2 := range s {
267				v, ok := copy[v1.String()]
268				if !ok {
269					t.Fatalf("unexpected %v", v1.String())
270				}
271				if v != v2.Interface() {
272					t.Fatalf("got %v, want %d", v2.Interface(), v)
273				}
274				delete(copy, v1.String())
275			}
276			if len(copy) != 0 {
277				t.Fatalf("should loop four times")
278			}
279		}},
280		{"func", ValueOf(func(f func(int, int) bool) {
281			for i := range 4 {
282				f(i, i+1)
283			}
284		}), func(t *testing.T, s iter.Seq2[Value, Value]) {
285			i := int64(0)
286			for v1, v2 := range s {
287				if v1.Int() != i {
288					t.Fatalf("got %d, want %d", v1.Int(), i)
289				}
290				i++
291				if v2.Int() != i {
292					t.Fatalf("got %d, want %d", v2.Int(), i)
293				}
294			}
295			if i != 4 {
296				t.Fatalf("should loop four times")
297			}
298		}},
299	}
300	for _, tc := range tests {
301		seq := tc.val.Seq2()
302		tc.check(t, seq)
303	}
304}
305