Skip to content

Commit

Permalink
Merge pull request #10 from bailey-spencer/feature_mktime
Browse files Browse the repository at this point in the history
  • Loading branch information
asprega committed May 27, 2022
2 parents ac49696 + d809097 commit 233b19f
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 2 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ Note that, as this is not a tool intended for production, it should be required
- getdate()
- gettimeofday()
- gmdate()
- gmmktime()
- gmstrftime()
- idate()
- localtime()
- microtime()
- mktime()
- strftime()
- strtotime()
- time()
Expand All @@ -53,8 +55,6 @@ Note that, as this is not a tool intended for production, it should be required

- date_create_from_format()
- date_create_immutable_from_format()
- gmmktime()
- mktime()
- DateTime::createFromFormat
- DateTimeImmutable::createFromFormat
- $_SERVER['REQUEST_TIME']
Expand Down
41 changes: 41 additions & 0 deletions src/ClockMock.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,12 @@ public static function reset(): void
uopz_unset_return('getdate');
uopz_unset_return('gettimeofday');
uopz_unset_return('gmdate');
uopz_unset_return('gmmktime');
uopz_unset_return('gmstrftime');
uopz_unset_return('idate');
uopz_unset_return('localtime');
uopz_unset_return('microtime');
uopz_unset_return('mktime');
uopz_unset_return('strftime');
uopz_unset_return('strtotime');
uopz_unset_return('time');
Expand Down Expand Up @@ -87,10 +89,12 @@ private static function activateMocksIfNeeded(): void
uopz_set_return('getdate', self::mock_getdate(), true);
uopz_set_return('gettimeofday', self::mock_gettimeofday(), true);
uopz_set_return('gmdate', self::mock_gmdate(), true);
uopz_set_return('gmmktime', self::mock_gmmktime(), true);
uopz_set_return('gmstrftime', self::mock_gmstrftime(), true);
uopz_set_return('idate', self::mock_idate(), true);
uopz_set_return('localtime', self::mock_localtime(), true);
uopz_set_return('microtime', self::mock_microtime(), true);
uopz_set_return('mktime', self::mock_mktime(), true);
uopz_set_return('strftime', self::mock_strftime(), true);
uopz_set_return('strtotime', self::mock_strtotime(), true);
uopz_set_return('time', self::mock_time(), true);
Expand Down Expand Up @@ -190,6 +194,26 @@ private static function mock_gmstrftime(): callable
return fn (string $format, ?int $timestamp = null) => $gmstrftime_mock($format, $timestamp);
}

/**
* @see https://www.php.net/manual/en/function.gmmktime.php
*/
private static function mock_gmmktime(): callable
{
$gmmktime_mock = function (int $hour, ?int $minute, ?int $second, ?int $month, ?int $day, ?int $year) {
/** @var \DateTime $gmtDateTime */
$gmtDateTime = self::mock_date_create()(self::mock_gmdate()('Y-m-d H:i:s.u'));

return self::mock_mktime()($hour + self::$frozenDateTime->getOffset() / 3600,
$minute ?? (int) $gmtDateTime->format('i'),
$second ?? (int) $gmtDateTime->format('s'),
$month ?? (int) $gmtDateTime->format('m'),
$day ?? (int) $gmtDateTime->format('j'),
$year ?? (int) $gmtDateTime->format('Y'));
};

return fn (int $hour, ?int $minute = null, ?int $second = null, ?int $month = null, ?int $day = null, ?int $year = null) => $gmmktime_mock($hour, $minute, $second, $month, $day, $year);
}

/**
* @see https://www.php.net/manual/en/function.idate.php
*/
Expand Down Expand Up @@ -242,6 +266,23 @@ private static function mock_strftime(): callable
return fn (string $format, ?int $timestamp = null) => $strftime_mock($format, $timestamp);
}

/**
* @see https://www.php.net/manual/en/function.mktime.php
*/
private static function mock_mktime(): callable
{
$mktime_mock = function (int $hour, ?int $minute, ?int $second, ?int $month, ?int $day, ?int $year) {
return mktime($hour,
$minute ?? (int) self::$frozenDateTime->format('i'),
$second ?? (int) self::$frozenDateTime->format('s'),
$month ?? (int) self::$frozenDateTime->format('m'),
$day ?? (int) self::$frozenDateTime->format('j'),
$year ?? (int) self::$frozenDateTime->format('Y'));
};

return fn (int $hour, ?int $minute = null, ?int $second = null, ?int $month = null, ?int $day = null, ?int $year = null) => $mktime_mock($hour, $minute, $second, $month, $day, $year);
}

/**
* @see https://www.php.net/manual/en/function.strtotime.php
*/
Expand Down
105 changes: 105 additions & 0 deletions tests/ClockMockTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,60 @@ public function test_gmstrftime()
$this->assertEquals('2022-04-04 11:26:29', gmstrftime('%F %T'));
}

public function dateProvider_gmmktime(): array
{
// NOTE: for all datasets, hour in freezeDateTime is completely irrelevant because always overridden by $hour
// parameter provided to gmmktime. Also, in expectedDateTime hour is always "13" because hour 10 in GMT
// corresponds to hour 13 when we are in +03:00 offset.
return [
[
'2022-04-04T05:26:29+03:00',
[10],
'2022-04-04T13:26:29+00:00'
],
[
'2022-04-04T05:26:29+03:00',
[10, 10],
'2022-04-04T13:10:29+00:00'
],
[
'2022-04-04T05:26:29+03:00',
[10, null, 10],
'2022-04-04T13:26:10+00:00'
],
[
'2022-04-04T05:26:29+03:00',
[10, null, null, 10],
'2022-10-04T13:26:29+00:00'
],
[
'2022-04-04T05:26:29+03:00',
[10, null, null, null, 10],
'2022-04-10T13:26:29+00:00'
],
[
'2022-04-04T05:26:29+03:00',
[10, null, null, null, null, 10],
'2010-04-04T13:26:29+00:00'
],
[
'2022-04-04T05:26:29+03:00',
[10, 10, 10, 10, 10, 10],
'2010-10-10T13:10:10+00:00'
],
];
}

/**
* @dataProvider dateProvider_gmmktime
*/
public function test_gmmktime(string $freezeDateTime, array $mktimeArgs, string $expectedDateTime)
{
ClockMock::freeze(new \DateTime($freezeDateTime));

$this->assertEquals($expectedDateTime, date(DATE_ATOM, gmmktime(...$mktimeArgs)));
}

public function test_idate()
{
ClockMock::freeze(new \DateTime('1986-06-05'));
Expand Down Expand Up @@ -225,6 +279,57 @@ public function test_strftime()
$this->assertEquals('2022-04-04 14:26:29', strftime('%F %T'));
}

public function dateProvider_mktime(): array
{
return [
[
'2022-04-04T14:26:29+00:00',
[10],
'2022-04-04T10:26:29+00:00'
],
[
'2022-04-04T14:26:29+00:00',
[10, 10],
'2022-04-04T10:10:29+00:00'
],
[
'2022-04-04T14:26:29+00:00',
[10, null, 10],
'2022-04-04T10:26:10+00:00'
],
[
'2022-04-04T14:26:29+00:00',
[10, null, null, 10],
'2022-10-04T10:26:29+00:00'
],
[
'2022-04-04T14:26:29+00:00',
[10, null, null, null, 10],
'2022-04-10T10:26:29+00:00'
],
[
'2022-04-04T14:26:29+00:00',
[10, null, null, null, null, 10],
'2010-04-04T10:26:29+00:00'
],
[
'2022-04-04T14:26:29+00:00',
[10, 10, 10, 10, 10, 10],
'2010-10-10T10:10:10+00:00'
],
];
}

/**
* @dataProvider dateProvider_mktime
*/
public function test_mktime(string $freezeDateTime, array $mktimeArgs, string $expectedDateTime)
{
ClockMock::freeze(new \DateTime($freezeDateTime));

$this->assertEquals($expectedDateTime, date(DATE_ATOM, mktime(...$mktimeArgs)));
}

public function test_strtotime()
{
ClockMock::freeze($fakeNow = new \DateTimeImmutable('1986-06-05'));
Expand Down

0 comments on commit 233b19f

Please sign in to comment.