Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 0 additions & 111 deletions fixtures/raceResults.ts

This file was deleted.

149 changes: 149 additions & 0 deletions fixtures/sprintWeekend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import { RaceEvent, RaceType } from "../src/types/entities";

const imolaRace = {
season: "2022",
round: 4,
raceName: "Emilia Romagna Grand Prix",
Circuit: {
circuitId: "imola",
url: "http://en.wikipedia.org/wiki/Autodromo_Enzo_e_Dino_Ferrari",
circuitName: "Autodromo Enzo e Dino Ferrari",
Location: {
lat: 44.3439,
long: 11.7167,
locality: "Imola",
country: "Italy",
},
},
date: "2022-04-24",
time: "13:00:00Z",
FirstPractice: new Date("2022-04-22T11:30:00Z"),
Qualifying: new Date("2022-04-22T15:00:00Z"),
SecondPractice: new Date("2022-04-23T10:30:00Z"),
Sprint: new Date("2022-04-23T14:30:00Z"),
};

export const sprintRaceEvent: RaceEvent = {
Race: imolaRace,
eventType: RaceType.SPRINT_RACE,
id: "4-s",
};

export const grandPrixEvent: RaceEvent = {
Race: imolaRace,
eventType: RaceType.GRAND_PRIX,
id: "4",
};

/**
* A schedule with rounds 1-5, where round 4 (Imola) is a sprint weekend.
* Events are in chronological order (sprint before GP for round 4).
*/
export const sprintWeekendSchedule: RaceEvent[] = [
{
Race: {
season: "2022",
round: 1,
raceName: "Bahrain Grand Prix",
Circuit: {
circuitId: "bahrain",
url: "http://en.wikipedia.org/wiki/Bahrain_International_Circuit",
circuitName: "Bahrain International Circuit",
Location: {
lat: 26.0325,
long: 50.5106,
locality: "Sakhir",
country: "Bahrain",
},
},
date: "2022-03-20",
time: "15:00:00Z",
FirstPractice: new Date("2022-03-18T12:00:00Z"),
SecondPractice: new Date("2022-03-18T15:00:00Z"),
ThirdPractice: new Date("2022-03-19T12:00:00Z"),
Qualifying: new Date("2022-03-19T15:00:00Z"),
},
eventType: RaceType.GRAND_PRIX,
id: "1",
},
{
Race: {
season: "2022",
round: 2,
raceName: "Saudi Arabian Grand Prix",
Circuit: {
circuitId: "jeddah",
url: "http://en.wikipedia.org/wiki/Jeddah_Street_Circuit",
circuitName: "Jeddah Corniche Circuit",
Location: {
lat: 21.6319,
long: 39.1044,
locality: "Jeddah",
country: "Saudi Arabia",
},
},
date: "2022-03-27",
time: "17:00:00Z",
FirstPractice: new Date("2022-03-25T14:00:00Z"),
SecondPractice: new Date("2022-03-25T17:00:00Z"),
ThirdPractice: new Date("2022-03-26T14:00:00Z"),
Qualifying: new Date("2022-03-26T17:00:00Z"),
},
eventType: RaceType.GRAND_PRIX,
id: "2",
},
{
Race: {
season: "2022",
round: 3,
raceName: "Australian Grand Prix",
Circuit: {
circuitId: "albert_park",
url: "http://en.wikipedia.org/wiki/Melbourne_Grand_Prix_Circuit",
circuitName: "Albert Park Grand Prix Circuit",
Location: {
lat: -37.8497,
long: 144.968,
locality: "Melbourne",
country: "Australia",
},
},
date: "2022-04-10",
time: "05:00:00Z",
FirstPractice: new Date("2022-04-08T03:00:00Z"),
SecondPractice: new Date("2022-04-08T06:00:00Z"),
ThirdPractice: new Date("2022-04-09T03:00:00Z"),
Qualifying: new Date("2022-04-09T06:00:00Z"),
},
eventType: RaceType.GRAND_PRIX,
id: "3",
},
sprintRaceEvent,
grandPrixEvent,
{
Race: {
season: "2022",
round: 5,
raceName: "Miami Grand Prix",
Circuit: {
circuitId: "miami",
url: "http://en.wikipedia.org/wiki/Miami_International_Autodrome",
circuitName: "Miami International Autodrome",
Location: {
lat: 25.9581,
long: -80.2389,
locality: "Miami",
country: "USA",
},
},
date: "2022-05-08",
time: "19:30:00Z",
FirstPractice: new Date("2022-05-06T18:30:00Z"),
SecondPractice: new Date("2022-05-06T21:30:00Z"),
ThirdPractice: new Date("2022-05-07T17:00:00Z"),
Qualifying: new Date("2022-05-07T20:00:00Z"),
},
eventType: RaceType.GRAND_PRIX,
id: "5",
},
];
118 changes: 118 additions & 0 deletions src/common/getEventDate.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { afterEach, describe, expect, test, vi } from "vitest";

import {
grandPrixEvent,
sprintRaceEvent,
sprintWeekendSchedule,
} from "../../fixtures/sprintWeekend";
import { RaceEvent, RaceType } from "../types/entities";
import { getEventDate } from "./getEventDate";

describe("getEventDate", () => {
test("returns Sprint date for a sprint race event", () => {
const result = getEventDate(sprintRaceEvent);
expect(result).toEqual(new Date("2022-04-23T14:30:00Z"));
});

test("returns race date+time for a grand prix event", () => {
const result = getEventDate(grandPrixEvent);
expect(result).toEqual(new Date("2022-04-24T13:00:00Z"));
});

test("returns undefined for a sprint race event without Sprint date", () => {
const event: RaceEvent = {
...sprintRaceEvent,
Race: { ...sprintRaceEvent.Race, Sprint: undefined },
};
const result = getEventDate(event);
expect(result).toBeUndefined();
});

test("returns undefined for a GP event without date", () => {
const event: RaceEvent = {
...grandPrixEvent,
Race: { ...grandPrixEvent.Race, date: "" },
};
const result = getEventDate(event);
expect(result).toBeUndefined();
});

test("returns undefined for a GP event without time", () => {
const event: RaceEvent = {
...grandPrixEvent,
Race: { ...grandPrixEvent.Race, time: "" },
};
const result = getEventDate(event);
expect(result).toBeUndefined();
});
});

describe("lastRoundIndex logic during sprint weekend", () => {
afterEach(() => {
vi.useRealTimers();
});

function findLastRound(
eventSchedule: RaceEvent[],
standingsRound: number,
now: Date,
) {
const reversedSchedule = eventSchedule.toReversed();
const lastRoundIndex = reversedSchedule.findIndex((event) => {
const eventDate = getEventDate(event);
return (
event.Race.round <= standingsRound &&
eventDate !== undefined &&
eventDate <= now
);
});
return reversedSchedule[lastRoundIndex];
}

test("after sprint only: lastRound is the sprint, not the GP", () => {
// Between sprint (Apr 23 14:30Z) and GP (Apr 24 13:00Z)
const now = new Date("2022-04-23T18:00:00Z");
const lastRound = findLastRound(sprintWeekendSchedule, 4, now);

expect(lastRound).toBeDefined();
expect(lastRound.eventType).toBe(RaceType.SPRINT_RACE);
expect(lastRound.id).toBe("4-s");
});

test("after both sprint and GP: lastRound is the GP", () => {
// After GP (Apr 24 13:00Z)
const now = new Date("2022-04-24T16:00:00Z");
const lastRound = findLastRound(sprintWeekendSchedule, 4, now);

expect(lastRound).toBeDefined();
expect(lastRound.eventType).toBe(RaceType.GRAND_PRIX);
expect(lastRound.id).toBe("4");
});

test("before any events in the round: no match", () => {
// Before sprint (Apr 23 14:30Z), standings still at round 3
const now = new Date("2022-04-22T10:00:00Z");
const lastRound = findLastRound(sprintWeekendSchedule, 3, now);

// Round 3 (Australian GP on Apr 10) is in the past, so it should match
expect(lastRound).toBeDefined();
expect(lastRound.Race.round).toBe(3);
});

test("normal weekend after GP: lastRound is the GP", () => {
// After Australian GP (Apr 10 05:00Z)
const now = new Date("2022-04-10T08:00:00Z");
const lastRound = findLastRound(sprintWeekendSchedule, 3, now);

expect(lastRound).toBeDefined();
expect(lastRound.eventType).toBe(RaceType.GRAND_PRIX);
expect(lastRound.Race.round).toBe(3);
});

test("no races yet: returns undefined", () => {
const now = new Date("2022-01-01T00:00:00Z");
const lastRound = findLastRound(sprintWeekendSchedule, 0, now);

expect(lastRound).toBeUndefined();
});
});
13 changes: 13 additions & 0 deletions src/common/getEventDate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { RaceEvent, RaceType } from "../types/entities";

export function getEventDate(event: RaceEvent): Date | undefined {
if (event.eventType === RaceType.SPRINT_RACE) {
return event.Race.Sprint ? new Date(event.Race.Sprint) : undefined;
}

if (event.Race.date && event.Race.time) {
return new Date(`${event.Race.date}T${event.Race.time}`);
}

return undefined;
}
Loading
Loading