-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathonce_test.go
93 lines (88 loc) · 2.01 KB
/
once_test.go
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
package sync
import (
"errors"
"reflect"
"testing"
)
var oops = errors.New("oops")
func TestOnceFuncReflect(t *testing.T) {
var calls int
check := func() {
if calls > 0 {
panic("function called more than once")
}
calls++
}
for _, c := range []struct {
f any
want []any
}{
{func() { check() }, nil},
{func() int { check(); return 42 }, []any{42}},
{func() (int, error) { check(); return 42, oops }, []any{42, oops}},
} {
t.Run(reflect.TypeOf(c.f).String(), func(t *testing.T) {
calls = 0
fn := OnceFuncReflect(c.f)
for j := 0; j < 2; j++ {
got := reflect.ValueOf(fn).Call(nil)
if len(got) != len(c.want) {
t.Fatalf("got %d results, want %d", len(got), len(c.want))
}
for i, v := range got {
if g, w := v.Interface(), c.want[i]; g != w {
t.Fatalf("result %d is %v, want %v", i, g, w)
}
}
}
})
}
}
func BenchmarkOnceFunc(b *testing.B) {
b.Run("Func", func(b *testing.B) {
fn := OnceFunc(func() {})
for i := 0; i < b.N; i++ {
fn()
}
})
b.Run("Value", func(b *testing.B) {
fn := OnceValue(func() int { return 42 })
for i := 0; i < b.N; i++ {
if v := fn(); v != 42 {
b.Fatalf("got %v, want 42", v)
}
}
})
b.Run("Values", func(b *testing.B) {
fn := OnceValues(func() (int, error) { return 42, oops })
for i := 0; i < b.N; i++ {
if v, err := fn(); v != 42 || err != oops {
b.Fatalf("got %v, %v, want 42, oops", v, err)
}
}
})
}
func BenchmarkOnceFuncReflect(b *testing.B) {
b.Run("Func", func(b *testing.B) {
fn := OnceFuncReflect(func() {})
for i := 0; i < b.N; i++ {
fn()
}
})
b.Run("Value", func(b *testing.B) {
fn := OnceFuncReflect(func() int { return 42 })
for i := 0; i < b.N; i++ {
if v := fn(); v != 42 {
b.Fatalf("got %v, want 42", v)
}
}
})
b.Run("Values", func(b *testing.B) {
fn := OnceFuncReflect(func() (int, error) { return 42, oops })
for i := 0; i < b.N; i++ {
if v, err := fn(); v != 42 || err != oops {
b.Fatalf("got %v, %v, want 42, oops", v, err)
}
}
})
}