|
|
@@ -6,7 +6,10 @@ package syncs
|
|
|
|
|
|
import (
|
|
|
"context"
|
|
|
+ "sync"
|
|
|
"testing"
|
|
|
+
|
|
|
+ "github.com/google/go-cmp/cmp"
|
|
|
)
|
|
|
|
|
|
func TestWaitGroupChan(t *testing.T) {
|
|
|
@@ -73,3 +76,66 @@ func TestSemaphore(t *testing.T) {
|
|
|
s.Release()
|
|
|
s.Release()
|
|
|
}
|
|
|
+
|
|
|
+func TestMap(t *testing.T) {
|
|
|
+ var m Map[string, int]
|
|
|
+ if v, ok := m.Load("noexist"); v != 0 || ok {
|
|
|
+ t.Errorf(`Load("noexist") = (%v, %v), want (0, false)`, v, ok)
|
|
|
+ }
|
|
|
+ m.Store("one", 1)
|
|
|
+ if v, ok := m.LoadOrStore("one", -1); v != 1 || !ok {
|
|
|
+ t.Errorf(`LoadOrStore("one", 1) = (%v, %v), want (1, true)`, v, ok)
|
|
|
+ }
|
|
|
+ if v, ok := m.Load("one"); v != 1 || !ok {
|
|
|
+ t.Errorf(`Load("one") = (%v, %v), want (1, true)`, v, ok)
|
|
|
+ }
|
|
|
+ if v, ok := m.LoadOrStore("two", 2); v != 2 || ok {
|
|
|
+ t.Errorf(`LoadOrStore("two", 2) = (%v, %v), want (2, false)`, v, ok)
|
|
|
+ }
|
|
|
+ got := map[string]int{}
|
|
|
+ want := map[string]int{"one": 1, "two": 2}
|
|
|
+ m.Range(func(k string, v int) bool {
|
|
|
+ got[k] = v
|
|
|
+ return true
|
|
|
+ })
|
|
|
+ if d := cmp.Diff(got, want); d != "" {
|
|
|
+ t.Errorf("Range mismatch (-got +want):\n%s", d)
|
|
|
+ }
|
|
|
+ if v, ok := m.LoadAndDelete("two"); v != 2 || !ok {
|
|
|
+ t.Errorf(`LoadAndDelete("two) = (%v, %v), want (2, true)`, v, ok)
|
|
|
+ }
|
|
|
+ if v, ok := m.LoadAndDelete("two"); v != 0 || ok {
|
|
|
+ t.Errorf(`LoadAndDelete("two) = (%v, %v), want (0, false)`, v, ok)
|
|
|
+ }
|
|
|
+ m.Delete("one")
|
|
|
+ m.Delete("noexist")
|
|
|
+ got = map[string]int{}
|
|
|
+ want = map[string]int{}
|
|
|
+ m.Range(func(k string, v int) bool {
|
|
|
+ got[k] = v
|
|
|
+ return true
|
|
|
+ })
|
|
|
+ if d := cmp.Diff(got, want); d != "" {
|
|
|
+ t.Errorf("Range mismatch (-got +want):\n%s", d)
|
|
|
+ }
|
|
|
+
|
|
|
+ t.Run("LoadOrStore", func(t *testing.T) {
|
|
|
+ var m Map[string, string]
|
|
|
+ var wg sync.WaitGroup
|
|
|
+ wg.Add(2)
|
|
|
+ var ok1, ok2 bool
|
|
|
+ go func() {
|
|
|
+ defer wg.Done()
|
|
|
+ _, ok1 = m.LoadOrStore("", "")
|
|
|
+ }()
|
|
|
+ go func() {
|
|
|
+ defer wg.Done()
|
|
|
+ _, ok2 = m.LoadOrStore("", "")
|
|
|
+ }()
|
|
|
+ wg.Wait()
|
|
|
+
|
|
|
+ if ok1 == ok2 {
|
|
|
+ t.Errorf("exactly one LoadOrStore should load")
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|