266 lines
7.7 KiB
TypeScript
266 lines
7.7 KiB
TypeScript
import { beforeEach, describe, expect, it } from 'vitest';
|
|
import { RacingDomainValidationError } from '../../errors/RacingDomainError';
|
|
import { DriverId } from '../DriverId';
|
|
import { RaceId } from '../RaceId';
|
|
import { IncidentCount } from './IncidentCount';
|
|
import { LapTime } from './LapTime';
|
|
import { Position } from './Position';
|
|
import { Result } from './Result';
|
|
|
|
describe('Result', () => {
|
|
const validId = 'result-123';
|
|
const validRaceId = 'race-456';
|
|
const validDriverId = 'driver-789';
|
|
const validPosition = 1;
|
|
const validFastestLap = 95.5;
|
|
const validIncidents = 0;
|
|
const validStartPosition = 2;
|
|
|
|
describe('create', () => {
|
|
it('should create a Result with valid props', () => {
|
|
const props = {
|
|
id: validId,
|
|
raceId: validRaceId,
|
|
driverId: validDriverId,
|
|
position: validPosition,
|
|
fastestLap: validFastestLap,
|
|
incidents: validIncidents,
|
|
startPosition: validStartPosition,
|
|
points: 10,
|
|
};
|
|
|
|
const result = Result.create(props);
|
|
|
|
expect(result.id).toBe(validId);
|
|
expect(result.raceId.toString()).toBe(validRaceId);
|
|
expect(result.driverId.toString()).toBe(validDriverId);
|
|
expect(result.position.toNumber()).toBe(validPosition);
|
|
expect(result.fastestLap.toNumber()).toBe(validFastestLap);
|
|
expect(result.incidents.toNumber()).toBe(validIncidents);
|
|
expect(result.startPosition.toNumber()).toBe(validStartPosition);
|
|
expect(result.points).toBe(10);
|
|
});
|
|
|
|
it('should throw error for empty id', () => {
|
|
const props = {
|
|
id: '',
|
|
raceId: validRaceId,
|
|
driverId: validDriverId,
|
|
position: validPosition,
|
|
fastestLap: validFastestLap,
|
|
incidents: validIncidents,
|
|
startPosition: validStartPosition,
|
|
points: 10,
|
|
};
|
|
|
|
expect(() => Result.create(props)).toThrow(RacingDomainValidationError);
|
|
});
|
|
|
|
it('should throw error for empty raceId', () => {
|
|
const props = {
|
|
id: validId,
|
|
raceId: '',
|
|
driverId: validDriverId,
|
|
position: validPosition,
|
|
fastestLap: validFastestLap,
|
|
incidents: validIncidents,
|
|
startPosition: validStartPosition,
|
|
points: 10,
|
|
};
|
|
|
|
expect(() => Result.create(props)).toThrow(RacingDomainValidationError);
|
|
});
|
|
|
|
it('should throw error for empty driverId', () => {
|
|
const props = {
|
|
id: validId,
|
|
raceId: validRaceId,
|
|
driverId: '',
|
|
position: validPosition,
|
|
fastestLap: validFastestLap,
|
|
incidents: validIncidents,
|
|
startPosition: validStartPosition,
|
|
};
|
|
|
|
expect(() => Result.create(props)).toThrow(RacingDomainValidationError);
|
|
});
|
|
|
|
it('should throw error for invalid position', () => {
|
|
const props = {
|
|
id: validId,
|
|
raceId: validRaceId,
|
|
driverId: validDriverId,
|
|
position: 0,
|
|
fastestLap: validFastestLap,
|
|
incidents: validIncidents,
|
|
startPosition: validStartPosition,
|
|
};
|
|
|
|
expect(() => Result.create(props)).toThrow(RacingDomainValidationError);
|
|
});
|
|
|
|
it('should throw error for invalid fastestLap', () => {
|
|
const props = {
|
|
id: validId,
|
|
raceId: validRaceId,
|
|
driverId: validDriverId,
|
|
position: validPosition,
|
|
fastestLap: -1,
|
|
incidents: validIncidents,
|
|
startPosition: validStartPosition,
|
|
};
|
|
|
|
expect(() => Result.create(props)).toThrow(RacingDomainValidationError);
|
|
});
|
|
|
|
it('should throw error for invalid incidents', () => {
|
|
const props = {
|
|
id: validId,
|
|
raceId: validRaceId,
|
|
driverId: validDriverId,
|
|
position: validPosition,
|
|
fastestLap: validFastestLap,
|
|
incidents: -1,
|
|
startPosition: validStartPosition,
|
|
};
|
|
|
|
expect(() => Result.create(props)).toThrow(RacingDomainValidationError);
|
|
});
|
|
|
|
it('should throw error for invalid startPosition', () => {
|
|
const props = {
|
|
id: validId,
|
|
raceId: validRaceId,
|
|
driverId: validDriverId,
|
|
position: validPosition,
|
|
fastestLap: validFastestLap,
|
|
incidents: validIncidents,
|
|
startPosition: 0,
|
|
};
|
|
|
|
expect(() => Result.create(props)).toThrow(RacingDomainValidationError);
|
|
});
|
|
});
|
|
|
|
describe('entity properties', () => {
|
|
let result: Result;
|
|
|
|
beforeEach(() => {
|
|
result = Result.create({
|
|
id: validId,
|
|
raceId: validRaceId,
|
|
driverId: validDriverId,
|
|
position: validPosition,
|
|
fastestLap: validFastestLap,
|
|
incidents: validIncidents,
|
|
startPosition: validStartPosition,
|
|
});
|
|
});
|
|
|
|
it('should have readonly id', () => {
|
|
expect(result.id).toBe(validId);
|
|
});
|
|
|
|
it('should have readonly raceId as RaceId', () => {
|
|
expect(result.raceId).toBeInstanceOf(RaceId);
|
|
expect(result.raceId.toString()).toBe(validRaceId);
|
|
});
|
|
|
|
it('should have readonly driverId as DriverId', () => {
|
|
expect(result.driverId).toBeInstanceOf(DriverId);
|
|
expect(result.driverId.toString()).toBe(validDriverId);
|
|
});
|
|
|
|
it('should have readonly position as Position', () => {
|
|
expect(result.position).toBeInstanceOf(Position);
|
|
expect(result.position.toNumber()).toBe(validPosition);
|
|
});
|
|
|
|
it('should have readonly fastestLap as LapTime', () => {
|
|
expect(result.fastestLap).toBeInstanceOf(LapTime);
|
|
expect(result.fastestLap.toNumber()).toBe(validFastestLap);
|
|
});
|
|
|
|
it('should have readonly incidents as IncidentCount', () => {
|
|
expect(result.incidents).toBeInstanceOf(IncidentCount);
|
|
expect(result.incidents.toNumber()).toBe(validIncidents);
|
|
});
|
|
|
|
it('should have readonly startPosition as Position', () => {
|
|
expect(result.startPosition).toBeInstanceOf(Position);
|
|
expect(result.startPosition.toNumber()).toBe(validStartPosition);
|
|
});
|
|
});
|
|
|
|
describe('domain methods', () => {
|
|
it('should calculate position change correctly', () => {
|
|
const result = Result.create({
|
|
id: validId,
|
|
raceId: validRaceId,
|
|
driverId: validDriverId,
|
|
position: 1,
|
|
fastestLap: validFastestLap,
|
|
incidents: validIncidents,
|
|
startPosition: 3,
|
|
});
|
|
|
|
expect(result.getPositionChange()).toBe(2); // 3 - 1
|
|
});
|
|
|
|
it('should return true for podium finish', () => {
|
|
const result = Result.create({
|
|
id: validId,
|
|
raceId: validRaceId,
|
|
driverId: validDriverId,
|
|
position: 3,
|
|
fastestLap: validFastestLap,
|
|
incidents: validIncidents,
|
|
startPosition: validStartPosition,
|
|
});
|
|
|
|
expect(result.isPodium()).toBe(true);
|
|
});
|
|
|
|
it('should return false for non-podium finish', () => {
|
|
const result = Result.create({
|
|
id: validId,
|
|
raceId: validRaceId,
|
|
driverId: validDriverId,
|
|
position: 4,
|
|
fastestLap: validFastestLap,
|
|
incidents: validIncidents,
|
|
startPosition: validStartPosition,
|
|
});
|
|
|
|
expect(result.isPodium()).toBe(false);
|
|
});
|
|
|
|
it('should return true for clean race', () => {
|
|
const result = Result.create({
|
|
id: validId,
|
|
raceId: validRaceId,
|
|
driverId: validDriverId,
|
|
position: validPosition,
|
|
fastestLap: validFastestLap,
|
|
incidents: 0,
|
|
startPosition: validStartPosition,
|
|
});
|
|
|
|
expect(result.isClean()).toBe(true);
|
|
});
|
|
|
|
it('should return false for race with incidents', () => {
|
|
const result = Result.create({
|
|
id: validId,
|
|
raceId: validRaceId,
|
|
driverId: validDriverId,
|
|
position: validPosition,
|
|
fastestLap: validFastestLap,
|
|
incidents: 1,
|
|
startPosition: validStartPosition,
|
|
});
|
|
|
|
expect(result.isClean()).toBe(false);
|
|
});
|
|
});
|
|
}); |