package syncext import ( "context" "sync" "testing" "time" ) func TestAtomicBoolGetSet(t *testing.T) { b := NewAtomicBool(false) if b.Get() { t.Error("expected false") } old := b.Set(true) if old { t.Error("expected old value false") } if !b.Get() { t.Error("expected true") } old = b.Set(false) if !old { t.Error("expected old value true") } } func TestAtomicBoolWaitAlreadyMatching(t *testing.T) { b := NewAtomicBool(true) done := make(chan struct{}) go func() { b.Wait(true) close(done) }() select { case <-done: // ok case <-time.After(500 * time.Millisecond): t.Error("Wait should return immediately if value already matches") } } func TestAtomicBoolWaitWithTimeoutNoMatch(t *testing.T) { b := NewAtomicBool(false) err := b.WaitWithTimeout(50*time.Millisecond, true) if err == nil { t.Error("expected timeout error") } } func TestAtomicBoolWaitWithTimeoutMatchAfterSet(t *testing.T) { b := NewAtomicBool(false) go func() { time.Sleep(20 * time.Millisecond) b.Set(true) }() err := b.WaitWithTimeout(500*time.Millisecond, true) if err != nil { t.Errorf("expected nil, got %v", err) } } func TestAtomicBoolWaitWithContextCancel(t *testing.T) { b := NewAtomicBool(false) ctx, cancel := context.WithCancel(context.Background()) go func() { time.Sleep(20 * time.Millisecond) cancel() }() err := b.WaitWithContext(ctx, true) if err == nil { t.Error("expected ctx error") } } func TestAtomicBoolWaitWithContextAlreadyCancelled(t *testing.T) { b := NewAtomicBool(false) ctx, cancel := context.WithCancel(context.Background()) cancel() err := b.WaitWithContext(ctx, false) if err == nil { t.Error("expected ctx error") } } func TestAtomicBoolWaitWithContextMatching(t *testing.T) { b := NewAtomicBool(true) ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() err := b.WaitWithContext(ctx, true) if err != nil { t.Errorf("expected nil, got %v", err) } } func TestAtomicBoolConcurrentSet(t *testing.T) { b := NewAtomicBool(false) var wg sync.WaitGroup for i := 0; i < 50; i++ { wg.Add(1) go func(v bool) { defer wg.Done() b.Set(v) }(i%2 == 0) } wg.Wait() }