Skip to content

Commit c75d0bf

Browse files
Add Timer class and tests
1 parent c6432d5 commit c75d0bf

2 files changed

Lines changed: 138 additions & 0 deletions

File tree

src/Runner/Timer.php

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
/**
4+
* This file is part of CaptainHook.
5+
*
6+
* (c) Sebastian Feldmann <sf@sebastian-feldmann.info>
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 CaptainHook\App\Runner;
13+
14+
use RuntimeException;
15+
16+
/**
17+
* Timer
18+
*
19+
* Measures hook and action execution times.
20+
*
21+
* @package CaptainHook
22+
* @author Sebastian Feldmann <sf@sebastian-feldmann.info>
23+
* @link https://github.com/captainhook-git/captainhook
24+
* @since Class available since Release 5.28.0
25+
*/
26+
class Timer
27+
{
28+
private float $start = 0.0;
29+
private float $stop = 0.0;
30+
31+
/**
32+
* Start the timer
33+
*
34+
* @return float
35+
*/
36+
public function start(): float
37+
{
38+
$this->start = microtime(true);
39+
return $this->start;
40+
}
41+
42+
/**
43+
* Stop the timer and calculate the elapsed time.
44+
*
45+
* @return float The time elapsed in seconds.
46+
*/
47+
public function stop(): float
48+
{
49+
if ($this->start === 0.0) {
50+
throw new RuntimeException('Timer not started');
51+
}
52+
$this->stop = microtime(true);
53+
return $this->stop - $this->start;
54+
}
55+
56+
/**
57+
* Determine if the timer is currently running
58+
*
59+
* @return bool
60+
*/
61+
public function isRunning(): bool
62+
{
63+
return $this->start > 0.0 && $this->stop === 0.0;
64+
}
65+
66+
/**
67+
* Creates a new timer, starts the timer, and returns the instance.
68+
*
69+
* @return \CaptainHook\App\Runner\Timer.
70+
*/
71+
public static function createAndStart(): self
72+
{
73+
$timer = new self();
74+
$timer->start();
75+
return $timer;
76+
}
77+
}

tests/unit/Runner/TimerTest.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
/**
4+
* This file is part of CaptainHook.
5+
*
6+
* (c) Sebastian Feldmann <sf@sebastian-feldmann.info>
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 CaptainHook\App\Runner;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use RuntimeException;
16+
17+
class TimerTest extends TestCase
18+
{
19+
public function testStartReturnsTheStartTime(): void
20+
{
21+
$timer = new Timer();
22+
23+
$start = $timer->start();
24+
25+
$this->assertIsFloat($start);
26+
$this->assertGreaterThan(0.0, $start);
27+
}
28+
29+
public function testNotStartedTimerCanNotBeStopped(): void
30+
{
31+
$this->expectException(RuntimeException::class);
32+
$timer = new Timer();
33+
$timer->stop();
34+
}
35+
36+
public function testTimerStatusCanBeChecked(): void
37+
{
38+
$timer = new Timer();
39+
$this->assertFalse($timer->isRunning());
40+
41+
$timer->start();
42+
$this->assertTrue($timer->isRunning());
43+
44+
$timer->stop();
45+
$this->assertFalse($timer->isRunning());
46+
}
47+
48+
public function testStopReturnsElapsedSeconds(): void
49+
{
50+
$timer = new Timer();
51+
52+
$timer->start();
53+
usleep(10_000); // 10ms to avoid flaky zero durations on fast machines
54+
55+
$elapsed = $timer->stop();
56+
57+
$this->assertIsFloat($elapsed);
58+
$this->assertGreaterThan(0.0, $elapsed);
59+
$this->assertLessThan(1.0, $elapsed, 'Timer should not take this long in a unit test');
60+
}
61+
}

0 commit comments

Comments
 (0)