279 lines
8.4 KiB
TypeScript
279 lines
8.4 KiB
TypeScript
/**
|
|
* Tests for ScheduleCalculator have been moved to:
|
|
* tests/unit/domain/services/ScheduleCalculator.test.ts
|
|
*
|
|
* This file is kept as a stub to avoid placing tests under domain/services.
|
|
*/
|
|
describe('calculateRaceDates', () => {
|
|
describe('with empty or invalid input', () => {
|
|
it('should return empty array when weekdays is empty', () => {
|
|
// Given
|
|
const config: ScheduleConfig = {
|
|
weekdays: [],
|
|
frequency: 'weekly',
|
|
rounds: 8,
|
|
startDate: new Date('2024-01-01'),
|
|
};
|
|
|
|
// When
|
|
const result = calculateRaceDates(config);
|
|
|
|
// Then
|
|
expect(result.raceDates).toEqual([]);
|
|
expect(result.seasonDurationWeeks).toBe(0);
|
|
});
|
|
|
|
it('should return empty array when rounds is 0', () => {
|
|
// Given
|
|
const config: ScheduleConfig = {
|
|
weekdays: ['Sat'] as Weekday[],
|
|
frequency: 'weekly',
|
|
rounds: 0,
|
|
startDate: new Date('2024-01-01'),
|
|
};
|
|
|
|
// When
|
|
const result = calculateRaceDates(config);
|
|
|
|
// Then
|
|
expect(result.raceDates).toEqual([]);
|
|
});
|
|
|
|
it('should return empty array when rounds is negative', () => {
|
|
// Given
|
|
const config: ScheduleConfig = {
|
|
weekdays: ['Sat'] as Weekday[],
|
|
frequency: 'weekly',
|
|
rounds: -5,
|
|
startDate: new Date('2024-01-01'),
|
|
};
|
|
|
|
// When
|
|
const result = calculateRaceDates(config);
|
|
|
|
// Then
|
|
expect(result.raceDates).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe('weekly scheduling', () => {
|
|
it('should schedule 8 races on Saturdays starting from a Saturday', () => {
|
|
// Given - January 6, 2024 is a Saturday
|
|
const config: ScheduleConfig = {
|
|
weekdays: ['Sat'] as Weekday[],
|
|
frequency: 'weekly',
|
|
rounds: 8,
|
|
startDate: new Date('2024-01-06'),
|
|
};
|
|
|
|
// When
|
|
const result = calculateRaceDates(config);
|
|
|
|
// Then
|
|
expect(result.raceDates.length).toBe(8);
|
|
// All dates should be Saturdays
|
|
result.raceDates.forEach(date => {
|
|
expect(date.getDay()).toBe(6); // Saturday
|
|
});
|
|
// First race should be Jan 6
|
|
expect(result.raceDates[0].toISOString().split('T')[0]).toBe('2024-01-06');
|
|
// Last race should be 7 weeks later (Feb 24)
|
|
expect(result.raceDates[7].toISOString().split('T')[0]).toBe('2024-02-24');
|
|
});
|
|
|
|
it('should schedule races on multiple weekdays', () => {
|
|
// Given
|
|
const config: ScheduleConfig = {
|
|
weekdays: ['Wed', 'Sat'] as Weekday[],
|
|
frequency: 'weekly',
|
|
rounds: 8,
|
|
startDate: new Date('2024-01-01'), // Monday
|
|
};
|
|
|
|
// When
|
|
const result = calculateRaceDates(config);
|
|
|
|
// Then
|
|
expect(result.raceDates.length).toBe(8);
|
|
// Should alternate between Wednesday and Saturday
|
|
result.raceDates.forEach(date => {
|
|
const day = date.getDay();
|
|
expect([3, 6]).toContain(day); // Wed=3, Sat=6
|
|
});
|
|
});
|
|
|
|
it('should schedule 8 races on Sundays', () => {
|
|
// Given - January 7, 2024 is a Sunday
|
|
const config: ScheduleConfig = {
|
|
weekdays: ['Sun'] as Weekday[],
|
|
frequency: 'weekly',
|
|
rounds: 8,
|
|
startDate: new Date('2024-01-01'),
|
|
};
|
|
|
|
// When
|
|
const result = calculateRaceDates(config);
|
|
|
|
// Then
|
|
expect(result.raceDates.length).toBe(8);
|
|
result.raceDates.forEach(date => {
|
|
expect(date.getDay()).toBe(0); // Sunday
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('bi-weekly scheduling', () => {
|
|
it('should schedule races every 2 weeks on Saturdays', () => {
|
|
// Given - January 6, 2024 is a Saturday
|
|
const config: ScheduleConfig = {
|
|
weekdays: ['Sat'] as Weekday[],
|
|
frequency: 'everyNWeeks',
|
|
rounds: 4,
|
|
startDate: new Date('2024-01-06'),
|
|
intervalWeeks: 2,
|
|
};
|
|
|
|
// When
|
|
const result = calculateRaceDates(config);
|
|
|
|
// Then
|
|
expect(result.raceDates.length).toBe(4);
|
|
// First race Jan 6
|
|
expect(result.raceDates[0].toISOString().split('T')[0]).toBe('2024-01-06');
|
|
// Second race 2 weeks later (Jan 20)
|
|
expect(result.raceDates[1].toISOString().split('T')[0]).toBe('2024-01-20');
|
|
// Third race 2 weeks later (Feb 3)
|
|
expect(result.raceDates[2].toISOString().split('T')[0]).toBe('2024-02-03');
|
|
// Fourth race 2 weeks later (Feb 17)
|
|
expect(result.raceDates[3].toISOString().split('T')[0]).toBe('2024-02-17');
|
|
});
|
|
});
|
|
|
|
describe('with start and end dates', () => {
|
|
it('should evenly distribute races across the date range', () => {
|
|
// Given - 3 month season
|
|
const config: ScheduleConfig = {
|
|
weekdays: ['Sat'] as Weekday[],
|
|
frequency: 'weekly',
|
|
rounds: 8,
|
|
startDate: new Date('2024-01-06'),
|
|
endDate: new Date('2024-03-30'),
|
|
};
|
|
|
|
// When
|
|
const result = calculateRaceDates(config);
|
|
|
|
// Then
|
|
expect(result.raceDates.length).toBe(8);
|
|
// First race should be at or near start
|
|
expect(result.raceDates[0].toISOString().split('T')[0]).toBe('2024-01-06');
|
|
// Races should be spread across the range, not consecutive weeks
|
|
});
|
|
|
|
it('should use all available days if fewer than rounds requested', () => {
|
|
// Given - short period with only 3 Saturdays
|
|
const config: ScheduleConfig = {
|
|
weekdays: ['Sat'] as Weekday[],
|
|
frequency: 'weekly',
|
|
rounds: 10,
|
|
startDate: new Date('2024-01-06'),
|
|
endDate: new Date('2024-01-21'),
|
|
};
|
|
|
|
// When
|
|
const result = calculateRaceDates(config);
|
|
|
|
// Then
|
|
// Only 3 Saturdays in this range: Jan 6, 13, 20
|
|
expect(result.raceDates.length).toBe(3);
|
|
});
|
|
});
|
|
|
|
describe('season duration calculation', () => {
|
|
it('should calculate correct season duration in weeks', () => {
|
|
// Given
|
|
const config: ScheduleConfig = {
|
|
weekdays: ['Sat'] as Weekday[],
|
|
frequency: 'weekly',
|
|
rounds: 8,
|
|
startDate: new Date('2024-01-06'),
|
|
};
|
|
|
|
// When
|
|
const result = calculateRaceDates(config);
|
|
|
|
// Then
|
|
// 8 races, 1 week apart = 7 weeks duration
|
|
expect(result.seasonDurationWeeks).toBe(7);
|
|
});
|
|
|
|
it('should return 0 duration for single race', () => {
|
|
// Given
|
|
const config: ScheduleConfig = {
|
|
weekdays: ['Sat'] as Weekday[],
|
|
frequency: 'weekly',
|
|
rounds: 1,
|
|
startDate: new Date('2024-01-06'),
|
|
};
|
|
|
|
// When
|
|
const result = calculateRaceDates(config);
|
|
|
|
// Then
|
|
expect(result.raceDates.length).toBe(1);
|
|
expect(result.seasonDurationWeeks).toBe(0);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('getNextWeekday', () => {
|
|
it('should return next Saturday from a Monday', () => {
|
|
// Given - January 1, 2024 is a Monday
|
|
const fromDate = new Date('2024-01-01');
|
|
|
|
// When
|
|
const result = getNextWeekday(fromDate, 'Sat');
|
|
|
|
// Then
|
|
expect(result.toISOString().split('T')[0]).toBe('2024-01-06');
|
|
expect(result.getDay()).toBe(6);
|
|
});
|
|
|
|
it('should return next occurrence when already on that weekday', () => {
|
|
// Given - January 6, 2024 is a Saturday
|
|
const fromDate = new Date('2024-01-06');
|
|
|
|
// When
|
|
const result = getNextWeekday(fromDate, 'Sat');
|
|
|
|
// Then
|
|
// Should return NEXT Saturday (7 days later), not same day
|
|
expect(result.toISOString().split('T')[0]).toBe('2024-01-13');
|
|
});
|
|
|
|
it('should return next Sunday from a Friday', () => {
|
|
// Given - January 5, 2024 is a Friday
|
|
const fromDate = new Date('2024-01-05');
|
|
|
|
// When
|
|
const result = getNextWeekday(fromDate, 'Sun');
|
|
|
|
// Then
|
|
expect(result.toISOString().split('T')[0]).toBe('2024-01-07');
|
|
expect(result.getDay()).toBe(0);
|
|
});
|
|
|
|
it('should return next Wednesday from a Thursday', () => {
|
|
// Given - January 4, 2024 is a Thursday
|
|
const fromDate = new Date('2024-01-04');
|
|
|
|
// When
|
|
const result = getNextWeekday(fromDate, 'Wed');
|
|
|
|
// Then
|
|
// Next Wednesday is 6 days later
|
|
expect(result.toISOString().split('T')[0]).toBe('2024-01-10');
|
|
expect(result.getDay()).toBe(3);
|
|
});
|
|
});
|
|
}); |