diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c3c2e5..4250c46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `Clock` interface has a `sleep()` method - `PsrToOrisaiClockAdapter` - makes any PSR clock compatible with `Orisai\Clock\Clock` - `SymfonyToOrisaiClockAdapter` - makes any symfony/clock compatible with `Orisai\Clock\Clock` +- `ClockAdapterFactory` - chooses best supported adapter for `Orisai\Clock\Clock` compatibility ### Changed diff --git a/docs/README.md b/docs/README.md index e82d52e..46c35eb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -14,6 +14,7 @@ Provides current time for runtime and controllable time for testing - [System clock](#system-clock) - [Frozen clock](#frozen-clock) - [Measurement clock](#measurement-clock) +- [Clock adapters](#clock-adapters) - [PSR to Orisai clock adapter](#psr-to-orisai-clock-adapter) - [Symfony to Orisai clock adapter](#symfony-to-orisai-clock-adapter) - [Integrations and extensions](#integrations-and-extensions) @@ -150,6 +151,21 @@ use DateTimeZone; $clock = new MeasurementClock(new DateTimeZone('UTC')); ``` +## Clock adapters + +Use `ClockAdapterFactory` to automatically create the best adapter for `Orisai\Clock\Clock` compatibility from +your `Psr\Clock\ClockInterface`. + +- It creates no adapter for `Orisai\Clock\Clock` instance and just returns it +- It prefers Symfony adapter over PSR adapter for `sleep()` method compatibility + +```php +use Orisai\Clock\Adapter\ClockAdapterFactory; +use Symfony\Component\Clock\NativeClock; + +$clock = ClockAdapterFactory::create($somePsrCompatibleClock); +``` + ### PSR to Orisai clock adapter Decorate any `Psr\Clock\ClockInterface` implementation to conform interface `Orisai\Clock\Clock`. diff --git a/src/Adapter/ClockAdapterFactory.php b/src/Adapter/ClockAdapterFactory.php new file mode 100644 index 0000000..8566032 --- /dev/null +++ b/src/Adapter/ClockAdapterFactory.php @@ -0,0 +1,25 @@ + $class + * + * @dataProvider provide + */ + public function test(ClockInterface $clock, string $class): void + { + self::assertInstanceOf( + $class, + ClockAdapterFactory::create($clock), + ); + } + + public function provide(): Generator + { + yield [ + new class implements ClockInterface { + + public function now(): DateTimeImmutable + { + return new DateTimeImmutable(); + } + + }, + PsrToOrisaiClockAdapter::class, + ]; + + yield [ + new FrozenClock(0), + FrozenClock::class, + ]; + + yield [ + new SystemClock(), + SystemClock::class, + ]; + + if (class_exists(SymfonyClock::class)) { + yield [ + new NativeClock(), + NativeClock::class, + ]; + } + } + +}