Skip to content

Commit

Permalink
Merge pull request #18 from Jeckel-Lab/feature/codeception-helper
Browse files Browse the repository at this point in the history
Update test and documentation
  • Loading branch information
jeckel authored Mar 26, 2021
2 parents 5903a87 + 6969073 commit 3307314
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 8 deletions.
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,50 @@ parameters:
mode: frozen
fake_time_path: '%kernel.project_dir%/var/fake_time.txt'
```

## Test with Codeception

To be able to change current date in your Codeception tests, you first need to configure your fake clock to use the `fake_time_path` file as a time source.

Next, configure codeception with the provided helper:

```yaml
# codeception.yaml
# ...
modules:
config:
\JeckelLab\Clock\CodeceptionHelper\Clock:
fake_time_path: 'var/test/fake_clock' # Required: path where the fake time should be provided to your project
date_format: 'Y/m/d' # Optional, date format for date value defined in your tests (default: Y/m/d)
time_format: 'H:i:s' # Optional, time format for time value defined in your tests (default: H:i:s)
```

Enable the helper in your suite:
```yaml
# acceptance.suite.yml
actor: AcceptanceTester
modules:
enabled:
- \JeckelLab\Clock\CodeceptionHelper\Clock
```

Now you can set the fake time in your tests:

**in BDD:**
```gherkin
Feature: A feature description
Scenario: A scenario description
Given current date is "2021/03/26" and time is "08:35:00"
```

**in other tests:**
```php
/** @var \Codeception\Actor $i */
$I->haveCurrentDateAndTime('2021/03/26', '08:35:00');
// or
$I->haveCurrentDateTime(DateTime::createFromFormat("Y/m/d H:i", "2021/03/26 08:35"));
```
52 changes: 44 additions & 8 deletions src/CodeceptionHelper/Clock.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@

use Codeception\Configuration;
use Codeception\Module;
use Codeception\TestInterface;
use DateTimeImmutable;
use DateTimeInterface;
use InvalidArgumentException;
use RuntimeException;

/**
Expand All @@ -19,25 +23,57 @@
*/
class Clock extends Module
{
/**
* @var string[]
*/
protected $config = [
'date_format' => 'Y/m/d',
'time_format' => 'H:i:s'
];

/**
* @var array
*/
protected $requiredFields = ['fake_time_path'];
protected $requiredFields = ['fake_time_path', 'date_format', 'time_format'];

// @codingStandardsIgnoreStart
/**
* HOOK: before test
* @param TestInterface $test
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function _before(TestInterface $test): void
{
$this->haveCurrentDateTime(new DateTimeImmutable());
}
// @codingStandardsIgnoreEnd

/**
* @Given current date is :currentDate and time is :currentTime
* @param string $date
* @param string $time
*/
public function haveCurrentDateAndTime(string $date, string $time): void
{
$format = sprintf('%s %s', $this->config['date_format'], $this->config['time_format']);
$currentDate = DateTimeImmutable::createFromFormat($format, sprintf('%s %s', $date, $time));
if (false === $currentDate) {
throw new InvalidArgumentException('Invalid date / time format');
}
$this->haveCurrentDateTime($currentDate);
}

/**
* Expected format 'Y-m-d H:i:s'
* @Given current date and time is :currentDate
* @param string $currentDate
* @param DateTimeInterface $dateTime
*/
public function currentDateAndTimeIs(string $currentDate): void
public function haveCurrentDateTime(DateTimeInterface $dateTime): void
{
/** @psalm-suppress MixedArrayAccess */
$fullPath = Configuration::projectDir() . ((string) $this->config['fake_time_path']);
$fullPath = Configuration::projectDir() . $this->config['fake_time_path'];

$dir = dirname($fullPath);
if (!is_dir($dir) && !mkdir($dir) && !is_dir($dir)) {
throw new RuntimeException(sprintf('Directory "%s" was not created', $dir));
}
file_put_contents($fullPath, $currentDate);
file_put_contents($fullPath, $dateTime->format('Y-m-d H:i:s'));
}
}

0 comments on commit 3307314

Please sign in to comment.