package stats import ( "testing" "time" ) func TestConnectDisconnectCounts(t *testing.T) { c := NewCollector() c.Start() c.OnConnect("d1", "Alice") c.OnConnect("d2", "Bob") c.OnDisconnect("d1", 5000) s := c.Server() if s.CurrentClients != 1 { t.Errorf("CurrentClients: got %d", s.CurrentClients) } if s.PeakClients != 2 { t.Errorf("PeakClients: got %d", s.PeakClients) } if s.TotalConnections != 2 { t.Errorf("TotalConnections: got %d", s.TotalConnections) } if s.TotalDisconnects != 1 { t.Errorf("TotalDisconnects: got %d", s.TotalDisconnects) } if s.UptimeMs < 0 { t.Errorf("UptimeMs negative: %d", s.UptimeMs) } } func TestLapAndDriverProfile(t *testing.T) { c := NewCollector() c.Start() c.OnConnect("d1", "Alice") c.OnLapRecorded(LapRecord{RaceID: "r1", DriverID: "d1", LapMs: 12_345, TSMs: time.Now().UnixMilli()}) c.OnLapRecorded(LapRecord{RaceID: "r1", DriverID: "d1", LapMs: 11_500, TSMs: time.Now().UnixMilli()}) c.OnLapRecorded(LapRecord{RaceID: "r1", DriverID: "d1", LapMs: 13_000, TSMs: time.Now().UnixMilli()}) d := c.Driver("d1", "Alice") if d.TotalLaps != 3 { t.Errorf("TotalLaps: got %d", d.TotalLaps) } if d.BestLapMs != 11_500 { t.Errorf("BestLapMs: got %d", d.BestLapMs) } if d.LastLapMs != 13_000 { t.Errorf("LastLapMs: got %d", d.LastLapMs) } } func TestRaceFinishedUpdatesProfile(t *testing.T) { c := NewCollector() c.Start() c.OnConnect("d1", "Alice") c.OnConnect("d2", "Bob") c.OnRaceStarted([]string{"d1", "d2"}) c.OnRaceFinished(RaceResult{RaceID: "r1", DriverID: "d1", Position: 1, TotalLaps: 5, BestLapMs: 11_000, TotalTimeMs: 60_000}) c.OnRaceFinished(RaceResult{RaceID: "r1", DriverID: "d2", Position: 2, TotalLaps: 5, BestLapMs: 11_500, TotalTimeMs: 60_500}) d1 := c.Driver("d1", "") if d1.Wins != 1 { t.Errorf("Wins: got %d", d1.Wins) } if d1.BestLapMs != 11_000 { t.Errorf("BestLapMs: got %d", d1.BestLapMs) } d2 := c.Driver("d2", "") if d2.Wins != 0 || d2.Podiums != 1 { t.Errorf("Podiums: got %d", d2.Podiums) } s := c.Server() if s.TotalRacesStarted != 1 || s.TotalRacesFinished != 2 { t.Errorf("counters: started=%d finished=%d", s.TotalRacesStarted, s.TotalRacesFinished) } } func TestRTTWindowAverage(t *testing.T) { c := NewCollector() c.Start() for _, v := range []int64{10, 20, 30, 40, 50} { c.OnRTT(v) } s := c.Server() if s.AvgRTTMs != 30 { t.Errorf("AvgRTTMs: got %v want 30", s.AvgRTTMs) } if len(s.RecentRTTs) != 5 { t.Errorf("RecentRTTs len: got %d", len(s.RecentRTTs)) } } func TestRecentLapsOrder(t *testing.T) { c := NewCollector() c.Start() for i := 0; i < 5; i++ { c.OnLapRecorded(LapRecord{RaceID: "r1", DriverID: "d1", LapMs: int64(10_000 + i), TSMs: int64(i)}) } laps := c.RecentLaps(3) if len(laps) != 3 { t.Fatalf("got %d laps", len(laps)) } if laps[0].TSMs < laps[1].TSMs { t.Errorf("expected newest first, got order: %v", laps) } }