snicco/testable-clock

v2.0.0-beta.9 2024-09-07 14:27 UTC

README

codecov Psalm Type-Coverage Psalm level PhpMetrics - Static Analysis PHP-Versions

The TestableClock component of the Snicco project decouples code from DateTimeImmutable so that its properly testable.

Installation

composer require snicco/testable-clock

Usage

Instead of using DateTimeImmutable and time() directly in your code you use the Clock interface.

use Snicco\Component\TestableClock\Clock;
use Snicco\Component\TestableClock\SystemClock;
use Snicco\Component\TestableClock\TestClock;

class IsTrialExpired {
    
    private  Clock $clock;
    
    public function __construct(Clock $clock) {
        $this->clock = $clock;
    }
        
    public function __invoke(object $trial) {
        return $trial->expiresAt > $this->clock->currentTimestamp();
    }
        
}

// In production code
$clock = SystemClock::fromUTC();

// or
$clock = new SystemClock(new DateTimeZone('Europe/Berlin'));

$is_trial_expired = new IsTrialExpired($clock)

// In test code
$test_clock = new TestClock();

$is_trial_expired = new IsTrialExpired($test_clock)

The TestClock stays frozen, meaning it will always return the same timestamp.

You can advance the clock, or go back in time.

use Snicco\Component\TestableClock\TestClock;

$clock = new TestClock();

$time_0 = $clock->currentTimestamp();

var_dump(time() === $time_0); // true

sleep(10);

$time_01 = $clock->currentTimestamp();

var_dump($time_01 === $time_0); // true
var_dump(time() === $time_01); // false

$clock->travelIntoFuture(10);

$time_02 = $clock->currentTimestamp();

var_dump(time() === $time_02); // true

$time_03 = $clock->travelIntoPast(10);

var_dump($time_03 === $time_01); // true 

Contributing

This repository is a read-only split of the development repo of the Snicco project.

This is how you can contribute.

Reporting issues and sending pull requests

Please report issues in the Snicco monorepo.

Security

If you discover a security vulnerability, please follow our disclosure procedure.