-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathflat_map_test.go
More file actions
181 lines (145 loc) · 4.63 KB
/
Copy pathflat_map_test.go
File metadata and controls
181 lines (145 loc) · 4.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package enumerators_test
import (
"testing"
"github.com/fgrzl/enumerators"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestFlatMap_BasicFlattening(t *testing.T) {
// Arrange
input := enumerators.Slice([][]int{{1, 2}, {3, 4}, {5}})
// Act
flattened := enumerators.FlatMap(input, enumerators.Slice[int])
result, err := enumerators.ToSlice(flattened)
// Assert
assert.NoError(t, err)
assert.Equal(t, []int{1, 2, 3, 4, 5}, result)
}
func TestFlatMap_EmptyInput(t *testing.T) {
// Arrange
input := enumerators.Slice([][]int{})
// Act
flattened := enumerators.FlatMap(input, enumerators.Slice[int])
result, err := enumerators.ToSlice(flattened)
// Assert
assert.NoError(t, err)
assert.Empty(t, result)
}
func TestFlatMap_EmptySubSequences(t *testing.T) {
// Arrange
input := enumerators.Slice([][]int{{1, 2}, {}, {3, 4}})
// Act
flattened := enumerators.FlatMap(input, enumerators.Slice[int])
result, err := enumerators.ToSlice(flattened)
// Assert
assert.NoError(t, err)
assert.Equal(t, []int{1, 2, 3, 4}, result) // Empty slice is skipped
}
func TestFlatMap_SingleElement(t *testing.T) {
// Arrange
input := enumerators.Slice([][]string{{"hello", "world"}})
// Act
flattened := enumerators.FlatMap(input, enumerators.Slice[string])
result, err := enumerators.ToSlice(flattened)
// Assert
assert.NoError(t, err)
assert.Equal(t, []string{"hello", "world"}, result)
}
func TestFlatMap_StringToChars(t *testing.T) {
// Arrange
input := enumerators.Slice([]string{"hi", "go"})
stringToChars := func(s string) enumerators.Enumerator[rune] {
runes := []rune(s)
return enumerators.Slice(runes)
}
// Act
flattened := enumerators.FlatMap(input, stringToChars)
result, err := enumerators.ToSlice(flattened)
// Assert
assert.NoError(t, err)
assert.Equal(t, []rune{'h', 'i', 'g', 'o'}, result)
}
func TestFlatMap_NumberToRange(t *testing.T) {
// Arrange
input := enumerators.Slice([]int{2, 3})
numberToRange := func(n int) enumerators.Enumerator[int] {
return enumerators.Range(0, n, func(i int) int { return i })
}
// Act
flattened := enumerators.FlatMap(input, numberToRange)
result, err := enumerators.ToSlice(flattened)
// Assert
assert.NoError(t, err)
assert.Equal(t, []int{0, 1, 0, 1, 2}, result) // Range(0,2) + Range(0,3)
}
func TestFlatMap_StepByStep(t *testing.T) {
// Arrange
input := enumerators.Slice([][]int{{10, 20}, {30}})
flattened := enumerators.FlatMap(input, enumerators.Slice[int])
// Act & Assert
assert.True(t, flattened.MoveNext())
current, err := flattened.Current()
require.NoError(t, err)
assert.Equal(t, 10, current)
assert.True(t, flattened.MoveNext())
current, err = flattened.Current()
require.NoError(t, err)
assert.Equal(t, 20, current)
assert.True(t, flattened.MoveNext())
current, err = flattened.Current()
require.NoError(t, err)
assert.Equal(t, 30, current)
assert.False(t, flattened.MoveNext())
assert.NoError(t, flattened.Err())
}
func TestFlatMap_DisposesSubEnumerators(t *testing.T) {
// Arrange
disposed1 := false
disposed2 := false
input := enumerators.Slice([]int{1, 2})
createEnum := func(n int) enumerators.Enumerator[int] {
var cleanup func()
if n == 1 {
cleanup = func() { disposed1 = true }
} else {
cleanup = func() { disposed2 = true }
}
return enumerators.Cleanup(
enumerators.Slice([]int{n * 10}),
cleanup,
)
}
// Act
flattened := enumerators.FlatMap(input, createEnum)
result, err := enumerators.ToSlice(flattened)
// Assert
assert.NoError(t, err)
assert.Equal(t, []int{10, 20}, result)
assert.True(t, disposed1, "First sub-enumerator should be disposed")
assert.True(t, disposed2, "Second sub-enumerator should be disposed")
}
func TestFlatMap_Dispose(t *testing.T) {
// Arrange
input := enumerators.Slice([][]int{{1, 2}, {3, 4}})
flattened := enumerators.FlatMap(input, enumerators.Slice[int])
// Move to start working with sub-enumerator
assert.True(t, flattened.MoveNext())
// Act
flattened.Dispose() // Should dispose base and current sub-enumerator
// Assert - should not panic, and the functionality should still work for testing
// (though in practice, using after dispose is not recommended)
current, err := flattened.Current()
require.NoError(t, err)
assert.Equal(t, 1, current)
}
func TestFlatMap_CurrentBeforeMoveNext(t *testing.T) {
// Arrange
input := enumerators.Slice([][]int{{1, 2}})
flattened := enumerators.FlatMap(input, enumerators.Slice[int])
// Act - calling Current before MoveNext should return error
current, err := flattened.Current()
// Assert
assert.Error(t, err)
assert.Equal(t, 0, current) // zero value for int
assert.Contains(t, err.Error(), "no current item")
}