cricinfo-cli-go 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +63 -0
- package/CONTRIBUTORS.md +75 -0
- package/LICENSE +21 -0
- package/Makefile +131 -0
- package/README.md +130 -0
- package/bin/cricinfo.js +44 -0
- package/cmd/cricinfo/main.go +15 -0
- package/go.mod +10 -0
- package/go.sum +10 -0
- package/internal/app/app.go +11 -0
- package/internal/app/app_test.go +122 -0
- package/internal/buildinfo/buildinfo.go +16 -0
- package/internal/cli/analysis.go +262 -0
- package/internal/cli/analysis_test.go +175 -0
- package/internal/cli/competitions.go +154 -0
- package/internal/cli/competitions_test.go +165 -0
- package/internal/cli/leagues.go +297 -0
- package/internal/cli/leagues_test.go +194 -0
- package/internal/cli/matches.go +403 -0
- package/internal/cli/matches_test.go +413 -0
- package/internal/cli/players.go +263 -0
- package/internal/cli/players_test.go +384 -0
- package/internal/cli/root.go +141 -0
- package/internal/cli/search.go +119 -0
- package/internal/cli/teams.go +214 -0
- package/internal/cli/teams_test.go +192 -0
- package/internal/cricinfo/analysis.go +1401 -0
- package/internal/cricinfo/analysis_phase15_test.go +267 -0
- package/internal/cricinfo/client.go +471 -0
- package/internal/cricinfo/client_test.go +280 -0
- package/internal/cricinfo/cmd/fixture-refresh/main.go +145 -0
- package/internal/cricinfo/competitions.go +405 -0
- package/internal/cricinfo/competitions_phase13_test.go +234 -0
- package/internal/cricinfo/coverage_ledger.go +122 -0
- package/internal/cricinfo/coverage_ledger_test.go +253 -0
- package/internal/cricinfo/decode.go +115 -0
- package/internal/cricinfo/decode_test.go +100 -0
- package/internal/cricinfo/entity_index.go +618 -0
- package/internal/cricinfo/entity_index_test.go +175 -0
- package/internal/cricinfo/fixture_matrix.go +243 -0
- package/internal/cricinfo/fixture_matrix_test.go +49 -0
- package/internal/cricinfo/fixtures_test.go +264 -0
- package/internal/cricinfo/historical_hydration.go +1641 -0
- package/internal/cricinfo/historical_phase14_test.go +542 -0
- package/internal/cricinfo/leagues.go +1210 -0
- package/internal/cricinfo/leagues_phase12_test.go +324 -0
- package/internal/cricinfo/live_leagues_test.go +169 -0
- package/internal/cricinfo/live_matches_test.go +203 -0
- package/internal/cricinfo/live_matrix_test.go +118 -0
- package/internal/cricinfo/live_players_test.go +122 -0
- package/internal/cricinfo/live_search_test.go +86 -0
- package/internal/cricinfo/live_smoke_test.go +213 -0
- package/internal/cricinfo/live_teams_test.go +104 -0
- package/internal/cricinfo/matches.go +1508 -0
- package/internal/cricinfo/matches_phase7_test.go +207 -0
- package/internal/cricinfo/matches_phase9_test.go +253 -0
- package/internal/cricinfo/normalize_entities.go +1727 -0
- package/internal/cricinfo/normalize_leagues.go +346 -0
- package/internal/cricinfo/players.go +1332 -0
- package/internal/cricinfo/players_phase10_test.go +174 -0
- package/internal/cricinfo/players_phase11_test.go +373 -0
- package/internal/cricinfo/render_contract.go +1088 -0
- package/internal/cricinfo/render_phase4_test.go +633 -0
- package/internal/cricinfo/renderer.go +1689 -0
- package/internal/cricinfo/resolver.go +813 -0
- package/internal/cricinfo/resolver_test.go +244 -0
- package/internal/cricinfo/teams.go +603 -0
- package/internal/cricinfo/teams_phase8_test.go +231 -0
- package/internal/cricinfo/testdata/fixtures/README.md +43 -0
- package/internal/cricinfo/testdata/fixtures/aux-competition-metadata/broadcasts.json +11 -0
- package/internal/cricinfo/testdata/fixtures/aux-competition-metadata/officials.json +150 -0
- package/internal/cricinfo/testdata/fixtures/details-plays/detail-110.json +157 -0
- package/internal/cricinfo/testdata/fixtures/details-plays/detail-52545007.json +145 -0
- package/internal/cricinfo/testdata/fixtures/details-plays/detail-52559021.json +143 -0
- package/internal/cricinfo/testdata/fixtures/details-plays/plays.json +15 -0
- package/internal/cricinfo/testdata/fixtures/endpoint-matrix.tsv +19 -0
- package/internal/cricinfo/testdata/fixtures/innings-fow-partnerships/fow-1.json +12 -0
- package/internal/cricinfo/testdata/fixtures/innings-fow-partnerships/fow.json +42 -0
- package/internal/cricinfo/testdata/fixtures/innings-fow-partnerships/innings-1-2.json +38 -0
- package/internal/cricinfo/testdata/fixtures/innings-fow-partnerships/partnership-1.json +31 -0
- package/internal/cricinfo/testdata/fixtures/innings-fow-partnerships/partnerships.json +42 -0
- package/internal/cricinfo/testdata/fixtures/leagues-seasons-standings/calendar-offdays.json +20 -0
- package/internal/cricinfo/testdata/fixtures/leagues-seasons-standings/calendar-ondays.json +21 -0
- package/internal/cricinfo/testdata/fixtures/leagues-seasons-standings/calendar.json +14 -0
- package/internal/cricinfo/testdata/fixtures/leagues-seasons-standings/season-2025.json +13 -0
- package/internal/cricinfo/testdata/fixtures/leagues-seasons-standings/season-group-1.json +13 -0
- package/internal/cricinfo/testdata/fixtures/leagues-seasons-standings/season-groups.json +11 -0
- package/internal/cricinfo/testdata/fixtures/leagues-seasons-standings/season-type-1.json +13 -0
- package/internal/cricinfo/testdata/fixtures/leagues-seasons-standings/season-types.json +11 -0
- package/internal/cricinfo/testdata/fixtures/leagues-seasons-standings/seasons.json +30 -0
- package/internal/cricinfo/testdata/fixtures/leagues-seasons-standings/standings-item-1.json +72 -0
- package/internal/cricinfo/testdata/fixtures/leagues-seasons-standings/standings-root.json +3 -0
- package/internal/cricinfo/testdata/fixtures/leagues-seasons-standings/standings.json +15 -0
- package/internal/cricinfo/testdata/fixtures/matches-competitions/competition.json +460 -0
- package/internal/cricinfo/testdata/fixtures/matches-competitions/event-1529474.json +86 -0
- package/internal/cricinfo/testdata/fixtures/matches-competitions/matchcards-1527966.json +368 -0
- package/internal/cricinfo/testdata/fixtures/matches-competitions/situation-1529474.json +10 -0
- package/internal/cricinfo/testdata/fixtures/players/athlete-1361257-statistics.json +126 -0
- package/internal/cricinfo/testdata/fixtures/players/athlete-1361257.json +113 -0
- package/internal/cricinfo/testdata/fixtures/players/roster-1361257-linescores-1-1-statistics-0.json +208 -0
- package/internal/cricinfo/testdata/fixtures/players/roster-1361257-linescores-1-2-statistics-0.json +252 -0
- package/internal/cricinfo/testdata/fixtures/players/roster-1361257-linescores.json +74 -0
- package/internal/cricinfo/testdata/fixtures/players/roster-1361257-statistics-0.json +1008 -0
- package/internal/cricinfo/testdata/fixtures/root-discovery/events.json +72 -0
- package/internal/cricinfo/testdata/fixtures/root-discovery/root.json +28 -0
- package/internal/cricinfo/testdata/fixtures/team-competitor/competitor-789643.json +40 -0
- package/internal/cricinfo/testdata/fixtures/team-competitor/leaders-789643.json +353 -0
- package/internal/cricinfo/testdata/fixtures/team-competitor/records-789643.json +91 -0
- package/internal/cricinfo/testdata/fixtures/team-competitor/roster-1147772-object.json +231 -0
- package/internal/cricinfo/testdata/fixtures/team-competitor/roster-1147772.json +235 -0
- package/internal/cricinfo/testdata/fixtures/team-competitor/roster-789643.json +322 -0
- package/internal/cricinfo/testdata/fixtures/team-competitor/scores-789643.json +19 -0
- package/internal/cricinfo/testdata/fixtures/team-competitor/statistics-789643.json +629 -0
- package/internal/cricinfo/testdata/fixtures/team-competitor/team-789643-athletes.json +7 -0
- package/internal/cricinfo/testdata/fixtures/team-competitor/team-789643.json +67 -0
- package/internal/cricinfo/testdata/golden/match-empty.golden +1 -0
- package/internal/cricinfo/testdata/golden/match-list.golden +2 -0
- package/internal/cricinfo/testdata/golden/match-partial.golden +3 -0
- package/internal/cricinfo/types.go +54 -0
- package/package.json +51 -0
- package/scripts/postinstall.js +153 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
package cricinfo
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"context"
|
|
5
|
+
"fmt"
|
|
6
|
+
"net/http"
|
|
7
|
+
"net/http/httptest"
|
|
8
|
+
"path/filepath"
|
|
9
|
+
"strings"
|
|
10
|
+
"testing"
|
|
11
|
+
"time"
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
func TestTeamServicePhase8GlobalAndMatchRosterScopes(t *testing.T) {
|
|
15
|
+
t.Parallel()
|
|
16
|
+
|
|
17
|
+
service := newPhase8TeamTestService(t)
|
|
18
|
+
|
|
19
|
+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
20
|
+
defer cancel()
|
|
21
|
+
|
|
22
|
+
showResult, err := service.Show(ctx, "Boost Region", TeamLookupOptions{LeagueID: "19138"})
|
|
23
|
+
if err != nil {
|
|
24
|
+
t.Fatalf("Show error: %v", err)
|
|
25
|
+
}
|
|
26
|
+
if showResult.Kind != EntityTeam {
|
|
27
|
+
t.Fatalf("expected show kind %q, got %q", EntityTeam, showResult.Kind)
|
|
28
|
+
}
|
|
29
|
+
team, ok := showResult.Data.(Team)
|
|
30
|
+
if !ok {
|
|
31
|
+
t.Fatalf("expected show data Team, got %T", showResult.Data)
|
|
32
|
+
}
|
|
33
|
+
if team.ID != "789643" {
|
|
34
|
+
t.Fatalf("expected team id 789643, got %q", team.ID)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
globalRosterResult, err := service.Roster(ctx, "789643", TeamLookupOptions{LeagueID: "19138"})
|
|
38
|
+
if err != nil {
|
|
39
|
+
t.Fatalf("Roster global error: %v", err)
|
|
40
|
+
}
|
|
41
|
+
if globalRosterResult.Kind != EntityTeamRoster {
|
|
42
|
+
t.Fatalf("expected global roster kind %q, got %q", EntityTeamRoster, globalRosterResult.Kind)
|
|
43
|
+
}
|
|
44
|
+
if globalRosterResult.Status == ResultStatusError {
|
|
45
|
+
t.Fatalf("expected non-error global roster result, got %+v", globalRosterResult)
|
|
46
|
+
}
|
|
47
|
+
if !strings.Contains(globalRosterResult.RequestedRef, "/teams/789643/athletes") {
|
|
48
|
+
t.Fatalf("expected global roster route to request /teams/{id}/athletes, requestedRef=%q", globalRosterResult.RequestedRef)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
matchRosterResult, err := service.Roster(ctx, "Boost Region", TeamLookupOptions{LeagueID: "19138", MatchQuery: "3rd Match"})
|
|
52
|
+
if err != nil {
|
|
53
|
+
t.Fatalf("Roster match error: %v", err)
|
|
54
|
+
}
|
|
55
|
+
if matchRosterResult.Kind != EntityTeamRoster {
|
|
56
|
+
t.Fatalf("expected match roster kind %q, got %q", EntityTeamRoster, matchRosterResult.Kind)
|
|
57
|
+
}
|
|
58
|
+
if matchRosterResult.Status == ResultStatusError {
|
|
59
|
+
t.Fatalf("expected non-error match roster result, got %+v", matchRosterResult)
|
|
60
|
+
}
|
|
61
|
+
if len(matchRosterResult.Items) == 0 {
|
|
62
|
+
t.Fatalf("expected roster entries in match-scoped roster result")
|
|
63
|
+
}
|
|
64
|
+
if !strings.Contains(matchRosterResult.RequestedRef, "/competitors/789643/roster") {
|
|
65
|
+
t.Fatalf("expected match roster route to request competitor roster, requestedRef=%q", matchRosterResult.RequestedRef)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
func TestTeamServicePhase8LeadersStatisticsRecordsAndScores(t *testing.T) {
|
|
70
|
+
t.Parallel()
|
|
71
|
+
|
|
72
|
+
service := newPhase8TeamTestService(t)
|
|
73
|
+
|
|
74
|
+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
75
|
+
defer cancel()
|
|
76
|
+
|
|
77
|
+
scoresResult, err := service.Scores(ctx, "789643", TeamLookupOptions{LeagueID: "19138", MatchQuery: "1529474"})
|
|
78
|
+
if err != nil {
|
|
79
|
+
t.Fatalf("Scores error: %v", err)
|
|
80
|
+
}
|
|
81
|
+
if scoresResult.Kind != EntityTeamScore {
|
|
82
|
+
t.Fatalf("expected scores kind %q, got %q", EntityTeamScore, scoresResult.Kind)
|
|
83
|
+
}
|
|
84
|
+
score, ok := scoresResult.Data.(*TeamScore)
|
|
85
|
+
if !ok {
|
|
86
|
+
t.Fatalf("expected scores data *TeamScore, got %T", scoresResult.Data)
|
|
87
|
+
}
|
|
88
|
+
if strings.TrimSpace(score.DisplayValue) == "" {
|
|
89
|
+
t.Fatalf("expected non-empty display score")
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
leadersResult, err := service.Leaders(ctx, "Boost Region", TeamLookupOptions{LeagueID: "19138", MatchQuery: "3rd Match"})
|
|
93
|
+
if err != nil {
|
|
94
|
+
t.Fatalf("Leaders error: %v", err)
|
|
95
|
+
}
|
|
96
|
+
if leadersResult.Kind != EntityTeamLeaders {
|
|
97
|
+
t.Fatalf("expected leaders kind %q, got %q", EntityTeamLeaders, leadersResult.Kind)
|
|
98
|
+
}
|
|
99
|
+
leaders, ok := leadersResult.Data.(*TeamLeaders)
|
|
100
|
+
if !ok {
|
|
101
|
+
t.Fatalf("expected leaders data *TeamLeaders, got %T (status=%s message=%q error=%+v)", leadersResult.Data, leadersResult.Status, leadersResult.Message, leadersResult.Error)
|
|
102
|
+
}
|
|
103
|
+
if len(leaders.Categories) == 0 {
|
|
104
|
+
t.Fatalf("expected leader categories in result")
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
statisticsResult, err := service.Statistics(ctx, "789643", TeamLookupOptions{LeagueID: "19138", MatchQuery: "1529474"})
|
|
108
|
+
if err != nil {
|
|
109
|
+
t.Fatalf("Statistics error: %v", err)
|
|
110
|
+
}
|
|
111
|
+
if statisticsResult.Kind != EntityTeamStatistics {
|
|
112
|
+
t.Fatalf("expected statistics kind %q, got %q", EntityTeamStatistics, statisticsResult.Kind)
|
|
113
|
+
}
|
|
114
|
+
if len(statisticsResult.Items) == 0 {
|
|
115
|
+
t.Fatalf("expected statistics categories in result")
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
recordsResult, err := service.Records(ctx, "789643", TeamLookupOptions{LeagueID: "19138", MatchQuery: "1529474"})
|
|
119
|
+
if err != nil {
|
|
120
|
+
t.Fatalf("Records error: %v", err)
|
|
121
|
+
}
|
|
122
|
+
if recordsResult.Kind != EntityTeamRecords {
|
|
123
|
+
t.Fatalf("expected records kind %q, got %q", EntityTeamRecords, recordsResult.Kind)
|
|
124
|
+
}
|
|
125
|
+
if len(recordsResult.Items) == 0 {
|
|
126
|
+
t.Fatalf("expected record categories in result")
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
func newPhase8TeamTestService(t *testing.T) *TeamService {
|
|
131
|
+
t.Helper()
|
|
132
|
+
|
|
133
|
+
teamFixture := mustReadFixtureBytes(t, "team-competitor/team-789643.json")
|
|
134
|
+
athletesFixture := mustReadFixtureBytes(t, "team-competitor/team-789643-athletes.json")
|
|
135
|
+
rosterFixture := mustReadFixtureBytes(t, "team-competitor/roster-1147772.json")
|
|
136
|
+
scoresFixture := mustReadFixtureBytes(t, "team-competitor/scores-789643.json")
|
|
137
|
+
leadersFixture := mustReadFixtureBytes(t, "team-competitor/leaders-789643.json")
|
|
138
|
+
statisticsFixture := mustReadFixtureBytes(t, "team-competitor/statistics-789643.json")
|
|
139
|
+
recordsFixture := mustReadFixtureBytes(t, "team-competitor/records-789643.json")
|
|
140
|
+
|
|
141
|
+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
142
|
+
base := "http://" + r.Host + "/v2/sports/cricket"
|
|
143
|
+
competitionPath := "/v2/sports/cricket/leagues/19138/events/1529474/competitions/1529474"
|
|
144
|
+
|
|
145
|
+
switch r.URL.Path {
|
|
146
|
+
case "/v2/sports/cricket/teams/789643":
|
|
147
|
+
_, _ = w.Write(rewriteFixtureBaseURL(teamFixture, base))
|
|
148
|
+
case "/v2/sports/cricket/teams/789643/athletes":
|
|
149
|
+
_, _ = w.Write(rewriteFixtureBaseURL(athletesFixture, base))
|
|
150
|
+
case competitionPath:
|
|
151
|
+
competition := fmt.Sprintf(`{"$ref":"%s/leagues/19138/events/1529474/competitions/1529474","id":"1529474","description":"3rd Match","shortDescription":"3rd Match","date":"2026-04-09T05:30Z","competitors":[{"$ref":"%s/leagues/19138/events/1529474/competitions/1529474/competitors/789643","id":"789643","team":{"$ref":"%s/events/1529474/teams/789643"},"score":{"$ref":"%s/leagues/19138/events/1529474/competitions/1529474/competitors/789643/scores"},"roster":{"$ref":"%s/leagues/19138/events/1529474/competitions/1529474/competitors/789643/roster"},"leaders":{"$ref":"%s/leagues/19138/events/1529474/competitions/1529474/competitors/789643/leaders"},"statistics":{"$ref":"%s/leagues/19138/events/1529474/competitions/1529474/competitors/789643/statistics"},"record":{"$ref":"%s/leagues/19138/events/1529474/competitions/1529474/competitors/789643/records"}}]}`,
|
|
152
|
+
base, base, base, base, base, base, base, base)
|
|
153
|
+
_, _ = w.Write([]byte(competition))
|
|
154
|
+
case competitionPath + "/competitors/789643/roster":
|
|
155
|
+
_, _ = w.Write(rewriteFixtureBaseURL(rosterFixture, base))
|
|
156
|
+
case competitionPath + "/competitors/789643/scores":
|
|
157
|
+
_, _ = w.Write(rewriteFixtureBaseURL(scoresFixture, base))
|
|
158
|
+
case competitionPath + "/competitors/789643/leaders":
|
|
159
|
+
_, _ = w.Write(rewriteFixtureBaseURL(leadersFixture, base))
|
|
160
|
+
case competitionPath + "/competitors/789643/statistics":
|
|
161
|
+
_, _ = w.Write(rewriteFixtureBaseURL(statisticsFixture, base))
|
|
162
|
+
case competitionPath + "/competitors/789643/records":
|
|
163
|
+
_, _ = w.Write(rewriteFixtureBaseURL(recordsFixture, base))
|
|
164
|
+
default:
|
|
165
|
+
http.NotFound(w, r)
|
|
166
|
+
}
|
|
167
|
+
}))
|
|
168
|
+
t.Cleanup(server.Close)
|
|
169
|
+
|
|
170
|
+
index, err := OpenEntityIndex(filepath.Join(t.TempDir(), "resolver-index.json"))
|
|
171
|
+
if err != nil {
|
|
172
|
+
t.Fatalf("OpenEntityIndex error: %v", err)
|
|
173
|
+
}
|
|
174
|
+
if err := index.UpsertMany([]IndexedEntity{
|
|
175
|
+
{
|
|
176
|
+
Kind: EntityTeam,
|
|
177
|
+
ID: "789643",
|
|
178
|
+
Ref: "/teams/789643",
|
|
179
|
+
Name: "Boost Region",
|
|
180
|
+
ShortName: "BOOST",
|
|
181
|
+
LeagueID: "19138",
|
|
182
|
+
EventID: "1529474",
|
|
183
|
+
MatchID: "1529474",
|
|
184
|
+
Aliases: []string{"Boost Region", "BOOST", "789643"},
|
|
185
|
+
UpdatedAt: time.Now().UTC(),
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
Kind: EntityMatch,
|
|
189
|
+
ID: "1529474",
|
|
190
|
+
Ref: "/leagues/19138/events/1529474/competitions/1529474",
|
|
191
|
+
Name: "3rd Match",
|
|
192
|
+
ShortName: "3rd Match",
|
|
193
|
+
LeagueID: "19138",
|
|
194
|
+
EventID: "1529474",
|
|
195
|
+
MatchID: "1529474",
|
|
196
|
+
Aliases: []string{"3rd Match", "1529474"},
|
|
197
|
+
UpdatedAt: time.Now().UTC(),
|
|
198
|
+
},
|
|
199
|
+
}); err != nil {
|
|
200
|
+
t.Fatalf("index upsert error: %v", err)
|
|
201
|
+
}
|
|
202
|
+
index.SetLastEventsSeedAt(time.Now().UTC())
|
|
203
|
+
|
|
204
|
+
client, err := NewClient(Config{BaseURL: server.URL + "/v2/sports/cricket"})
|
|
205
|
+
if err != nil {
|
|
206
|
+
t.Fatalf("NewClient error: %v", err)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
resolver, err := NewResolver(ResolverConfig{
|
|
210
|
+
Client: client,
|
|
211
|
+
Index: index,
|
|
212
|
+
EventSeedTTL: 24 * time.Hour,
|
|
213
|
+
Now: func() time.Time { return time.Now().UTC() },
|
|
214
|
+
})
|
|
215
|
+
if err != nil {
|
|
216
|
+
t.Fatalf("NewResolver error: %v", err)
|
|
217
|
+
}
|
|
218
|
+
t.Cleanup(func() {
|
|
219
|
+
_ = resolver.Close()
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
service, err := NewTeamService(TeamServiceConfig{Client: client, Resolver: resolver})
|
|
223
|
+
if err != nil {
|
|
224
|
+
t.Fatalf("NewTeamService error: %v", err)
|
|
225
|
+
}
|
|
226
|
+
t.Cleanup(func() {
|
|
227
|
+
_ = service.Close()
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
return service
|
|
231
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Curated Fixture Strategy
|
|
2
|
+
|
|
3
|
+
This fixture tree is organized by major Cricinfo API resource families so future phases can validate only the families they touch.
|
|
4
|
+
|
|
5
|
+
Families:
|
|
6
|
+
|
|
7
|
+
- `root-discovery`
|
|
8
|
+
- `matches-competitions`
|
|
9
|
+
- `details-plays`
|
|
10
|
+
- `team-competitor`
|
|
11
|
+
- `innings-fow-partnerships`
|
|
12
|
+
- `players`
|
|
13
|
+
- `leagues-seasons-standings`
|
|
14
|
+
- `aux-competition-metadata`
|
|
15
|
+
|
|
16
|
+
Sources:
|
|
17
|
+
|
|
18
|
+
- Endpoint inventory: `internal/cricinfo/fixture_matrix.go`
|
|
19
|
+
- Generated matrix file: `internal/cricinfo/testdata/fixtures/endpoint-matrix.tsv`
|
|
20
|
+
|
|
21
|
+
Refresh command:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
go run ./internal/cricinfo/cmd/fixture-refresh --write
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Refresh only selected families:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
go run ./internal/cricinfo/cmd/fixture-refresh --write --families players,details-plays
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Live integration test entrypoint:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
CRICINFO_LIVE_MATRIX=1 go test ./internal/cricinfo -run TestLive -count=1
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Limit live test families with:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
CRICINFO_LIVE_MATRIX=1 CRICINFO_LIVE_FAMILIES=players,team-competitor go test ./internal/cricinfo -run TestLiveFixtureMatrixByFamily -count=1
|
|
43
|
+
```
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
{
|
|
2
|
+
"count": 5,
|
|
3
|
+
"pageIndex": 1,
|
|
4
|
+
"pageSize": 25,
|
|
5
|
+
"pageCount": 1,
|
|
6
|
+
"items": [
|
|
7
|
+
{
|
|
8
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/leagues/11132/events/1527944/competitions/1527944/officials",
|
|
9
|
+
"displayName": "Anil Chaugai",
|
|
10
|
+
"firstName": "Anil",
|
|
11
|
+
"flag": {
|
|
12
|
+
"alt": "Nepal",
|
|
13
|
+
"height": 500,
|
|
14
|
+
"href": "https://a.espncdn.com/i/teamlogos/countries/500/nep.png",
|
|
15
|
+
"rel": [
|
|
16
|
+
"full",
|
|
17
|
+
"default"
|
|
18
|
+
],
|
|
19
|
+
"width": 500
|
|
20
|
+
},
|
|
21
|
+
"lastName": "Chaugai",
|
|
22
|
+
"links": {
|
|
23
|
+
"href": "https://www.espncricinfo.com/ci/content/player/1413793.html",
|
|
24
|
+
"rel": "playerprofie",
|
|
25
|
+
"shortText": "Player Profile",
|
|
26
|
+
"text": "Player Profile",
|
|
27
|
+
"type": "desktop"
|
|
28
|
+
},
|
|
29
|
+
"order": 1,
|
|
30
|
+
"position": {
|
|
31
|
+
"displayName": "umpire",
|
|
32
|
+
"name": "umpire"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/leagues/11132/events/1527944/competitions/1527944/officials",
|
|
37
|
+
"displayName": "Himal Giri",
|
|
38
|
+
"firstName": "Himal",
|
|
39
|
+
"flag": {
|
|
40
|
+
"alt": "Nepal",
|
|
41
|
+
"height": 500,
|
|
42
|
+
"href": "https://a.espncdn.com/i/teamlogos/countries/500/nep.png",
|
|
43
|
+
"rel": [
|
|
44
|
+
"full",
|
|
45
|
+
"default"
|
|
46
|
+
],
|
|
47
|
+
"width": 500
|
|
48
|
+
},
|
|
49
|
+
"lastName": "Giri",
|
|
50
|
+
"links": {
|
|
51
|
+
"href": "https://www.espncricinfo.com/ci/content/player/543484.html",
|
|
52
|
+
"rel": "playerprofie",
|
|
53
|
+
"shortText": "Player Profile",
|
|
54
|
+
"text": "Player Profile",
|
|
55
|
+
"type": "desktop"
|
|
56
|
+
},
|
|
57
|
+
"order": 2,
|
|
58
|
+
"position": {
|
|
59
|
+
"displayName": "umpire",
|
|
60
|
+
"name": "umpire"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/leagues/11132/events/1527944/competitions/1527944/officials",
|
|
65
|
+
"displayName": "Mohammed Shafique",
|
|
66
|
+
"firstName": "Mohammed",
|
|
67
|
+
"flag": {
|
|
68
|
+
"alt": "Nepal",
|
|
69
|
+
"height": 500,
|
|
70
|
+
"href": "https://a.espncdn.com/i/teamlogos/countries/500/nep.png",
|
|
71
|
+
"rel": [
|
|
72
|
+
"full",
|
|
73
|
+
"default"
|
|
74
|
+
],
|
|
75
|
+
"width": 500
|
|
76
|
+
},
|
|
77
|
+
"lastName": "Shafique",
|
|
78
|
+
"links": {
|
|
79
|
+
"href": "https://www.espncricinfo.com/ci/content/player/543489.html",
|
|
80
|
+
"rel": "playerprofie",
|
|
81
|
+
"shortText": "Player Profile",
|
|
82
|
+
"text": "Player Profile",
|
|
83
|
+
"type": "desktop"
|
|
84
|
+
},
|
|
85
|
+
"order": 3,
|
|
86
|
+
"position": {
|
|
87
|
+
"displayName": "referee",
|
|
88
|
+
"name": "referee"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/leagues/11132/events/1527944/competitions/1527944/officials",
|
|
93
|
+
"displayName": "Prabin Thapa",
|
|
94
|
+
"firstName": "Prabin",
|
|
95
|
+
"flag": {
|
|
96
|
+
"alt": "Nepal",
|
|
97
|
+
"height": 500,
|
|
98
|
+
"href": "https://a.espncdn.com/i/teamlogos/countries/500/nep.png",
|
|
99
|
+
"rel": [
|
|
100
|
+
"full",
|
|
101
|
+
"default"
|
|
102
|
+
],
|
|
103
|
+
"width": 500
|
|
104
|
+
},
|
|
105
|
+
"lastName": "Thapa",
|
|
106
|
+
"links": {
|
|
107
|
+
"href": "https://www.espncricinfo.com/ci/content/player/1290784.html",
|
|
108
|
+
"rel": "playerprofie",
|
|
109
|
+
"shortText": "Player Profile",
|
|
110
|
+
"text": "Player Profile",
|
|
111
|
+
"type": "desktop"
|
|
112
|
+
},
|
|
113
|
+
"order": 4,
|
|
114
|
+
"position": {
|
|
115
|
+
"displayName": "reserve umpire",
|
|
116
|
+
"name": "reserve umpire"
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/leagues/11132/events/1527944/competitions/1527944/officials",
|
|
121
|
+
"displayName": "Naren Bhatta",
|
|
122
|
+
"firstName": "Naren",
|
|
123
|
+
"flag": {
|
|
124
|
+
"alt": "Nepal",
|
|
125
|
+
"height": 500,
|
|
126
|
+
"href": "https://a.espncdn.com/i/teamlogos/countries/500/nep.png",
|
|
127
|
+
"rel": [
|
|
128
|
+
"full",
|
|
129
|
+
"default"
|
|
130
|
+
],
|
|
131
|
+
"width": 500
|
|
132
|
+
},
|
|
133
|
+
"lastName": "Bhatta",
|
|
134
|
+
"links": {
|
|
135
|
+
"href": "https://www.espncricinfo.com/ci/content/player/1290622.html",
|
|
136
|
+
"rel": "playerprofie",
|
|
137
|
+
"shortText": "Player Profile",
|
|
138
|
+
"text": "Player Profile",
|
|
139
|
+
"type": "desktop"
|
|
140
|
+
},
|
|
141
|
+
"order": 5,
|
|
142
|
+
"position": {
|
|
143
|
+
"displayName": "sub fielder",
|
|
144
|
+
"name": "sub fielder"
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
]
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/leagues/19138/events/1529474/competitions/1529474/details/110",
|
|
3
|
+
"id": "110",
|
|
4
|
+
"uid": "s:200~e:1529474~c:1529474~d:52542569",
|
|
5
|
+
"clock": "00:00",
|
|
6
|
+
"date": "2026-4-09 10:00:00",
|
|
7
|
+
"playType": {
|
|
8
|
+
"id": "1",
|
|
9
|
+
"description": "run"
|
|
10
|
+
},
|
|
11
|
+
"team": {
|
|
12
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/teams/789643"
|
|
13
|
+
},
|
|
14
|
+
"mediaId": 0,
|
|
15
|
+
"period": 1,
|
|
16
|
+
"periodText": "1st innings",
|
|
17
|
+
"shortPeriodText": "1st innings",
|
|
18
|
+
"xCoordinate": null,
|
|
19
|
+
"yCoordinate": null,
|
|
20
|
+
"preText": "",
|
|
21
|
+
"text": "",
|
|
22
|
+
"postText": "",
|
|
23
|
+
"shortText": "Amanullah to Fazal Haq Shaheen, 1 run",
|
|
24
|
+
"homeScore": "1/0",
|
|
25
|
+
"awayScore": "0",
|
|
26
|
+
"scoreValue": 1,
|
|
27
|
+
"sequence": 100001,
|
|
28
|
+
"athletesInvolved": [
|
|
29
|
+
{
|
|
30
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/leagues/19138/athletes/1361257"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/leagues/19138/athletes/976585"
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"hawkeyeId": null,
|
|
37
|
+
"boundary": false,
|
|
38
|
+
"speedKPH": null,
|
|
39
|
+
"speedMPH": null,
|
|
40
|
+
"bowler": {
|
|
41
|
+
"athlete": {
|
|
42
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/leagues/19138/athletes/976585"
|
|
43
|
+
},
|
|
44
|
+
"team": {
|
|
45
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/teams/789647/"
|
|
46
|
+
},
|
|
47
|
+
"maidens": 0,
|
|
48
|
+
"balls": 1,
|
|
49
|
+
"wickets": 0,
|
|
50
|
+
"overs": 0.1,
|
|
51
|
+
"conceded": 1
|
|
52
|
+
},
|
|
53
|
+
"otherBowler": {
|
|
54
|
+
"athlete": {
|
|
55
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/leagues/19138/athletes/0"
|
|
56
|
+
},
|
|
57
|
+
"team": {
|
|
58
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/teams/789647/"
|
|
59
|
+
},
|
|
60
|
+
"maidens": 0,
|
|
61
|
+
"balls": 0,
|
|
62
|
+
"wickets": 0,
|
|
63
|
+
"overs": 0,
|
|
64
|
+
"conceded": 0
|
|
65
|
+
},
|
|
66
|
+
"batsman": {
|
|
67
|
+
"athlete": {
|
|
68
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/leagues/19138/athletes/1361257"
|
|
69
|
+
},
|
|
70
|
+
"team": {
|
|
71
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/teams/789643/"
|
|
72
|
+
},
|
|
73
|
+
"totalRuns": 1,
|
|
74
|
+
"faced": 1,
|
|
75
|
+
"fours": 0,
|
|
76
|
+
"runs": 1,
|
|
77
|
+
"sixes": 0
|
|
78
|
+
},
|
|
79
|
+
"otherBatsman": {
|
|
80
|
+
"athlete": {
|
|
81
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/leagues/19138/athletes/0"
|
|
82
|
+
},
|
|
83
|
+
"team": {
|
|
84
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/teams/789643/"
|
|
85
|
+
},
|
|
86
|
+
"totalRuns": 0,
|
|
87
|
+
"faced": 0,
|
|
88
|
+
"fours": 0,
|
|
89
|
+
"runs": 0,
|
|
90
|
+
"sixes": 0
|
|
91
|
+
},
|
|
92
|
+
"innings": {
|
|
93
|
+
"id": "286727",
|
|
94
|
+
"runRate": 6,
|
|
95
|
+
"remainingBalls": 0,
|
|
96
|
+
"byes": 0,
|
|
97
|
+
"number": 1,
|
|
98
|
+
"balls": 1,
|
|
99
|
+
"noBalls": 0,
|
|
100
|
+
"requiredRunRate": null,
|
|
101
|
+
"wickets": 0,
|
|
102
|
+
"legByes": 0,
|
|
103
|
+
"ballLimit": 0,
|
|
104
|
+
"target": 0,
|
|
105
|
+
"session": 0,
|
|
106
|
+
"day": 0,
|
|
107
|
+
"fallOfWickets": 0,
|
|
108
|
+
"trailBy": 0,
|
|
109
|
+
"leadBy": 0,
|
|
110
|
+
"remainingRuns": null,
|
|
111
|
+
"remainingOvers": 0.0,
|
|
112
|
+
"totalRuns": 1,
|
|
113
|
+
"wides": 0,
|
|
114
|
+
"runs": 1
|
|
115
|
+
},
|
|
116
|
+
"over": {
|
|
117
|
+
"ball": 1,
|
|
118
|
+
"balls": 6,
|
|
119
|
+
"complete": false,
|
|
120
|
+
"limit": 0.0,
|
|
121
|
+
"maiden": 0,
|
|
122
|
+
"noBall": 0,
|
|
123
|
+
"wide": 0,
|
|
124
|
+
"legByes": 0,
|
|
125
|
+
"byes": 0,
|
|
126
|
+
"number": 1,
|
|
127
|
+
"runs": 5,
|
|
128
|
+
"wickets": 0,
|
|
129
|
+
"overs": 0.1,
|
|
130
|
+
"actual": 0.1,
|
|
131
|
+
"unique": 0.01
|
|
132
|
+
},
|
|
133
|
+
"dismissal": {
|
|
134
|
+
"dismissal": false,
|
|
135
|
+
"bowled": false,
|
|
136
|
+
"type": "",
|
|
137
|
+
"bowler": {
|
|
138
|
+
"athlete": {
|
|
139
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/leagues/19138/athletes/976585"
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
"batsman": {
|
|
143
|
+
"athlete": {
|
|
144
|
+
"$ref": "http://core.espnuk.org/v2/sports/cricket/leagues/19138/athletes/1361257"
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
"text": "",
|
|
148
|
+
"minutes": 0,
|
|
149
|
+
"retiredText": ""
|
|
150
|
+
},
|
|
151
|
+
"bbbTimestamp": 0
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|