Skip to content

Commit 1415093

Browse files
committed
refactor: simplify PointersOf function and enhance tests for various cases
1 parent 824e027 commit 1415093

2 files changed

Lines changed: 65 additions & 14 deletions

File tree

utils/slice/utils.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
package slice
22

33
import (
4-
"reflect"
54
"slices"
65
)
76

87
// PointersOf returns a slice of pointers to each element in the provided slice.
9-
func PointersOf(v any) any {
10-
in := reflect.ValueOf(v)
11-
out := reflect.MakeSlice(reflect.SliceOf(reflect.PointerTo(in.Type().Elem())), in.Len(), in.Len())
12-
for i := 0; i < in.Len(); i++ {
13-
out.Index(i).Set(in.Index(i).Addr())
14-
}
15-
return out.Interface()
8+
func PointersOf[S ~[]E, E any](v S) []*E {
9+
return Map(v, func(e E) *E { return &e })
1610
}
1711

1812
// Projects each element of a slice into a new form.

utils/slice/utils_test.go

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,69 @@ import (
1010
)
1111

1212
func Test_PointersOf(t *testing.T) {
13-
type testObj struct{ prop string }
14-
obj1 := testObj{prop: "obj1prop"}
15-
obj2 := testObj{prop: "obj2prop"}
16-
expected := []*testObj{&obj1, &obj2}
17-
actual := slice.PointersOf([]testObj{obj1, obj2})
18-
assert.Equal(t, expected, actual)
13+
type obj struct{ prop string }
14+
15+
t.Run("nil returns empty slice", func(t *testing.T) {
16+
result := slice.PointersOf[[]obj](nil)
17+
assert.Empty(t, result)
18+
})
19+
t.Run("empty slice", func(t *testing.T) {
20+
result := slice.PointersOf([]obj{})
21+
assert.Empty(t, result)
22+
})
23+
t.Run("single element", func(t *testing.T) {
24+
src := []obj{{"a"}}
25+
result := slice.PointersOf(src)
26+
assert.Len(t, result, 1)
27+
assert.Equal(t, src[0], *result[0])
28+
})
29+
t.Run("multiple elements length and values", func(t *testing.T) {
30+
src := []obj{{"a"}, {"b"}, {"c"}}
31+
result := slice.PointersOf(src)
32+
assert.Len(t, result, len(src))
33+
for i, p := range result {
34+
assert.Equal(t, src[i], *p)
35+
}
36+
})
37+
t.Run("pointers are distinct", func(t *testing.T) {
38+
src := []obj{{"x"}, {"x"}}
39+
result := slice.PointersOf(src)
40+
assert.NotSame(t, result[0], result[1])
41+
})
42+
t.Run("modifying source does not affect returned pointers", func(t *testing.T) {
43+
src := []obj{{"original"}}
44+
result := slice.PointersOf(src)
45+
src[0].prop = "mutated"
46+
assert.Equal(t, "original", result[0].prop)
47+
})
48+
t.Run("modifying returned pointer does not affect other pointers", func(t *testing.T) {
49+
src := []obj{{"a"}, {"b"}}
50+
result := slice.PointersOf(src)
51+
result[0].prop = "changed"
52+
assert.Equal(t, "b", result[1].prop)
53+
})
54+
t.Run("integer slice", func(t *testing.T) {
55+
src := []int{1, 2, 3}
56+
result := slice.PointersOf(src)
57+
assert.Len(t, result, 3)
58+
for i, p := range result {
59+
assert.Equal(t, src[i], *p)
60+
}
61+
})
62+
t.Run("string slice", func(t *testing.T) {
63+
src := []string{"foo", "bar"}
64+
result := slice.PointersOf(src)
65+
assert.Len(t, result, 2)
66+
assert.Equal(t, "foo", *result[0])
67+
assert.Equal(t, "bar", *result[1])
68+
})
69+
t.Run("order is preserved", func(t *testing.T) {
70+
src := []int{10, 20, 30, 40}
71+
result := slice.PointersOf(src)
72+
for i, p := range result {
73+
assert.Equal(t, src[i], *p)
74+
}
75+
})
1976
}
2077

2178
func Test_Map(t *testing.T) {

0 commit comments

Comments
 (0)