Skip to content

Commit

Permalink
Add clock test trait (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
frankdekker authored Jan 2, 2025
1 parent 7e789fd commit 555662a
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 0 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,17 @@ This trait includes methods for verifying the status code, response message cont
- `assertResponseIsClientError`
- `assertResponseIsServerError`

### ClockTestTrait
The ClockTestTrait provides a set of methods to manipulate the current time in tests. This trait will automatically freeze the time at the start of
each test. The trait also provides methods to get the current time as timestamp or `DateTimeImmutable` object,

**Methods**
- `self::time(): int`
- `self::now(): DateTimeImmutable`
- `self::sleep(int|float $seconds): void`
- `self::assertNow()`
- `self::assertSameTime()`

## About us

At 123inkt (Part of Digital Revolution B.V.), every day more than 50 development professionals are working on improving our internal ERP
Expand Down
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"phpstan/phpstan-symfony": "^2.0",
"roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.7",
"symfony/clock": "^6.4||^7.0",
"symfony/form": "^6.0||^7.0",
"symfony/framework-bundle": "^6.0||^7.0",
"symfony/security-core": "^6.0||^7.0",
Expand All @@ -46,6 +47,7 @@
"test:integration": "phpunit --testsuite integration"
},
"suggest": {
"symfony/clock": "Symfony clock component is required when using the ClockTestTrait",
"symfony/form": "Symfony form component is required for testing the controller createForm methods",
"symfony/framework-bundle": "Symfony framework bundle is required for the AbstractControllerTestCase",
"symfony/security-core": "Symfony security component is required for testing authentication/authorization related methods",
Expand Down
80 changes: 80 additions & 0 deletions src/Symfony/ClockTestTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);

namespace DR\PHPUnitExtensions\Symfony;

use DateTimeImmutable;
use DateTimeInterface;
use PHPUnit\Framework\Attributes\Before;
use Symfony\Component\Clock\Clock;
use Symfony\Component\Clock\Test\ClockSensitiveTrait;

trait ClockTestTrait
{
use ClockSensitiveTrait;

/**
* @before
*/
#[Before]
protected function freezeTime(): void
{
self::mockTime((new DateTimeImmutable())->setTimestamp($this->freezeTimeAt()));
}

/**
* Override this method to set your own custom time freeze.
*/
protected function freezeTimeAt(): int
{
return 1634050575; // tuesday, 12-10-2021 16:56:15 +02:00
}

/**
* Returns the currently mocked time as timestamp
*/
protected static function time(): int
{
return Clock::get()->now()->getTimestamp();
}

/**
* Returns the currently mocked time as DateTimeImmutable object
*/
protected static function now(): DateTimeImmutable
{
return Clock::get()->now();
}

/**
* Sleep for a given amount of seconds. Use a float to sleep fractions of a second.
*/
protected static function sleep(int|float $seconds): void
{
Clock::get()->sleep($seconds);
}

/**
* Asserts that the give timestamp of DateTime is equal to now
*/
protected static function assertNow(int|DateTimeInterface $actual, string $message = ''): void
{
self::assertSameTime(self::now(), $actual, $message);
}

/**
* Asserts that two timestamps (or timestamp of DateTime) are equal.
*/
protected static function assertSameTime(int|DateTimeInterface $expected, int|DateTimeInterface $actual, string $message = ''): void
{
if ($expected instanceof DateTimeInterface) {
$expected = $expected->getTimestamp();
}
if ($actual instanceof DateTimeInterface) {
$actual = $actual->getTimestamp();
}

self::assertSame($expected, $actual, $message);
}
}
43 changes: 43 additions & 0 deletions tests/Unit/Symfony/ClockTestTraitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace DR\PHPUnitExtensions\Tests\Unit\Symfony;

use DateTimeImmutable;
use DR\PHPUnitExtensions\Symfony\ClockTestTrait;
use PHPUnit\Framework\TestCase;

/**
* @covers \DR\PHPUnitExtensions\Symfony\ClockTestTrait
*/
class ClockTestTraitTest extends TestCase
{
use ClockTestTrait;

public function testTime(): void
{
self::assertSame(1634050575, self::time());
}

public function testNow(): void
{
self::assertSame(1634050575, self::now()->getTimestamp());
}

public function testSleep(): void
{
self::sleep(123.456);
self::assertSame(1634050698, self::time());
}

public function testAssertNow(): void
{
self::assertNow((new DateTimeImmutable())->setTimestamp(1634050575));
}

public function testAssertTime(): void
{
self::assertSameTime(1634050575, self::now());
}
}

0 comments on commit 555662a

Please sign in to comment.