Skip to content

Commit 24529f6

Browse files
committed
feature symfony#16194 [PhpUnit] Mock clock on @group time-sensitive annotations (nicolas-grekas)
This PR was merged into the 2.8 branch. Discussion ---------- [PhpUnit] Mock clock on @group time-sensitive annotations | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - Instead of spreading the same clock mock code everywhere, let's create a test case that helps mocking the time related functions. Commits ------- 34a0846 [PhpUnit] Mock clock on @group time-sensitive annotations
2 parents 77f5141 + 34a0846 commit 24529f6

17 files changed

+165
-253
lines changed
+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\PhpUnit;
13+
14+
/**
15+
* @author Nicolas Grekas <[email protected]>
16+
*/
17+
class ClockMock
18+
{
19+
private static $now;
20+
21+
public static function withClockMock($enable = null)
22+
{
23+
if (null === $enable) {
24+
return null !== self::$now;
25+
}
26+
27+
self::$now = is_numeric($enable) ? (float) $enable : ($enable ? microtime(true) : null);
28+
}
29+
30+
public static function time()
31+
{
32+
if (null === self::$now) {
33+
return \time();
34+
}
35+
36+
return (int) self::$now;
37+
}
38+
39+
public static function sleep($s)
40+
{
41+
if (null === self::$now) {
42+
return \sleep($s);
43+
}
44+
45+
self::$now += (int) $s;
46+
47+
return 0;
48+
}
49+
50+
public static function usleep($us)
51+
{
52+
if (null === self::$now) {
53+
return \usleep($us);
54+
}
55+
56+
self::$now += $us / 1000000;
57+
}
58+
59+
public static function microtime($asFloat = false)
60+
{
61+
if (null === self::$now) {
62+
return \microtime($asFloat);
63+
}
64+
65+
if ($asFloat) {
66+
return self::$now;
67+
}
68+
69+
return sprintf("%0.6f %d\n", $now - (int) $now, (int) self::$now);
70+
}
71+
72+
public static function register($class)
73+
{
74+
$self = get_called_class();
75+
76+
$mockedNs = array(substr($class, 0, strrpos($class, '\\')));
77+
if (strpos($class, '\\Tests\\')) {
78+
$ns = str_replace('\\Tests\\', '\\', $class);
79+
$mockedNs[] = substr($ns, 0, strrpos($ns, '\\'));
80+
}
81+
foreach ($mockedNs as $ns) {
82+
if (function_exists($ns.'\time')) {
83+
continue;
84+
}
85+
eval(<<<EOPHP
86+
namespace $ns;
87+
88+
function time()
89+
{
90+
return \\$self::time();
91+
}
92+
93+
function microtime(\$asFloat = false)
94+
{
95+
return \\$self::microtime(\$asFloat);
96+
}
97+
98+
function sleep(\$s)
99+
{
100+
return \\$self::sleep(\$s);
101+
}
102+
103+
function usleep(\$us)
104+
{
105+
return \\$self::usleep(\$us);
106+
}
107+
108+
EOPHP
109+
);
110+
}
111+
}
112+
113+
}

src/Symfony/Bridge/PhpUnit/SymfonyTestsListener.php

+24
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class SymfonyTestsListener extends \PHPUnit_Framework_BaseTestListener
2424
private $skippedFile = false;
2525
private $wasSkipped = array();
2626
private $isSkipped = array();
27+
private $testsStack = array();
2728

2829
public function __destruct()
2930
{
@@ -82,4 +83,27 @@ public function addSkippedTest(\PHPUnit_Framework_Test $test, \Exception $e, $ti
8283
$this->isSkipped[$class][$method] = 1;
8384
}
8485
}
86+
87+
public function startTest(\PHPUnit_Framework_Test $test)
88+
{
89+
if ($test instanceof \PHPUnit_Framework_TestCase) {
90+
$groups = \PHPUnit_Util_Test::getGroups(get_class($test), $test->getName());
91+
92+
if (in_array('time-sensitive', $groups, true)) {
93+
ClockMock::register(get_class($test));
94+
ClockMock::withClockMock(true);
95+
}
96+
}
97+
}
98+
99+
public function endTest(\PHPUnit_Framework_Test $test, $time)
100+
{
101+
if ($test instanceof \PHPUnit_Framework_TestCase) {
102+
$groups = \PHPUnit_Util_Test::getGroups(get_class($test), $test->getName());
103+
104+
if (in_array('time-sensitive', $groups, true)) {
105+
ClockMock::withClockMock(false);
106+
}
107+
}
108+
}
85109
}

src/Symfony/Component/Console/Tests/ClockMock.php

-41
This file was deleted.

src/Symfony/Component/Console/Tests/Helper/LegacyProgressHelperTest.php

+1-13
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,13 @@
1313

1414
use Symfony\Component\Console\Helper\ProgressHelper;
1515
use Symfony\Component\Console\Output\StreamOutput;
16-
use Symfony\Component\Console\Tests;
17-
18-
require_once __DIR__.'/../ClockMock.php';
1916

2017
/**
2118
* @group legacy
19+
* @group time-sensitive
2220
*/
2321
class LegacyProgressHelperTest extends \PHPUnit_Framework_TestCase
2422
{
25-
protected function setUp()
26-
{
27-
Tests\with_clock_mock(true);
28-
}
29-
30-
protected function tearDown()
31-
{
32-
Tests\with_clock_mock(false);
33-
}
34-
3523
public function testAdvance()
3624
{
3725
$progress = new ProgressHelper();

src/Symfony/Component/Console/Tests/Helper/ProgressBarTest.php

+3-13
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,12 @@
1414
use Symfony\Component\Console\Helper\ProgressBar;
1515
use Symfony\Component\Console\Helper\Helper;
1616
use Symfony\Component\Console\Output\StreamOutput;
17-
use Symfony\Component\Console\Tests;
18-
19-
require_once __DIR__.'/../ClockMock.php';
2017

18+
/**
19+
* @group time-sensitive
20+
*/
2121
class ProgressBarTest extends \PHPUnit_Framework_TestCase
2222
{
23-
protected function setUp()
24-
{
25-
Tests\with_clock_mock(true);
26-
}
27-
28-
protected function tearDown()
29-
{
30-
Tests\with_clock_mock(false);
31-
}
32-
3323
public function testMultipleStart()
3424
{
3525
$bar = new ProgressBar($output = $this->getOutputStream());

src/Symfony/Component/HttpFoundation/Tests/ClockMockTestCase.php

-88
This file was deleted.

src/Symfony/Component/HttpFoundation/Tests/CookieTest.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
*
1919
* @author John Kary <[email protected]>
2020
* @author Hugo Hamon <[email protected]>
21+
*
22+
* @group time-sensitive
2123
*/
22-
class CookieTest extends ClockMockTestCase
24+
class CookieTest extends \PHPUnit_Framework_TestCase
2325
{
2426
public function invalidNames()
2527
{

src/Symfony/Component/HttpFoundation/Tests/ResponseHeaderBagTest.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
1515
use Symfony\Component\HttpFoundation\Cookie;
1616

17-
class ResponseHeaderBagTest extends ClockMockTestCase
17+
/**
18+
* @group time-sensitive
19+
*/
20+
class ResponseHeaderBagTest extends \PHPUnit_Framework_TestCase
1821
{
1922
/**
2023
* @covers Symfony\Component\HttpFoundation\ResponseHeaderBag::allPreserveCase

src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/LegacyPdoSessionHandlerTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@
1212
namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
1313

1414
use Symfony\Component\HttpFoundation\Session\Storage\Handler\LegacyPdoSessionHandler;
15-
use Symfony\Component\HttpFoundation\Tests\ClockMockTestCase;
1615

1716
/**
1817
* @group legacy
1918
* @requires extension pdo_sqlite
19+
* @group time-sensitive
2020
*/
21-
class LegacyPdoSessionHandlerTest extends ClockMockTestCase
21+
class LegacyPdoSessionHandlerTest extends \PHPUnit_Framework_TestCase
2222
{
2323
private $pdo;
2424

src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/MemcacheSessionHandlerTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
1313

1414
use Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcacheSessionHandler;
15-
use Symfony\Component\HttpFoundation\Tests\ClockMockTestCase;
1615

1716
/**
1817
* @requires extension memcache
18+
* @group time-sensitive
1919
*/
20-
class MemcacheSessionHandlerTest extends ClockMockTestCase
20+
class MemcacheSessionHandlerTest extends \PHPUnit_Framework_TestCase
2121
{
2222
const PREFIX = 'prefix_';
2323
const TTL = 1000;

0 commit comments

Comments
 (0)