Skip to content

Commit a99e29e

Browse files
committed
Util\Timing: class no longer needs to be "static"
Now the "total runtime" recording is started and displayed from within the same class (`Runner`), the `Timing` class no longer needs to be a static class. It also no longer needs protection against the timer not having been started (as it will now be auto-started via the constructor) or against the time being printed twice. The only method which will remain static is the `getHumanReadableDuration()`, which is basically a stand-alone method anyhow and keeping it static makes testing this more straight-forward. Includes simplifying the tests significantly.
1 parent 7a035c1 commit a99e29e

File tree

3 files changed

+31
-110
lines changed

3 files changed

+31
-110
lines changed

src/Runner.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public function runPHPCS()
6161
$this->registerOutOfMemoryShutdownMessage('phpcs');
6262

6363
try {
64-
Timing::startTiming();
64+
$timing = new Timing();
6565

6666
if (defined('PHP_CODESNIFFER_CBF') === false) {
6767
define('PHP_CODESNIFFER_CBF', false);
@@ -123,7 +123,7 @@ public function runPHPCS()
123123
$this->reporter->printReports();
124124

125125
if ($this->config->quiet === false) {
126-
Timing::printRunTime();
126+
$timing->printRunTime();
127127
}
128128
} catch (DeepExitException $e) {
129129
echo $e->getMessage();
@@ -158,7 +158,7 @@ public function runPHPCBF()
158158
}
159159

160160
try {
161-
Timing::startTiming();
161+
$timing = new Timing();
162162

163163
// Creating the Config object populates it with all required settings
164164
// based on the CLI arguments provided to the script and any config
@@ -209,7 +209,7 @@ public function runPHPCBF()
209209

210210
if ($this->config->quiet === false) {
211211
StatusWriter::print('');
212-
Timing::printRunTime();
212+
$timing->printRunTime();
213213
}
214214
} catch (DeepExitException $e) {
215215
echo $e->getMessage();

src/Util/Timing.php

Lines changed: 13 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
<?php
22
/**
3-
* Timing functions for the run.
3+
* Timing functions.
44
*
55
* @author Greg Sherwood <[email protected]>
6+
* @author Juliette Reinders Folmer <[email protected]>
67
* @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
8+
* @copyright 2025 PHPCSStandards and contributors
79
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
810
*/
911

1012
namespace PHP_CodeSniffer\Util;
1113

1214
use PHP_CodeSniffer\Util\Writers\StatusWriter;
1315

14-
class Timing
16+
final class Timing
1517
{
1618

1719
/**
@@ -33,42 +35,29 @@ class Timing
3335
*
3436
* @var float
3537
*/
36-
private static $startTime;
37-
38-
/**
39-
* Used to make sure we only print the run time once per run.
40-
*
41-
* @var boolean
42-
*/
43-
private static $printed = false;
38+
private $startTime;
4439

4540

4641
/**
4742
* Start recording time for the run.
4843
*
4944
* @return void
5045
*/
51-
public static function startTiming()
46+
public function __construct()
5247
{
48+
$this->startTime = microtime(true);
5349

54-
self::$startTime = microtime(true);
55-
56-
}//end startTiming()
50+
}//end __construct()
5751

5852

5953
/**
6054
* Get the duration of the run up to "now".
6155
*
6256
* @return float Duration in milliseconds.
6357
*/
64-
public static function getDuration()
58+
public function getDuration()
6559
{
66-
if (self::$startTime === null) {
67-
// Timing was never started.
68-
return 0;
69-
}
70-
71-
return ((microtime(true) - self::$startTime) * 1000);
60+
return ((microtime(true) - $this->startTime) * 1000);
7261

7362
}//end getDuration()
7463

@@ -104,31 +93,16 @@ public static function getHumanReadableDuration($duration)
10493
/**
10594
* Print information about the run.
10695
*
107-
* @param boolean $force If TRUE, prints the output even if it has
108-
* already been printed during the run.
109-
*
11096
* @return void
11197
*/
112-
public static function printRunTime($force=false)
98+
public function printRunTime()
11399
{
114-
if ($force === false && self::$printed === true) {
115-
// A double call.
116-
return;
117-
}
118-
119-
if (self::$startTime === null) {
120-
// Timing was never started.
121-
return;
122-
}
123-
124-
$duration = self::getDuration();
125-
$duration = self::getHumanReadableDuration($duration);
100+
$duration = $this->getDuration();
101+
$duration = $this->getHumanReadableDuration($duration);
126102

127103
$mem = round((memory_get_peak_usage(true) / (1024 * 1024)), 2).'MB';
128104
StatusWriter::write("Time: $duration; Memory: $mem");
129105

130-
self::$printed = true;
131-
132106
}//end printRunTime()
133107

134108

tests/Core/Util/Timing/TimingTest.php

Lines changed: 14 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,23 @@
1616
/**
1717
* Tests for the \PHP_CodeSniffer\Util\Timing class.
1818
*
19-
* {@internal These tests need to run in separate processes as the Timing class uses static properties
20-
* to keep track of the start time and whether or not the runtime has been printed and these
21-
* can't be unset/reset once set.}
22-
*
2319
* @covers \PHP_CodeSniffer\Util\Timing
24-
*
25-
* @runTestsInSeparateProcesses
26-
* @preserveGlobalState disabled
2720
*/
2821
final class TimingTest extends TestCase
2922
{
3023
use StatusWriterTestHelper;
3124

3225

33-
/**
34-
* Verify that getDuration() returns 0 when the timer wasn't started.
35-
*
36-
* @return void
37-
*/
38-
public function testGetDurationWithoutStartReturnsZero()
39-
{
40-
$this->assertSame(0, Timing::getDuration());
41-
42-
}//end testGetDurationWithoutStartReturnsZero()
43-
44-
4526
/**
4627
* Verify that getDuration() returns the time in milliseconds.
4728
*
4829
* @return void
4930
*/
5031
public function testGetDurationWithStartReturnsMilliseconds()
5132
{
52-
Timing::startTiming();
33+
$timing = new Timing();
5334
usleep(1500);
54-
$duration = Timing::getDuration();
35+
$duration = $timing->getDuration();
5536

5637
$this->assertIsFloat($duration);
5738
$this->assertGreaterThan(1, $duration);
@@ -61,77 +42,43 @@ public function testGetDurationWithStartReturnsMilliseconds()
6142

6243

6344
/**
64-
* Verify that printRunTime() doesn't print anything if the timer wasn't started.
65-
*
66-
* @return void
67-
*/
68-
public function testTimeIsNotPrintedIfTimerWasNeverStarted()
69-
{
70-
$this->expectNoStdoutOutput();
71-
72-
Timing::printRunTime();
73-
74-
$this->assertStderrOutputSameString('');
75-
76-
}//end testTimeIsNotPrintedIfTimerWasNeverStarted()
77-
78-
79-
/**
80-
* Verify that printRunTime() doesn't print anything if the timer wasn't started.
81-
*
82-
* @return void
83-
*/
84-
public function testTimeIsNotPrintedIfTimerWasNeverStartedEvenWhenForced()
85-
{
86-
$this->expectNoStdoutOutput();
87-
88-
Timing::printRunTime(true);
89-
90-
$this->assertStderrOutputSameString('');
91-
92-
}//end testTimeIsNotPrintedIfTimerWasNeverStartedEvenWhenForced()
93-
94-
95-
/**
96-
* Verify that printRunTime() when called multiple times only prints the runtime information once.
45+
* Verify that printRunTime() prints the runtime information.
9746
*
9847
* @return void
9948
*/
100-
public function testTimeIsPrintedOnlyOnce()
49+
public function testTimeIsPrinted()
10150
{
10251
$this->expectNoStdoutOutput();
10352

104-
Timing::startTiming();
53+
$timing = new Timing();
10554
usleep(2000);
106-
Timing::printRunTime();
107-
Timing::printRunTime();
108-
Timing::printRunTime();
55+
$timing->printRunTime();
10956

11057
$regex = '`^Time: [0-9]+ms; Memory: [0-9\.]+MB'.PHP_EOL.'$`';
11158
$this->assertStderrOutputMatchesRegex($regex);
11259

113-
}//end testTimeIsPrintedOnlyOnce()
60+
}//end testTimeIsPrinted()
11461

11562

11663
/**
117-
* Verify that printRunTime() when called multiple times prints the runtime information multiple times if forced.
64+
* Verify that printRunTime() when called multiple times prints the runtime information multiple times.
11865
*
11966
* @return void
12067
*/
121-
public function testTimeIsPrintedMultipleTimesOnlyIfForced()
68+
public function testTimeIsPrintedMultipleTimesWhenRequestedMultipleTimes()
12269
{
12370
$this->expectNoStdoutOutput();
12471

125-
Timing::startTiming();
72+
$timing = new Timing();
12673
usleep(2000);
127-
Timing::printRunTime(true);
128-
Timing::printRunTime(true);
129-
Timing::printRunTime(true);
74+
$timing->printRunTime(true);
75+
$timing->printRunTime(true);
76+
$timing->printRunTime(true);
13077

13178
$regex = '`^(Time: [0-9]+ms; Memory: [0-9\.]+MB'.PHP_EOL.'){3}$`';
13279
$this->assertStderrOutputMatchesRegex($regex);
13380

134-
}//end testTimeIsPrintedMultipleTimesOnlyIfForced()
81+
}//end testTimeIsPrintedMultipleTimesWhenRequestedMultipleTimes()
13582

13683

13784
}//end class

0 commit comments

Comments
 (0)