1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Stopwatch\Tests;
13
14use PHPUnit\Framework\TestCase;
15use Symfony\Component\Stopwatch\StopwatchEvent;
16
17/**
18 * StopwatchEventTest.
19 *
20 * @author Fabien Potencier <fabien@symfony.com>
21 *
22 * @group time-sensitive
23 */
24class StopwatchEventTest extends TestCase
25{
26    const DELTA = 37;
27
28    public function testGetOrigin()
29    {
30        $event = new StopwatchEvent(12);
31        $this->assertEquals(12, $event->getOrigin());
32    }
33
34    public function testGetCategory()
35    {
36        $event = new StopwatchEvent(microtime(true) * 1000);
37        $this->assertEquals('default', $event->getCategory());
38
39        $event = new StopwatchEvent(microtime(true) * 1000, 'cat');
40        $this->assertEquals('cat', $event->getCategory());
41    }
42
43    public function testGetPeriods()
44    {
45        $event = new StopwatchEvent(microtime(true) * 1000);
46        $this->assertEquals([], $event->getPeriods());
47
48        $event = new StopwatchEvent(microtime(true) * 1000);
49        $event->start();
50        $event->stop();
51        $this->assertCount(1, $event->getPeriods());
52
53        $event = new StopwatchEvent(microtime(true) * 1000);
54        $event->start();
55        $event->stop();
56        $event->start();
57        $event->stop();
58        $this->assertCount(2, $event->getPeriods());
59    }
60
61    public function testLap()
62    {
63        $event = new StopwatchEvent(microtime(true) * 1000);
64        $event->start();
65        $event->lap();
66        $event->stop();
67        $this->assertCount(2, $event->getPeriods());
68    }
69
70    public function testDuration()
71    {
72        $event = new StopwatchEvent(microtime(true) * 1000);
73        $event->start();
74        usleep(200000);
75        $event->stop();
76        $this->assertEqualsWithDelta(200, $event->getDuration(), self::DELTA);
77
78        $event = new StopwatchEvent(microtime(true) * 1000);
79        $event->start();
80        usleep(100000);
81        $event->stop();
82        usleep(50000);
83        $event->start();
84        usleep(100000);
85        $event->stop();
86        $this->assertEqualsWithDelta(200, $event->getDuration(), self::DELTA);
87    }
88
89    public function testDurationBeforeStop()
90    {
91        $event = new StopwatchEvent(microtime(true) * 1000);
92        $event->start();
93        usleep(200000);
94        $this->assertEqualsWithDelta(200, $event->getDuration(), self::DELTA);
95
96        $event = new StopwatchEvent(microtime(true) * 1000);
97        $event->start();
98        usleep(100000);
99        $event->stop();
100        usleep(50000);
101        $event->start();
102        $this->assertEqualsWithDelta(100, $event->getDuration(), self::DELTA);
103        usleep(100000);
104        $this->assertEqualsWithDelta(200, $event->getDuration(), self::DELTA);
105    }
106
107    public function testDurationWithMultipleStarts()
108    {
109        $event = new StopwatchEvent(microtime(true) * 1000);
110        $event->start();
111        usleep(100000);
112        $event->start();
113        usleep(100000);
114        $this->assertEqualsWithDelta(300, $event->getDuration(), self::DELTA);
115        $event->stop();
116        $this->assertEqualsWithDelta(300, $event->getDuration(), self::DELTA);
117        usleep(100000);
118        $this->assertEqualsWithDelta(400, $event->getDuration(), self::DELTA);
119        $event->stop();
120        $this->assertEqualsWithDelta(400, $event->getDuration(), self::DELTA);
121    }
122
123    public function testStopWithoutStart()
124    {
125        $this->expectException('LogicException');
126        $event = new StopwatchEvent(microtime(true) * 1000);
127        $event->stop();
128    }
129
130    public function testIsStarted()
131    {
132        $event = new StopwatchEvent(microtime(true) * 1000);
133        $event->start();
134        $this->assertTrue($event->isStarted());
135    }
136
137    public function testIsNotStarted()
138    {
139        $event = new StopwatchEvent(microtime(true) * 1000);
140        $this->assertFalse($event->isStarted());
141    }
142
143    public function testEnsureStopped()
144    {
145        // this also test overlap between two periods
146        $event = new StopwatchEvent(microtime(true) * 1000);
147        $event->start();
148        usleep(100000);
149        $event->start();
150        usleep(100000);
151        $event->ensureStopped();
152        $this->assertEqualsWithDelta(300, $event->getDuration(), self::DELTA);
153    }
154
155    public function testStartTime()
156    {
157        $event = new StopwatchEvent(microtime(true) * 1000);
158        $this->assertLessThanOrEqual(0.5, $event->getStartTime());
159
160        $event = new StopwatchEvent(microtime(true) * 1000);
161        $event->start();
162        $event->stop();
163        $this->assertLessThanOrEqual(1, $event->getStartTime());
164
165        $event = new StopwatchEvent(microtime(true) * 1000);
166        $event->start();
167        usleep(100000);
168        $event->stop();
169        $this->assertEqualsWithDelta(0, $event->getStartTime(), self::DELTA);
170    }
171
172    public function testStartTimeWhenStartedLater()
173    {
174        $event = new StopwatchEvent(microtime(true) * 1000);
175        usleep(100000);
176        $this->assertLessThanOrEqual(0.5, $event->getStartTime());
177
178        $event = new StopwatchEvent(microtime(true) * 1000);
179        usleep(100000);
180        $event->start();
181        $event->stop();
182        $this->assertLessThanOrEqual(101, $event->getStartTime());
183
184        $event = new StopwatchEvent(microtime(true) * 1000);
185        usleep(100000);
186        $event->start();
187        usleep(100000);
188        $this->assertEqualsWithDelta(100, $event->getStartTime(), self::DELTA);
189        $event->stop();
190        $this->assertEqualsWithDelta(100, $event->getStartTime(), self::DELTA);
191    }
192
193    public function testInvalidOriginThrowsAnException()
194    {
195        $this->expectException('InvalidArgumentException');
196        new StopwatchEvent('abc');
197    }
198
199    public function testHumanRepresentation()
200    {
201        $event = new StopwatchEvent(microtime(true) * 1000);
202        $this->assertEquals('default: 0.00 MiB - 0 ms', (string) $event);
203        $event->start();
204        $event->stop();
205        $this->assertEquals(1, preg_match('/default: [0-9\.]+ MiB - [0-9]+ ms/', (string) $event));
206
207        $event = new StopwatchEvent(microtime(true) * 1000, 'foo');
208        $this->assertEquals('foo: 0.00 MiB - 0 ms', (string) $event);
209    }
210}
211