type); self::assertCount(3, $config->periods); self::assertSame('T1', $config->periods[0]->label); self::assertSame('2025-09-01', $config->periods[0]->startDate->format('Y-m-d')); self::assertSame('2025-11-30', $config->periods[0]->endDate->format('Y-m-d')); self::assertSame('T2', $config->periods[1]->label); self::assertSame('2025-12-01', $config->periods[1]->startDate->format('Y-m-d')); self::assertSame('2026-02-28', $config->periods[1]->endDate->format('Y-m-d')); self::assertSame('T3', $config->periods[2]->label); self::assertSame('2026-03-01', $config->periods[2]->startDate->format('Y-m-d')); self::assertSame('2026-06-30', $config->periods[2]->endDate->format('Y-m-d')); } #[Test] public function itHandlesLeapYearForTrimesters(): void { // 2023-2024 : 2024 is a leap year, Feb has 29 days $config = DefaultPeriods::forType(PeriodType::TRIMESTER, 2023); self::assertSame('2024-02-29', $config->periods[1]->endDate->format('Y-m-d')); self::assertSame('2024-03-01', $config->periods[2]->startDate->format('Y-m-d')); } #[Test] public function itHandlesNonLeapYearForTrimesters(): void { // 2024-2025 : 2025 is not a leap year $config = DefaultPeriods::forType(PeriodType::TRIMESTER, 2024); self::assertSame('2025-02-28', $config->periods[1]->endDate->format('Y-m-d')); self::assertSame('2025-03-01', $config->periods[2]->startDate->format('Y-m-d')); } #[Test] public function itGeneratesDefaultSemesters(): void { $config = DefaultPeriods::forType(PeriodType::SEMESTER, 2025); self::assertSame(PeriodType::SEMESTER, $config->type); self::assertCount(2, $config->periods); self::assertSame('S1', $config->periods[0]->label); self::assertSame('2025-09-01', $config->periods[0]->startDate->format('Y-m-d')); self::assertSame('2026-01-31', $config->periods[0]->endDate->format('Y-m-d')); self::assertSame('S2', $config->periods[1]->label); self::assertSame('2026-02-01', $config->periods[1]->startDate->format('Y-m-d')); self::assertSame('2026-06-30', $config->periods[1]->endDate->format('Y-m-d')); } }