From 6c90d4b0aa0ccbb2760fa4f70b6cfe52435ae9f5 Mon Sep 17 00:00:00 2001 From: Maris Popens Date: Thu, 24 Sep 2026 14:00:50 +0300 Subject: [PATCH] feat: driver wins, short constructor names; clearer wins in standings tiles - drivers_standings now returns wins (Ergast already provides it per driver; only constructors had it before) - constructors_standings `team` drops Ergast's " F1 Team" suffix so "RB F1 Team"/"Alpine F1 Team"/"Haas F1 Team"/"Cadillac F1 Team" read RB/Alpine/Haas/Cadillac, matching the drivers tile and other tiles - widgets: the cryptic "(10W)" becomes a trophy + count in a fixed-width slot (points stay aligned), only shown when wins > 0, with a tooltip ("10 wins") - and drivers get it too --- main_test.go | 8 ++++---- standings.go | 5 +++-- .../f1_constructors_championship.yml | 3 +-- widgets/drivers-championship/f1_drivers_championship.yml | 4 +++- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/main_test.go b/main_test.go index 2dabf3a..b60c94f 100644 --- a/main_test.go +++ b/main_test.go @@ -39,9 +39,9 @@ func newUpstreamMock(t *testing.T) *upstreamMock { } switch r.URL.Path { case "/ergast/2026/driverStandings.json": - io.WriteString(w, `{"MRData":{"StandingsTable":{"StandingsLists":[{"DriverStandings":[{"position":"1","points":"100.5","Driver":{"familyName":"Verstappen","nationality":"Dutch"},"Constructors":[{"constructorId":"red_bull"}]}]}]}}}`) + io.WriteString(w, `{"MRData":{"StandingsTable":{"StandingsLists":[{"DriverStandings":[{"position":"1","points":"100.5","wins":"4","Driver":{"familyName":"Verstappen","nationality":"Dutch"},"Constructors":[{"constructorId":"red_bull"}]}]}]}}}`) case "/ergast/2026/constructorStandings.json": - io.WriteString(w, `{"MRData":{"StandingsTable":{"StandingsLists":[{"ConstructorStandings":[{"position":1,"points":150,"wins":3,"country":"Great Britain","flag":"gb","Constructor":{"name":"McLaren","nationality":"British","url":"https://example.test/mclaren"}}]}]}}}`) + io.WriteString(w, `{"MRData":{"StandingsTable":{"StandingsLists":[{"ConstructorStandings":[{"position":1,"points":150,"wins":3,"country":"Great Britain","flag":"gb","Constructor":{"name":"McLaren","nationality":"British","url":"https://example.test/mclaren"}},{"position":2,"points":100,"wins":0,"Constructor":{"name":"Haas F1 Team","nationality":"American","url":"https://example.test/haas"}}]}]}}}`) case "/ergast/current/last/results.json": io.WriteString(w, `{"MRData":{"RaceTable":{"Races":[{"season":"2026","round":"2","raceName":"Previous Grand Prix","url":"https://example.test/previous-race","date":"2026-02-22","Results":[{"position":"1","positionText":"1","laps":"57","Time":{"time":"1:30:00.000"},"Driver":{"familyName":"Verstappen","nationality":"Dutch"},"Constructor":{"constructorId":"red_bull"}},{"position":"20","positionText":"R","laps":"12","Driver":{"familyName":"Kimi Antonelli","nationality":"Italian"},"Constructor":{"constructorId":"mercedes"}}]}]}}}`) case "/ergast/2026.json": @@ -97,7 +97,7 @@ func TestDriversContractAndCache(t *testing.T) { server := newServer(testApp(t, mock)) result := decode(t, request(t, server, "/f1/drivers_standings/")) driver := result["drivers"].([]any)[0].(map[string]any) - if result["season"] != float64(2026) || driver["position"] != float64(1) || driver["points"] != 100.5 || driver["teamId"] != "Red Bull" || driver["country"] != "Netherlands" || driver["flag"] != "nl" { + if result["season"] != float64(2026) || driver["position"] != float64(1) || driver["points"] != 100.5 || driver["wins"] != float64(4) || driver["teamId"] != "Red Bull" || driver["country"] != "Netherlands" || driver["flag"] != "nl" { t.Fatalf("unexpected response: %#v", result) } request(t, server, "/f1/drivers_standings") @@ -110,7 +110,7 @@ func TestConstructorsContract(t *testing.T) { mock := newUpstreamMock(t) result := decode(t, request(t, newServer(testApp(t, mock)), "/f1/constructors_standings/")) item := result["constructors"].([]any)[0].(map[string]any) - if item["position"] != float64(1) || item["points"] != float64(150) || item["wins"] != float64(3) || item["country"] != "Great Britain" || item["flag"] != "gb" { + if item["position"] != float64(1) || item["points"] != float64(150) || item["wins"] != float64(3) || item["country"] != "Great Britain" || item["flag"] != "gb" || result["constructors"].([]any)[1].(map[string]any)["team"] != "Haas" { t.Fatalf("unexpected response: %#v", result) } } diff --git a/standings.go b/standings.go index 52503b7..578bda5 100644 --- a/standings.go +++ b/standings.go @@ -37,6 +37,7 @@ func (a *app) drivers(c echo.Context) error { Standings []struct { Position json.Number `json:"position"` Points json.Number `json:"points"` + Wins json.Number `json:"wins"` Driver struct{ FamilyName, Nationality string } `json:"Driver"` Constructors []struct { ID string `json:"constructorId"` @@ -57,7 +58,7 @@ func (a *app) drivers(c echo.Context) error { team = formatTeamName(standing.Constructors[0].ID) } country := normalizeNationality(standing.Driver.Nationality) - results = append(results, map[string]any{"surname": standing.Driver.FamilyName, "position": numberInt(standing.Position), "points": numberFloat(standing.Points), "teamId": team, "country": country, "flag": countryCodes[country]}) + results = append(results, map[string]any{"surname": standing.Driver.FamilyName, "position": numberInt(standing.Position), "points": numberFloat(standing.Points), "wins": numberInt(standing.Wins), "teamId": team, "country": country, "flag": countryCodes[country]}) } } result := map[string]any{"season": year, "drivers": results} @@ -94,7 +95,7 @@ func (a *app) constructors(c echo.Context) error { if len(upstream.MRData.StandingsTable.Lists) > 0 { for _, standing := range upstream.MRData.StandingsTable.Lists[0].Standings { country := normalizeNationality(standing.Constructor.Nationality) - results = append(results, map[string]any{"team": standing.Constructor.Name, "position": numberInt(standing.Position), "points": numberFloat(standing.Points), "wins": numberInt(standing.Wins), "country": country, "flag": countryCodes[country], "wiki": standing.Constructor.URL}) + results = append(results, map[string]any{"team": strings.TrimSuffix(standing.Constructor.Name, " F1 Team"), "position": numberInt(standing.Position), "points": numberFloat(standing.Points), "wins": numberInt(standing.Wins), "country": country, "flag": countryCodes[country], "wiki": standing.Constructor.URL}) } } result := map[string]any{"season": year, "constructors": results} diff --git a/widgets/constructors-championship/f1_constructors_championship.yml b/widgets/constructors-championship/f1_constructors_championship.yml index c371739..f2cb1b9 100644 --- a/widgets/constructors-championship/f1_constructors_championship.yml +++ b/widgets/constructors-championship/f1_constructors_championship.yml @@ -17,8 +17,7 @@ - {{ .String "points" }} - ({{ .String "wins" }}W) + {{ $w := .Int "wins" }}{{ if gt $w 0 }}🏆 {{ $w }}{{ end }} {{ .String "points" }} {{ end }} diff --git a/widgets/drivers-championship/f1_drivers_championship.yml b/widgets/drivers-championship/f1_drivers_championship.yml index bd1678c..2d0f6fb 100644 --- a/widgets/drivers-championship/f1_drivers_championship.yml +++ b/widgets/drivers-championship/f1_drivers_championship.yml @@ -19,7 +19,9 @@ ({{ .String "teamId" }}) {{ end }} - {{ .String "points" }} + + {{ $w := .Int "wins" }}{{ if gt $w 0 }}🏆 {{ $w }}{{ end }} {{ .String "points" }} + {{ end }} \ No newline at end of file