ldc-arcadia-api/tests/Unit/Shared/Time/ClockTest.php

97 lines
3.5 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
namespace Tests\Unit\Shared\Time;
use Psr\Clock\ClockInterface;
use Shared\Time\Clock;
use Shared\Time\FrozenClock;
use Shared\Time\SystemClock;
use Shared\Time\SystemUtcClock;
use Shared\Time\Utc;
covers(
SystemClock::class,
SystemUtcClock::class,
FrozenClock::class,
Utc::class,
);
afterEach(function (): void {
Utc::restore();
});
describe('PSR-20 UTC Clock Unit Tests', function (): void {
it('implements Psr ClockInterface and Clock contract with configured timezone', function (): void {
// GIVEN
$parisClock = new SystemClock(new \DateTimeZone('Europe/Paris'));
$utcClock = new SystemUtcClock();
// WHEN
$parisNow = $parisClock->now();
$utcNow = $utcClock->now();
// THEN
expect($parisClock)->toBeInstanceOf(ClockInterface::class)
->and($parisClock)->toBeInstanceOf(Clock::class)
->and($parisNow->getTimezone()->getName())->toBe('Europe/Paris')
->and($parisClock->timezone()->getName())->toBe('Europe/Paris')
->and($utcNow->getTimezone()->getName())->toBe('UTC');
});
it('parses date strings and normalizes to UTC with SystemUtcClock', function (): void {
// GIVEN
$clock = new SystemUtcClock();
// WHEN
$utcTime = $clock->parse('2026-08-21T15:00:00+02:00');
$startOfDay = $clock->startOfDay('2026-08-21');
$endOfDay = $clock->endOfDay('2026-08-21');
$isoString = $clock->toIso8601($utcTime);
// THEN
expect($utcTime->getTimezone()->getName())->toBe('UTC')
->and($utcTime->format('Y-m-d H:i:s'))->toBe('2026-08-21 13:00:00')
->and($startOfDay->format('Y-m-d H:i:s'))->toBe('2026-08-21 00:00:00')
->and($endOfDay->format('Y-m-d H:i:s.u'))->toBe('2026-08-21 23:59:59.999999')
->and($isoString)->toBe('2026-08-21T13:00:00+00:00');
});
it('allows freezing and manipulating time with FrozenClock', function (): void {
// GIVEN
$fixedTime = new \DateTimeImmutable('2026-08-21 10:00:00', new \DateTimeZone('UTC'));
$frozenClock = new FrozenClock($fixedTime);
// THEN
expect($frozenClock->now()->format('Y-m-d H:i:s'))->toBe('2026-08-21 10:00:00');
// WHEN
$frozenClock->setTo('2026-12-31 23:59:59');
// THEN
expect($frozenClock->now()->format('Y-m-d H:i:s'))->toBe('2026-12-31 23:59:59')
->and($frozenClock->now()->getTimezone()->getName())->toBe('UTC');
});
it('provides centralized static access through Utc facade', function (): void {
// GIVEN
$frozen = Utc::freeze(new \DateTimeImmutable('2026-08-21 14:00:00', new \DateTimeZone('UTC')));
// THEN
expect(Utc::now()->format('Y-m-d H:i:s'))->toBe('2026-08-21 14:00:00')
->and(Utc::parse('2026-08-21 12:00:00')->format('Y-m-d H:i:s'))->toBe('2026-08-21 12:00:00')
->and(Utc::startOfDay('2026-08-21')->format('Y-m-d H:i:s'))->toBe('2026-08-21 00:00:00')
->and(Utc::endOfDay('2026-08-21')->format('Y-m-d H:i:s'))->toBe('2026-08-21 23:59:59')
->and(Utc::toRfc3339('2026-08-21 14:00:00'))->toBe('2026-08-21T14:00:00+00:00')
->and(Utc::toNullableRfc3339(null))->toBeNull()
->and(Utc::toNullableRfc3339('2026-08-21 14:00:00'))->toBe('2026-08-21T14:00:00+00:00');
// WHEN
Utc::restore();
// THEN
expect(Utc::getClock())->toBeInstanceOf(SystemUtcClock::class);
});
});