pamil / clock

Lendable Clock Abstraction

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Lendable Clock Abstraction

Latest Stable Version License

Provides an object-oriented interface for retrieving the current time.

PHP of course provides \DateTime, \DateTimeImmutable and \DateTimeInterface. Why do we need a clock then? Why not just instantiate where required?

We can obtain the current time with $now = new \DateTime() after all, why do we need a Clock::now(): \DateTimeImmutable style API to obtain the current time?

Depending on a Clock rather than constructing native PHP time objects ad hoc means you can both reason and control time.

  • Underlying implementation can be swapped out to one more suitable for a test environment.
    • Time can now be stubbed with a fixed value, or even start from a point in time and tick from there.
    • Interactions with the Clock can be observed and asserted on.
    • Time passing can be simulated with changes to the output from the Clock.
    • Tests that make poor assumptions can be avoided, i.e., capturing the current time to the second, then asserting that an expected output matches it. However, time passed during the setup to the assertion, and this time it crossed the second boundary.
  • Clear dependencies on classes that require to obtain the current system time.
  • The PSR proposal for a Clock contains further information and examples of current libraries and their solutions and workarounds to provide mocking support.

This library makes no attempt to mock global state, such as \time() or calls to new \DateTimeImmutable(). You will have conflicts if you cannot assert enough control over your dependencies to ensure all current system time retrieval goes through the Clock.

Installation

You can install the library via Composer.

composer require lendable/clock

Clock types

SystemClock

Delegates to PHP for the current system time, uses a fixed timezone at construction.

Target: runtime

FixedClock

Always provides a specific timestamp that is provided at construction.

Target: unit tests

PersistedFixedClock

Similar to FixedClock, but can persist and load the given timestamp from disk. Use PersistedFixedClock::initializeWith(...) to set up the timestamp and PersistedFixedClock::fromPersisted(...) to load from the persisted value on disk.

Target: functional tests where you reload your context. E.g. Behat vs Symfony Kernel. You would initialize in a BeforeScenario hook and then load the data from within the Kernel.

About

Lendable Clock Abstraction

License:MIT License


Languages

Language:PHP 99.1%Language:Shell 0.9%