SafetyVantage Coding Challenge
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

68 lines
2.1 KiB

import { GamesLogError } from "./errors/games_log_error.js";
import { GamesLogParser, LogData } from "./games_log_parser.js";
import { GameEvent } from "../game/events/game_event.js";
import { GameStartedEvent } from "../game/events/game_started_event.js";
import { PlayerJoinedEvent } from "../game/events/player_joined_event.js";
import { PlayerRolledEvent } from "../game/events/player_rolled_event.js";
export class GamesLog {
private logData: LogData = [];
private gamesLogParser = new GamesLogParser();
async loadFile(filename: string, encoding?: BufferEncoding) {
this.logData = await this.gamesLogParser.parseFile(filename, encoding);
}
async readEvents() {
return this.logData.map((row, rowNumber) => {
const payload = row.eventPayload;
const requireProperties = this.requirePropertiesFor(payload, rowNumber);
let gameEvent: GameEvent;
switch (row.eventType) {
case "player_rolls_dice":
requireProperties("gameId", "playerId", "roll");
gameEvent = new PlayerRolledEvent(
payload.gameId,
payload.playerId,
payload.roll
);
break;
case "player_joins_game":
requireProperties("gameId", "playerId");
gameEvent = new PlayerJoinedEvent(payload.gameId, payload.playerId);
break;
case "game_started":
requireProperties("gameId");
gameEvent = new GameStartedEvent(payload.gameId);
break;
default:
throw new Error(
`Unknown event type: "${payload.eventType}" on row ${rowNumber}`
);
}
return gameEvent;
});
}
private requirePropertiesFor(
payload: { [key: string]: any },
rowNumber: number
) {
return (...props: string[]) =>
props.forEach((name) => {
if (!(name in payload)) {
throw new GamesLogError(
`Missing property: ${name} for event on row ${rowNumber}`
);
}
if (!Number.isInteger(payload[name])) {
throw new GamesLogError(
`Invalid value for: ${name} on row ${rowNumber}`
);
}
});
}
}