mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-04 19:17:47 +00:00
01d2ef327d
Signed-off-by: deadprogram <ron@hybridgroup.com>
160 lines
3.6 KiB
Go
160 lines
3.6 KiB
Go
// Copyright 2022 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package sync_test
|
|
|
|
import (
|
|
"sync"
|
|
"testing"
|
|
)
|
|
|
|
// We assume that the Once.Do tests have already covered parallelism.
|
|
|
|
func TestOnceFunc(t *testing.T) {
|
|
calls := 0
|
|
f := sync.OnceFunc(func() { calls++ })
|
|
allocs := testing.AllocsPerRun(10, f)
|
|
if calls != 1 {
|
|
t.Errorf("want calls==1, got %d", calls)
|
|
}
|
|
if allocs != 0 {
|
|
t.Errorf("want 0 allocations per call, got %v", allocs)
|
|
}
|
|
}
|
|
|
|
func TestOnceValue(t *testing.T) {
|
|
calls := 0
|
|
f := sync.OnceValue(func() int {
|
|
calls++
|
|
return calls
|
|
})
|
|
allocs := testing.AllocsPerRun(10, func() { f() })
|
|
value := f()
|
|
if calls != 1 {
|
|
t.Errorf("want calls==1, got %d", calls)
|
|
}
|
|
if value != 1 {
|
|
t.Errorf("want value==1, got %d", value)
|
|
}
|
|
if allocs != 0 {
|
|
t.Errorf("want 0 allocations per call, got %v", allocs)
|
|
}
|
|
}
|
|
|
|
func TestOnceValues(t *testing.T) {
|
|
calls := 0
|
|
f := sync.OnceValues(func() (int, int) {
|
|
calls++
|
|
return calls, calls + 1
|
|
})
|
|
allocs := testing.AllocsPerRun(10, func() { f() })
|
|
v1, v2 := f()
|
|
if calls != 1 {
|
|
t.Errorf("want calls==1, got %d", calls)
|
|
}
|
|
if v1 != 1 || v2 != 2 {
|
|
t.Errorf("want v1==1 and v2==2, got %d and %d", v1, v2)
|
|
}
|
|
if allocs != 0 {
|
|
t.Errorf("want 0 allocations per call, got %v", allocs)
|
|
}
|
|
}
|
|
|
|
// TODO: need to implement more complete panic handling for these tests.
|
|
// func testOncePanicX(t *testing.T, calls *int, f func()) {
|
|
// testOncePanicWith(t, calls, f, func(label string, p any) {
|
|
// if p != "x" {
|
|
// t.Fatalf("%s: want panic %v, got %v", label, "x", p)
|
|
// }
|
|
// })
|
|
// }
|
|
|
|
// func testOncePanicWith(t *testing.T, calls *int, f func(), check func(label string, p any)) {
|
|
// // Check that the each call to f panics with the same value, but the
|
|
// // underlying function is only called once.
|
|
// for _, label := range []string{"first time", "second time"} {
|
|
// var p any
|
|
// panicked := true
|
|
// func() {
|
|
// defer func() {
|
|
// p = recover()
|
|
// }()
|
|
// f()
|
|
// panicked = false
|
|
// }()
|
|
// if !panicked {
|
|
// t.Fatalf("%s: f did not panic", label)
|
|
// }
|
|
// check(label, p)
|
|
// }
|
|
// if *calls != 1 {
|
|
// t.Errorf("want calls==1, got %d", *calls)
|
|
// }
|
|
// }
|
|
|
|
// func TestOnceFuncPanic(t *testing.T) {
|
|
// calls := 0
|
|
// f := sync.OnceFunc(func() {
|
|
// calls++
|
|
// panic("x")
|
|
// })
|
|
// testOncePanicX(t, &calls, f)
|
|
// }
|
|
|
|
// func TestOnceValuePanic(t *testing.T) {
|
|
// calls := 0
|
|
// f := sync.OnceValue(func() int {
|
|
// calls++
|
|
// panic("x")
|
|
// })
|
|
// testOncePanicX(t, &calls, func() { f() })
|
|
// }
|
|
|
|
// func TestOnceValuesPanic(t *testing.T) {
|
|
// calls := 0
|
|
// f := sync.OnceValues(func() (int, int) {
|
|
// calls++
|
|
// panic("x")
|
|
// })
|
|
// testOncePanicX(t, &calls, func() { f() })
|
|
// }
|
|
//
|
|
// func TestOnceFuncPanicNil(t *testing.T) {
|
|
// calls := 0
|
|
// f := sync.OnceFunc(func() {
|
|
// calls++
|
|
// panic(nil)
|
|
// })
|
|
// testOncePanicWith(t, &calls, f, func(label string, p any) {
|
|
// switch p.(type) {
|
|
// case nil, *runtime.PanicNilError:
|
|
// return
|
|
// }
|
|
// t.Fatalf("%s: want nil panic, got %v", label, p)
|
|
// })
|
|
// }
|
|
//
|
|
// func TestOnceFuncGoexit(t *testing.T) {
|
|
// // If f calls Goexit, the results are unspecified. But check that f doesn't
|
|
// // get called twice.
|
|
// calls := 0
|
|
// f := sync.OnceFunc(func() {
|
|
// calls++
|
|
// runtime.Goexit()
|
|
// })
|
|
// var wg sync.WaitGroup
|
|
// for i := 0; i < 2; i++ {
|
|
// wg.Add(1)
|
|
// go func() {
|
|
// defer wg.Done()
|
|
// defer func() { recover() }()
|
|
// f()
|
|
// }()
|
|
// wg.Wait()
|
|
// }
|
|
// if calls != 1 {
|
|
// t.Errorf("want calls==1, got %d", calls)
|
|
// }
|
|
// }
|