From 89aed743552c7ef82228b50cabebc2f356abe732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Apr 2025 11:08:01 +0200 Subject: [PATCH] Refactor RollingDateConverter to use ClockInterface Introduced ClockInterface for better time mocking and handling, replacing default instantiation with dependency injection. Adjusted RollingDate logic to accept nullable pivot dates and updated related tests for improved flexibility and accuracy. --- .../Service/RollingDate/RollingDate.php | 4 +- .../RollingDate/RollingDateConverter.php | 40 +++++++++++-------- .../RollingDate/RollingDateConverterTest.php | 27 +++++++++---- 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Service/RollingDate/RollingDate.php b/src/Bundle/ChillMainBundle/Service/RollingDate/RollingDate.php index e984cad31..876c9dea3 100644 --- a/src/Bundle/ChillMainBundle/Service/RollingDate/RollingDate.php +++ b/src/Bundle/ChillMainBundle/Service/RollingDate/RollingDate.php @@ -72,7 +72,7 @@ class RollingDate public function __construct( private readonly string $roll, private readonly ?\DateTimeImmutable $fixedDate = null, - private readonly \DateTimeImmutable $pivotDate = new \DateTimeImmutable('now'), + private readonly ?\DateTimeImmutable $pivotDate = null, ) {} public function getFixedDate(): ?\DateTimeImmutable @@ -80,7 +80,7 @@ class RollingDate return $this->fixedDate; } - public function getPivotDate(): \DateTimeImmutable + public function getPivotDate(): ?\DateTimeImmutable { return $this->pivotDate; } diff --git a/src/Bundle/ChillMainBundle/Service/RollingDate/RollingDateConverter.php b/src/Bundle/ChillMainBundle/Service/RollingDate/RollingDateConverter.php index f569ebf18..6283bc1d1 100644 --- a/src/Bundle/ChillMainBundle/Service/RollingDate/RollingDateConverter.php +++ b/src/Bundle/ChillMainBundle/Service/RollingDate/RollingDateConverter.php @@ -11,8 +11,16 @@ declare(strict_types=1); namespace Chill\MainBundle\Service\RollingDate; -class RollingDateConverter implements RollingDateConverterInterface +use Symfony\Component\Clock\ClockInterface; + +final readonly class RollingDateConverter implements RollingDateConverterInterface { + + function __construct(private readonly ClockInterface $clock) + { + + } + public function convert(?RollingDate $rollingDate): ?\DateTimeImmutable { if (null === $rollingDate) { @@ -21,43 +29,43 @@ class RollingDateConverter implements RollingDateConverterInterface switch ($rollingDate->getRoll()) { case RollingDate::T_MONTH_CURRENT_START: - return $this->toBeginOfMonth($rollingDate->getPivotDate()); + return $this->toBeginOfMonth($rollingDate->getPivotDate() ?? $this->clock->now()); case RollingDate::T_MONTH_NEXT_START: - return $this->toBeginOfMonth($rollingDate->getPivotDate()->add(new \DateInterval('P1M'))); + return $this->toBeginOfMonth(($rollingDate->getPivotDate() ?? $this->clock->now())->add(new \DateInterval('P1M'))); case RollingDate::T_MONTH_PREVIOUS_START: - return $this->toBeginOfMonth($rollingDate->getPivotDate()->sub(new \DateInterval('P1M'))); + return $this->toBeginOfMonth(($rollingDate->getPivotDate() ?? $this->clock->now())->sub(new \DateInterval('P1M'))); case RollingDate::T_QUARTER_CURRENT_START: - return $this->toBeginOfQuarter($rollingDate->getPivotDate()); + return $this->toBeginOfQuarter($rollingDate->getPivotDate()?? $this->clock->now()); case RollingDate::T_QUARTER_NEXT_START: - return $this->toBeginOfQuarter($rollingDate->getPivotDate()->add(new \DateInterval('P3M'))); + return $this->toBeginOfQuarter(($rollingDate->getPivotDate() ?? $this->clock->now())->add(new \DateInterval('P3M'))); case RollingDate::T_QUARTER_PREVIOUS_START: - return $this->toBeginOfQuarter($rollingDate->getPivotDate()->sub(new \DateInterval('P3M'))); + return $this->toBeginOfQuarter(($rollingDate->getPivotDate() ?? $this->clock->now())->sub(new \DateInterval('P3M'))); case RollingDate::T_WEEK_CURRENT_START: - return $this->toBeginOfWeek($rollingDate->getPivotDate()); + return $this->toBeginOfWeek($rollingDate->getPivotDate() ?? $this->clock->now()); case RollingDate::T_WEEK_NEXT_START: - return $this->toBeginOfWeek($rollingDate->getPivotDate()->add(new \DateInterval('P1W'))); + return $this->toBeginOfWeek(($rollingDate->getPivotDate() ?? $this->clock->now())->add(new \DateInterval('P1W'))); case RollingDate::T_WEEK_PREVIOUS_START: - return $this->toBeginOfWeek($rollingDate->getPivotDate()->sub(new \DateInterval('P1W'))); + return $this->toBeginOfWeek(($rollingDate->getPivotDate() ?? $this->clock->now())->sub(new \DateInterval('P1W'))); case RollingDate::T_YEAR_CURRENT_START: - return $this->toBeginOfYear($rollingDate->getPivotDate()); + return $this->toBeginOfYear($rollingDate->getPivotDate() ?? $this->clock->now()); case RollingDate::T_YEAR_PREVIOUS_START: - return $this->toBeginOfYear($rollingDate->getPivotDate()->sub(new \DateInterval('P1Y'))); + return $this->toBeginOfYear(($rollingDate->getPivotDate() ?? $this->clock->now())->sub(new \DateInterval('P1Y'))); case RollingDate::T_YEAR_NEXT_START: - return $this->toBeginOfYear($rollingDate->getPivotDate()->add(new \DateInterval('P1Y'))); + return $this->toBeginOfYear(($rollingDate->getPivotDate() ?? $this->clock->now())->add(new \DateInterval('P1Y'))); case RollingDate::T_TODAY: - return $rollingDate->getPivotDate(); + return $rollingDate->getPivotDate() ?? $this->clock->now(); case RollingDate::T_FIXED_DATE: if (null === $rollingDate->getFixedDate()) { @@ -75,7 +83,7 @@ class RollingDateConverter implements RollingDateConverterInterface { return \DateTimeImmutable::createFromFormat( 'Y-m-d His', - sprintf('%s-%s-01 000000', $date->format('Y'), $date->format('m')) + sprintf('%s-%s-01 000000', $date->format('Y'), $date->format('m')), ); } @@ -90,7 +98,7 @@ class RollingDateConverter implements RollingDateConverterInterface return \DateTimeImmutable::createFromFormat( 'Y-m-d His', - sprintf('%s-%s-01 000000', $date->format('Y'), $month) + sprintf('%s-%s-01 000000', $date->format('Y'), $month), ); } diff --git a/src/Bundle/ChillMainBundle/Tests/Services/RollingDate/RollingDateConverterTest.php b/src/Bundle/ChillMainBundle/Tests/Services/RollingDate/RollingDateConverterTest.php index 5b2dfb954..f28e0f3cd 100644 --- a/src/Bundle/ChillMainBundle/Tests/Services/RollingDate/RollingDateConverterTest.php +++ b/src/Bundle/ChillMainBundle/Tests/Services/RollingDate/RollingDateConverterTest.php @@ -14,6 +14,7 @@ namespace Services\RollingDate; use Chill\MainBundle\Service\RollingDate\RollingDate; use Chill\MainBundle\Service\RollingDate\RollingDateConverter; use PHPUnit\Framework\TestCase; +use Symfony\Component\Clock\MockClock; /** * @internal @@ -22,11 +23,9 @@ use PHPUnit\Framework\TestCase; */ final class RollingDateConverterTest extends TestCase { - private RollingDateConverter $converter; - - protected function setUp(): void + private function buildConverter(\DateTimeImmutable|string $pivot = 'now'): RollingDateConverter { - $this->converter = new RollingDateConverter(); + return new RollingDateConverter(new MockClock($pivot)); } public static function generateDataConversionDate(): iterable @@ -66,7 +65,7 @@ final class RollingDateConverterTest extends TestCase $this->assertEquals( '2022-01-01', - $this->converter->convert($rollingDate)->format('Y-m-d') + $this->buildConverter()->convert($rollingDate)->format('Y-m-d') ); } @@ -74,7 +73,7 @@ final class RollingDateConverterTest extends TestCase { $rollingDate = new RollingDate(RollingDate::T_YEAR_PREVIOUS_START); - $actual = $this->converter->convert($rollingDate); + $actual = $this->buildConverter()->convert($rollingDate); $this->assertEquals( (int) (new \DateTimeImmutable('now'))->format('Y') - 1, @@ -94,7 +93,21 @@ final class RollingDateConverterTest extends TestCase $this->assertEquals( \DateTime::createFromFormat($format, $expectedDateTime), - $this->converter->convert($rollingDate) + $this->buildConverter()->convert($rollingDate) + ); + } + + /** + * @dataProvider generateDataConversionDate + */ + public function testConvertOnClock(string $roll, string $expectedDateTime, string $format) + { + $pivot = \DateTimeImmutable::createFromFormat('Y-m-d His', '2022-11-07 000000'); + $rollingDate = new RollingDate($roll, null); + + $this->assertEquals( + \DateTime::createFromFormat($format, $expectedDateTime), + $this->buildConverter($pivot)->convert($rollingDate) ); } }