test workload placement
This commit is contained in:
parent
80f8031ecc
commit
465db4a5b8
4 changed files with 345 additions and 0 deletions
129
backend/tests/Unit/Schedule/EvenDistributionSchedulerTest.php
Normal file
129
backend/tests/Unit/Schedule/EvenDistributionSchedulerTest.php
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Unit\Schedule;
|
||||
|
||||
use App\Schedule\EvenDistributionScheduler;
|
||||
use App\Schedule\WorkloadPlacement;
|
||||
use DateTimeImmutable;
|
||||
use DateTimeZone;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class EvenDistributionSchedulerTest extends TestCase
|
||||
{
|
||||
public function test_it_places_one_heavier_day_at_the_requested_position(): void
|
||||
{
|
||||
$scheduler = new EvenDistributionScheduler;
|
||||
$expectedCounts = [
|
||||
WorkloadPlacement::Start->value => [3, 2, 2, 2, 2],
|
||||
WorkloadPlacement::Middle->value => [2, 2, 3, 2, 2],
|
||||
WorkloadPlacement::End->value => [2, 2, 2, 2, 3],
|
||||
];
|
||||
|
||||
foreach (WorkloadPlacement::cases() as $placement) {
|
||||
$dates = $scheduler->scheduledDates(
|
||||
assignmentCount: 11,
|
||||
startDate: $this->utc('2026-08-10'),
|
||||
targetDate: $this->utc('2026-08-14'),
|
||||
workloadPlacement: $placement,
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
$expectedCounts[$placement->value],
|
||||
$this->dailyCounts($dates),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function test_it_keeps_multiple_heavier_days_together(): void
|
||||
{
|
||||
$scheduler = new EvenDistributionScheduler;
|
||||
$expectedCounts = [
|
||||
WorkloadPlacement::Start->value => [3, 3, 2, 2, 2],
|
||||
WorkloadPlacement::Middle->value => [2, 3, 3, 2, 2],
|
||||
WorkloadPlacement::End->value => [2, 2, 2, 3, 3],
|
||||
];
|
||||
|
||||
foreach (WorkloadPlacement::cases() as $placement) {
|
||||
$dates = $scheduler->scheduledDates(
|
||||
assignmentCount: 12,
|
||||
startDate: $this->utc('2026-08-10'),
|
||||
targetDate: $this->utc('2026-08-14'),
|
||||
workloadPlacement: $placement,
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
$expectedCounts[$placement->value],
|
||||
$this->dailyCounts($dates),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function test_it_preserves_sparse_distribution_across_the_full_range(): void
|
||||
{
|
||||
$dates = (new EvenDistributionScheduler)->scheduledDates(
|
||||
assignmentCount: 3,
|
||||
startDate: $this->utc('2026-08-10'),
|
||||
targetDate: $this->utc('2026-08-16'),
|
||||
workloadPlacement: WorkloadPlacement::Middle,
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
['2026-08-10', '2026-08-13', '2026-08-16'],
|
||||
$this->formattedDates($dates),
|
||||
);
|
||||
}
|
||||
|
||||
public function test_it_distributes_even_and_single_day_schedules(): void
|
||||
{
|
||||
$scheduler = new EvenDistributionScheduler;
|
||||
|
||||
$evenDates = $scheduler->scheduledDates(
|
||||
assignmentCount: 10,
|
||||
startDate: $this->utc('2026-08-10'),
|
||||
targetDate: $this->utc('2026-08-14'),
|
||||
workloadPlacement: WorkloadPlacement::End,
|
||||
);
|
||||
$singleDayDates = $scheduler->scheduledDates(
|
||||
assignmentCount: 4,
|
||||
startDate: $this->utc('2026-08-10'),
|
||||
targetDate: $this->utc('2026-08-10'),
|
||||
workloadPlacement: WorkloadPlacement::Middle,
|
||||
);
|
||||
|
||||
$this->assertSame([2, 2, 2, 2, 2], $this->dailyCounts($evenDates));
|
||||
$this->assertSame(
|
||||
[
|
||||
'2026-08-10',
|
||||
'2026-08-10',
|
||||
'2026-08-10',
|
||||
'2026-08-10',
|
||||
],
|
||||
$this->formattedDates($singleDayDates),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<DateTimeImmutable> $dates
|
||||
* @return list<int>
|
||||
*/
|
||||
private function dailyCounts(array $dates): array
|
||||
{
|
||||
return array_values(array_count_values($this->formattedDates($dates)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<DateTimeImmutable> $dates
|
||||
* @return list<string>
|
||||
*/
|
||||
private function formattedDates(array $dates): array
|
||||
{
|
||||
return array_map(function (DateTimeImmutable $date): string {
|
||||
return $date->format('Y-m-d');
|
||||
}, $dates);
|
||||
}
|
||||
|
||||
private function utc(string $date): DateTimeImmutable
|
||||
{
|
||||
return new DateTimeImmutable($date, new DateTimeZone('UTC'));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue