countSuspendedDaysInMonth( new DateTimeImmutable('2026-03-01'), new DateTimeImmutable('2026-03-31'), [] ); self::assertSame(0, $result); } public function testFullMonthSuspension(): void { $calc = new SuspensionDaysCalculator(); $suspension = $this->buildSuspension('2026-03-01', '2026-03-31'); $result = $calc->countSuspendedDaysInMonth( new DateTimeImmutable('2026-03-01'), new DateTimeImmutable('2026-03-31'), [$suspension] ); self::assertSame(31, $result); } public function testPartialMonthSuspension(): void { $calc = new SuspensionDaysCalculator(); $suspension = $this->buildSuspension('2026-03-10', '2026-03-20'); $result = $calc->countSuspendedDaysInMonth( new DateTimeImmutable('2026-03-01'), new DateTimeImmutable('2026-03-31'), [$suspension] ); self::assertSame(11, $result); } public function testSuspensionSpanningMultipleMonths(): void { $calc = new SuspensionDaysCalculator(); $suspension = $this->buildSuspension('2026-02-15', '2026-04-10'); // March fully covered $result = $calc->countSuspendedDaysInMonth( new DateTimeImmutable('2026-03-01'), new DateTimeImmutable('2026-03-31'), [$suspension] ); self::assertSame(31, $result); } public function testSuspensionWithoutEndDate(): void { $calc = new SuspensionDaysCalculator(); $suspension = $this->buildSuspension('2026-03-15', null); $result = $calc->countSuspendedDaysInMonth( new DateTimeImmutable('2026-03-01'), new DateTimeImmutable('2026-03-31'), [$suspension] ); self::assertSame(17, $result); } public function testMultipleSuspensionsInSameMonth(): void { $calc = new SuspensionDaysCalculator(); $s1 = $this->buildSuspension('2026-03-01', '2026-03-10'); $s2 = $this->buildSuspension('2026-03-20', '2026-03-25'); $result = $calc->countSuspendedDaysInMonth( new DateTimeImmutable('2026-03-01'), new DateTimeImmutable('2026-03-31'), [$s1, $s2] ); self::assertSame(16, $result); } public function testSuspensionOutsideMonthReturnsZero(): void { $calc = new SuspensionDaysCalculator(); $suspension = $this->buildSuspension('2026-01-01', '2026-01-31'); $result = $calc->countSuspendedDaysInMonth( new DateTimeImmutable('2026-03-01'), new DateTimeImmutable('2026-03-31'), [$suspension] ); self::assertSame(0, $result); } public function testCountSuspendedBusinessDays(): void { $calc = new SuspensionDaysCalculator(); // March 2-6, 2026 = Mon-Fri = 5 business days $suspension = $this->buildSuspension('2026-03-02', '2026-03-06'); $result = $calc->countSuspendedBusinessDays( new DateTimeImmutable('2026-01-01'), new DateTimeImmutable('2026-12-31'), [$suspension], [] ); self::assertSame(5, $result); } private function buildSuspension(string $start, ?string $end): ContractSuspension { $s = new ContractSuspension(); $s->setStartDate(new DateTimeImmutable($start)); if (null !== $end) { $s->setEndDate(new DateTimeImmutable($end)); } return $s; } }