package timer import ( "errors" "testing" "time" ) func TestTracker(t *testing.T) { tk := Start() time.Sleep(10 * time.Millisecond) tk.Record("step1") time.Sleep(20 * time.Millisecond) tk.Record("step2") laps := tk.Summarize() if len(laps) != 2 { t.Errorf("expected 2 laps, got %d", len(laps)) } if laps[0].Label != "step1" || laps[1].Label != "step2" { t.Errorf("invalid lap labels") } desc := tk.Describe() if desc == "" { t.Error("description should not be empty") } t.Log(desc) } func TestRetry(t *testing.T) { count := 0 err := Retry(func() error { count++ if count < 3 { return errors.New("fail") } return nil }, WithMaxRetries(3), WithBackoff(10*time.Millisecond, 2.0)) if err != nil { t.Errorf("expected success, got %v", err) } if count != 3 { t.Errorf("expected 3 attempts, got %d", count) } count = 0 err = Retry(func() error { count++ return errors.New("always fail") }, WithMaxRetries(2), WithBackoff(5*time.Millisecond, 2.0)) if err == nil { t.Error("expected error, got nil") } if count != 3 { // 0, 1, 2 = 3 times t.Errorf("expected 3 attempts, got %d", count) } } func TestTimeWheel(t *testing.T) { tw := NewTimeWheel(10*time.Millisecond, 10) tw.Start() defer tw.Stop() done := make(chan bool) start := time.Now() tw.AfterFunc(50*time.Millisecond, func() { duration := time.Since(start) if duration < 40*time.Millisecond { t.Errorf("too early: %v", duration) } done <- true }) select { case <-done: // success case <-time.After(200 * time.Millisecond): t.Fatal("timeout") } } func TestFlow(t *testing.T) { // Debounce test count := 0 d := NewDebouncer(20*time.Millisecond, func() { count++ }) d.Trigger() d.Trigger() d.Trigger() time.Sleep(50 * time.Millisecond) if count != 1 { t.Errorf("debounce failed, count: %d", count) } // Throttle test count = 0 tr := NewThrottler(20*time.Millisecond, func() { count++ }) tr.Trigger() tr.Trigger() tr.Trigger() time.Sleep(10 * time.Millisecond) if count != 1 { t.Errorf("throttle initial failed, count: %d", count) } time.Sleep(30 * time.Millisecond) tr.Trigger() time.Sleep(10 * time.Millisecond) if count != 2 { t.Errorf("throttle interval failed, count: %d", count) } } func TestRunTimeout(t *testing.T) { res, err := RunTimeout(50*time.Millisecond, func(tk *Tracker) (string, error) { tk.Record("start") time.Sleep(10 * time.Millisecond) tk.Record("middle") return "ok", nil }) if err != nil || res != "ok" { t.Errorf("RunTimeout failed: %v, %v", res, err) } _, err = RunTimeout(20*time.Millisecond, func(tk *Tracker) (string, error) { time.Sleep(50 * time.Millisecond) return "late", nil }) if err != ErrTimeout { t.Errorf("expected ErrTimeout, got %v", err) } }