timezone = date_default_timezone_get(); date_default_timezone_set('Europe/Zurich'); } protected function tearDown(): void { date_default_timezone_set($this->timezone); } public function testCalendarRangesUseLocalBoundaries(): void { [$dayStart, $dayEnd] = EnergyChartCalculator::rangeBounds( 'day', '2026-09-27', '2026-09-01', '2026-09-02' ); self::assertSame('2026-09-27 00:00', date('Y-m-d H:i', $dayStart)); self::assertSame('2026-09-28 00:00', date('Y-m-d H:i', $dayEnd)); [$weekStart, $weekEnd] = EnergyChartCalculator::rangeBounds( 'week', '2026-09-27', '2026-09-01', '2026-09-02' ); self::assertSame('2026-09-21', date('Y-m-d', $weekStart)); self::assertSame('2026-09-28', date('Y-m-d', $weekEnd)); [$monthStart, $monthEnd] = EnergyChartCalculator::rangeBounds( 'month', '2026-09-27', '2026-09-01', '2026-09-02' ); self::assertSame('2026-09-01', date('Y-m-d', $monthStart)); self::assertSame('2026-10-01', date('Y-m-d', $monthEnd)); [$yearStart, $yearEnd] = EnergyChartCalculator::rangeBounds( 'year', '2026-09-27', '2026-09-01', '2026-09-02' ); self::assertSame('2026-01-01', date('Y-m-d', $yearStart)); self::assertSame('2027-01-01', date('Y-m-d', $yearEnd)); } public function testCustomRangeIncludesCompleteEndDateAcrossDstChange(): void { [$start, $end] = EnergyChartCalculator::rangeBounds( 'custom', '2026-03-29', '2026-03-28', '2026-03-30' ); self::assertSame('2026-03-28 00:00', date('Y-m-d H:i', $start)); self::assertSame('2026-03-31 00:00', date('Y-m-d H:i', $end)); } public function testInvalidCustomRangeIsRejected(): void { $this->expectException(InvalidArgumentException::class); EnergyChartCalculator::rangeBounds( 'custom', '2026-09-27', '2026-09-28', '2026-09-27' ); } public function testMetricsUseDerivedOrExplicitConsumption(): void { $derived = EnergyChartCalculator::metrics(20.0, 5.0, 3.0); self::assertSame(18.0, $derived['Hausverbrauch']); self::assertSame(15.0, $derived['Eigenverbrauch']); self::assertSame(75.0, $derived['Eigenverbrauchsquote']); self::assertEqualsWithDelta(83.3333, $derived['Autarkiegrad'], 0.001); $explicit = EnergyChartCalculator::metrics(20.0, 5.0, 3.0, 16.0); self::assertSame(16.0, $explicit['Hausverbrauch']); self::assertSame(13.0, $explicit['Eigenverbrauch']); self::assertSame(65.0, $explicit['Eigenverbrauchsquote']); self::assertSame(81.25, $explicit['Autarkiegrad']); } public function testColorsAreValidatedAndNormalized(): void { self::assertSame( '#2F80ED', EnergyChartCalculator::normalizeColor('#2f80ed', '#000000') ); self::assertSame( '#00FF4C', EnergyChartCalculator::normalizeColor('65356', '#000000') ); self::assertSame( '#000000', EnergyChartCalculator::normalizeColor('0', '#FFFFFF') ); self::assertSame( '#22A06B', EnergyChartCalculator::normalizeColor('16777216', '#22a06b') ); self::assertSame( '#22A06B', EnergyChartCalculator::normalizeColor('-1', '#22a06b') ); } }