once_test.gno
4.45 Kb ยท 231 lines
1package once
2
3import (
4 "errors"
5 "testing"
6)
7
8func TestOnce_Do(t *testing.T) {
9 counter := 0
10 once := New()
11
12 increment := func() {
13 counter++
14 }
15
16 // First call should execute
17 once.Do(increment)
18 if counter != 1 {
19 t.Errorf("expected counter to be 1, got %d", counter)
20 }
21
22 // Second call should not execute
23 once.Do(increment)
24 if counter != 1 {
25 t.Errorf("expected counter to still be 1, got %d", counter)
26 }
27}
28
29func TestOnce_DoErr(t *testing.T) {
30 once := New()
31 expectedErr := errors.New("test error")
32
33 fn := func() error {
34 return expectedErr
35 }
36
37 // First call should return error
38 if err := once.DoErr(fn); err != expectedErr {
39 t.Errorf("expected error %v, got %v", expectedErr, err)
40 }
41
42 // Second call should return same error
43 if err := once.DoErr(fn); err != expectedErr {
44 t.Errorf("expected error %v, got %v", expectedErr, err)
45 }
46}
47
48func TestOnce_DoOrPanic(t *testing.T) {
49 once := New()
50 executed := false
51
52 fn := func() {
53 executed = true
54 }
55
56 // First call should execute
57 once.DoOrPanic(fn)
58 if !executed {
59 t.Error("function should have executed")
60 }
61
62 // Second call should panic
63 defer func() {
64 if r := recover(); r == nil {
65 t.Error("expected panic on second execution")
66 }
67 }()
68 once.DoOrPanic(fn)
69}
70
71func TestOnce_DoValue(t *testing.T) {
72 once := New()
73 expected := "test value"
74 counter := 0
75
76 fn := func() any {
77 counter++
78 return expected
79 }
80
81 // First call should return value
82 if result := once.DoValue(fn); result != expected {
83 t.Errorf("expected %v, got %v", expected, result)
84 }
85
86 // Second call should return cached value
87 if result := once.DoValue(fn); result != expected {
88 t.Errorf("expected %v, got %v", expected, result)
89 }
90
91 if counter != 1 {
92 t.Errorf("function should have executed only once, got %d executions", counter)
93 }
94}
95
96func TestOnce_DoValueErr(t *testing.T) {
97 once := New()
98 expectedVal := "test value"
99 expectedErr := errors.New("test error")
100 counter := 0
101
102 fn := func() (any, error) {
103 counter++
104 return expectedVal, expectedErr
105 }
106
107 // First call should return value and error
108 val, err := once.DoValueErr(fn)
109 if val != expectedVal || err != expectedErr {
110 t.Errorf("expected (%v, %v), got (%v, %v)", expectedVal, expectedErr, val, err)
111 }
112
113 // Second call should return cached value and error
114 val, err = once.DoValueErr(fn)
115 if val != expectedVal || err != expectedErr {
116 t.Errorf("expected (%v, %v), got (%v, %v)", expectedVal, expectedErr, val, err)
117 }
118
119 if counter != 1 {
120 t.Errorf("function should have executed only once, got %d executions", counter)
121 }
122}
123
124func TestOnce_Reset(t *testing.T) {
125 once := New()
126 counter := 0
127
128 fn := func() {
129 counter++
130 }
131
132 once.Do(fn)
133 if counter != 1 {
134 t.Errorf("expected counter to be 1, got %d", counter)
135 }
136
137 once.Reset()
138 once.Do(fn)
139 if counter != 2 {
140 t.Errorf("expected counter to be 2 after reset, got %d", counter)
141 }
142}
143
144func TestOnce_IsDone(t *testing.T) {
145 once := New()
146
147 if once.IsDone() {
148 t.Error("new Once instance should not be done")
149 }
150
151 once.Do(func() {})
152
153 if !once.IsDone() {
154 t.Error("Once instance should be done after execution")
155 }
156}
157
158func TestOnce_Error(t *testing.T) {
159 once := New()
160 expectedErr := errors.New("test error")
161
162 if err := once.Error(); err != nil {
163 t.Errorf("expected nil error, got %v", err)
164 }
165
166 once.DoErr(func() error {
167 return expectedErr
168 })
169
170 if err := once.Error(); err != expectedErr {
171 t.Errorf("expected error %v, got %v", expectedErr, err)
172 }
173}
174
175func TestOnce_Value(t *testing.T) {
176 once := New()
177
178 // Test unexecuted state
179 val, err := once.Value()
180 if err != ErrNotExecuted {
181 t.Errorf("expected ErrNotExecuted, got %v", err)
182 }
183 if val != nil {
184 t.Errorf("expected nil value, got %v", val)
185 }
186
187 // Test after execution
188 expected := "test value"
189 once.DoValue(func() any {
190 return expected
191 })
192
193 val, err = once.Value()
194 if err != nil {
195 t.Errorf("expected nil error, got %v", err)
196 }
197 if val != expected {
198 t.Errorf("expected value %v, got %v", expected, val)
199 }
200}
201
202func TestOnce_DoValueErr_Panic_MarkedDone(t *testing.T) {
203 once := New()
204 count := 0
205 fn := func() (any, error) {
206 count++
207 panic("panic")
208 }
209 var r any
210 func() {
211 defer func() { r = recover() }()
212 once.DoValueErr(fn)
213 }()
214 if r == nil {
215 t.Error("expected panic on first call")
216 }
217 if !once.IsDone() {
218 t.Error("expected once to be marked as done after panic")
219 }
220 r = nil
221 func() {
222 defer func() { r = recover() }()
223 once.DoValueErr(fn)
224 }()
225 if r != nil {
226 t.Error("expected no panic on subsequent call")
227 }
228 if count != 1 {
229 t.Errorf("expected count to be 1, got %d", count)
230 }
231}