Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

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}