raigu/psr20-clock-testdoubles

Test Doubles for PSR-20 clock interface

dev-main / 0.1.x-dev 2021-09-02 18:26 UTC

This package is auto-updated.

Last update: 2024-03-29 04:39:05 UTC


README

Latest Stable Version Latest Unstable Version Fallows SemVer build codecov Mutation testing badge License: MIT

Test Doubles for PSR-20 clock

Unstable because the PSR-20 is not officially released yet.

Compatibility

  • PHP 7.4, ^8.0
  • psr/clock==@dev

Changes

./CHANGELOG.md

Install

$ composer require --dev raigu/psr20-clock-testdoubles

Test Doubles

FrozenClock

Clock frozen in time. It always returns the same time now matter how many times the now is called.

// creating with current system date and time
$clock = new \Raigu\TestDouble\Psr20\FrozenClock;

// creating with predefined date and time at
$clock = new \Raigu\TestDouble\Psr20\FrozenClock(
    new DateTimeImmutable('2020-01-02')
);

TimeTravelClock

Clock that acts like normal clock but has a shift in time if given.

// By default, acts like normal clock. 
$clock = new \Raigu\TestDouble\Psr20\TimeTravelClock();
$moment = $clock->now();
sleep(2);
// after two seconds the TimeTravelClock is also moved forward.
assert($moment->add(new DateInterval('PT2S'))->getTimestamp() === $clock->now()->getTimestamp());

// Moving to the specific date and time in the future or past:
$clock->travelInTime(new DateTimeImmutable('2020-01-02'));
assert($clock->now()->format('Y-m-d') === '2020-01-02');

// Move by the specific interval to the future
$clock->travelInTimeByInterval(new DateInterval('P10D'));
assert($clock->now()->format('Y-m-d') === '2020-01-12');

// Move by the specific interval to the past
$clock->travelInTimeByInterval(DateInterval::createFromDateString('-1 day'));
assert($clock->now()->format('Y-m-d') === '2020-01-11');

The TimeTravelClock implements the Decorator pattern by wrapping a clock implementation. By default, it uses a system clock implementation, but it can be replaced in constructor.

For example, it is possible to create TimeTravelClock that is frozen by using FrozenClock:

$clock = new \Raigu\TestDouble\Psr20\TimeTravelClock(
    new Raigu\TestDouble\Psr20\FrozenClock()
);
$moment = $clock->now();
sleep(2);
assert($moment->getTimestamp() === $clock->getTimestamp(), 'Does not tick because base clock is frozen.');

Testing

$ composer test
$ composer specification 
$ composer coverage