From 8e2af95ac652aa5350b288adf47b6de05384f20f Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 28 Nov 2022 14:30:22 +0100 Subject: [PATCH] [Clock] Add ClockAwareTrait to help write time-sensitive classes --- src/Symfony/Component/Clock/CHANGELOG.md | 5 +++ .../Component/Clock/ClockAwareTrait.php | 36 +++++++++++++++++ .../Clock/Tests/ClockAwareTraitTest.php | 40 +++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 src/Symfony/Component/Clock/ClockAwareTrait.php create mode 100644 src/Symfony/Component/Clock/Tests/ClockAwareTraitTest.php diff --git a/src/Symfony/Component/Clock/CHANGELOG.md b/src/Symfony/Component/Clock/CHANGELOG.md index 5ffa40eff75d..9bb1c2d4148e 100644 --- a/src/Symfony/Component/Clock/CHANGELOG.md +++ b/src/Symfony/Component/Clock/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +6.3 +--- + + * Add `ClockAwareTrait` to help write time-sensitive classes + 6.2 --- diff --git a/src/Symfony/Component/Clock/ClockAwareTrait.php b/src/Symfony/Component/Clock/ClockAwareTrait.php new file mode 100644 index 000000000000..22f5d4698a0a --- /dev/null +++ b/src/Symfony/Component/Clock/ClockAwareTrait.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Clock; + +use Psr\Clock\ClockInterface; +use Symfony\Contracts\Service\Attribute\Required; + +/** + * A trait to help write time-sensitive classes. + * + * @author Nicolas Grekas + */ +trait ClockAwareTrait +{ + private readonly ClockInterface $clock; + + #[Required] + public function setClock(ClockInterface $clock): void + { + $this->clock = $clock; + } + + protected function now(): \DateTimeImmutable + { + return ($this->clock ??= new NativeClock())->now(); + } +} diff --git a/src/Symfony/Component/Clock/Tests/ClockAwareTraitTest.php b/src/Symfony/Component/Clock/Tests/ClockAwareTraitTest.php new file mode 100644 index 000000000000..c472541c6493 --- /dev/null +++ b/src/Symfony/Component/Clock/Tests/ClockAwareTraitTest.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Clock\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Clock\ClockAwareTrait; +use Symfony\Component\Clock\MockClock; + +class ClockAwareTraitTest extends TestCase +{ + public function testTrait() + { + $sut = new class() { + use ClockAwareTrait { + now as public; + } + }; + + $this->assertInstanceOf(\DateTimeImmutable::class, $sut->now()); + + $clock = new MockClock(); + $sut = new $sut(); + $sut->setClock($clock); + + $ts = $sut->now()->getTimestamp(); + $this->assertEquals($clock->now(), $sut->now()); + $clock->sleep(1); + $this->assertEquals($clock->now(), $sut->now()); + $this->assertSame(1.0, round($sut->now()->getTimestamp() - $ts, 1)); + } +}