Skip to content

Commit

Permalink
Enhancement: Extract Duration
Browse files Browse the repository at this point in the history
  • Loading branch information
localheinz committed Nov 1, 2023
1 parent 61a4f7d commit b389732
Show file tree
Hide file tree
Showing 19 changed files with 474 additions and 59 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

For a full diff see [`2.3.2...main`][2.3.2...main].

### Changed

- Extracted `Duration` ([#351]), by [@localheinz]

### Fixed

- Marked `DefaultDurationFormatter` as internal ([#350]), by [@localheinz]
Expand Down Expand Up @@ -169,5 +173,6 @@ For a full diff see [`7afa59c...1.0.0`][7afa59c...1.0.0].
[#342]: https://github.com/ergebnis/phpunit-slow-test-detector/pull/342
[#343]: https://github.com/ergebnis/phpunit-slow-test-detector/pull/343
[#350]: https://github.com/ergebnis/phpunit-slow-test-detector/pull/350
[#351]: https://github.com/ergebnis/phpunit-slow-test-detector/pull/351

[@localheinz]: https://github.com/localheinz
2 changes: 1 addition & 1 deletion psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
</file>
<file src="test/Unit/MaximumDurationTest.php">
<PossiblyUnusedMethod>
<code>provideMillisecondsAndTelemetryDuration</code>
<code>provideMillisecondsAndDuration</code>
</PossiblyUnusedMethod>
</file>
</files>
6 changes: 3 additions & 3 deletions src/Comparator/DurationComparator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@

namespace Ergebnis\PHPUnit\SlowTestDetector\Comparator;

use PHPUnit\Event;
use Ergebnis\PHPUnit\SlowTestDetector\Duration;

/**
* @internal
*/
final class DurationComparator
{
public function compare(
Event\Telemetry\Duration $one,
Event\Telemetry\Duration $two,
Duration $one,
Duration $two,
): int {
if ($one->isLessThan($two)) {
return -1;
Expand Down
90 changes: 90 additions & 0 deletions src/Duration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2021-2023 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/phpunit-slow-test-detector
*/

namespace Ergebnis\PHPUnit\SlowTestDetector;

/**
* @internal
*/
final class Duration
{
private function __construct(
private readonly int $seconds,
private readonly int $nanoseconds,
) {
}

/**
* @throws Exception\InvalidNanoseconds
* @throws Exception\InvalidSeconds
*/
public static function fromSecondsAndNanoseconds(
int $seconds,
int $nanoseconds,
): self {
if (0 > $seconds) {
throw Exception\InvalidSeconds::notGreaterThanZero($seconds);
}

if (0 > $nanoseconds) {
throw Exception\InvalidNanoseconds::notGreaterThanZero($nanoseconds);
}

$maxNanoseconds = 999_999_999;

if ($nanoseconds > $maxNanoseconds) {
throw Exception\InvalidNanoseconds::notLessThanOrEqualTo999999999($nanoseconds);
}

return new self(
$seconds,
$nanoseconds,
);
}

public function seconds(): int
{
return $this->seconds;
}

public function nanoseconds(): int
{
return $this->nanoseconds;
}

public function isLessThan(self $other): bool
{
if ($this->seconds < $other->seconds) {
return true;
}

if ($this->seconds > $other->seconds) {
return false;
}

return $this->nanoseconds < $other->nanoseconds;
}

public function isGreaterThan(self $other): bool
{
if ($this->seconds > $other->seconds) {
return true;
}

if ($this->seconds < $other->seconds) {
return false;
}

return $this->nanoseconds > $other->nanoseconds;
}
}
36 changes: 36 additions & 0 deletions src/Exception/InvalidNanoseconds.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2021-2023 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/phpunit-slow-test-detector
*/

namespace Ergebnis\PHPUnit\SlowTestDetector\Exception;

/**
* @internal
*/
final class InvalidNanoseconds extends \InvalidArgumentException
{
public static function notGreaterThanZero(int $value): self
{
return new self(\sprintf(
'Value should be greater than 0, but %d is not.',
$value,
));
}

public static function notLessThanOrEqualTo999999999(int $value): self
{
return new self(\sprintf(
'Value should be less than or equal to 999999999, but %d is not.',
$value,
));
}
}
28 changes: 28 additions & 0 deletions src/Exception/InvalidSeconds.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2021-2023 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/phpunit-slow-test-detector
*/

namespace Ergebnis\PHPUnit\SlowTestDetector\Exception;

/**
* @internal
*/
final class InvalidSeconds extends \InvalidArgumentException
{
public static function notGreaterThanZero(int $value): self
{
return new self(\sprintf(
'Value should be greater than 0, but %d is not.',
$value,
));
}
}
4 changes: 2 additions & 2 deletions src/Formatter/DefaultDurationFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace Ergebnis\PHPUnit\SlowTestDetector\Formatter;

use PHPUnit\Event;
use Ergebnis\PHPUnit\SlowTestDetector\Duration;

/**
* @internal
Expand All @@ -23,7 +23,7 @@ final class DefaultDurationFormatter implements DurationFormatter
/**
* @see https://github.com/sebastianbergmann/php-timer/blob/6.0.0/src/Duration.php
*/
public function format(Event\Telemetry\Duration $duration): string
public function format(Duration $duration): string
{
$durationInMilliseconds = $duration->seconds() * 1000 + $duration->nanoseconds() / 1000000;

Expand Down
4 changes: 2 additions & 2 deletions src/Formatter/DurationFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@

namespace Ergebnis\PHPUnit\SlowTestDetector\Formatter;

use PHPUnit\Event;
use Ergebnis\PHPUnit\SlowTestDetector\Duration;

/**
* @internal
*/
interface DurationFormatter
{
public function format(Event\Telemetry\Duration $duration): string;
public function format(Duration $duration): string;
}
10 changes: 4 additions & 6 deletions src/MaximumDuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@

namespace Ergebnis\PHPUnit\SlowTestDetector;

use PHPUnit\Event;

/**
* @internal
*/
final class MaximumDuration
{
private function __construct(private readonly Event\Telemetry\Duration $duration)
private function __construct(private readonly Duration $duration)
{
}

Expand All @@ -33,7 +31,7 @@ public static function fromSeconds(int $seconds): self
throw Exception\InvalidMaximumDuration::notGreaterThanZero($seconds);
}

return new self(Event\Telemetry\Duration::fromSecondsAndNanoseconds(
return new self(Duration::fromSecondsAndNanoseconds(
$seconds,
0,
));
Expand All @@ -55,13 +53,13 @@ public static function fromMilliseconds(int $milliseconds): self

$nanoseconds = ($milliseconds - $seconds * 1_000) * 1_000_000;

return new self(Event\Telemetry\Duration::fromSecondsAndNanoseconds(
return new self(Duration::fromSecondsAndNanoseconds(
$seconds,
$nanoseconds,
));
}

public function toTelemetryDuration(): Event\Telemetry\Duration
public function toDuration(): Duration
{
return $this->duration;
}
Expand Down
6 changes: 3 additions & 3 deletions src/Reporter/DefaultReporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
namespace Ergebnis\PHPUnit\SlowTestDetector\Reporter;

use Ergebnis\PHPUnit\SlowTestDetector\Comparator;
use Ergebnis\PHPUnit\SlowTestDetector\Duration;
use Ergebnis\PHPUnit\SlowTestDetector\Formatter;
use Ergebnis\PHPUnit\SlowTestDetector\MaximumCount;
use Ergebnis\PHPUnit\SlowTestDetector\MaximumDuration;
use Ergebnis\PHPUnit\SlowTestDetector\SlowTest;
use PHPUnit\Event;

/**
* @internal
Expand Down Expand Up @@ -98,14 +98,14 @@ private function list(SlowTest ...$slowTests): string

$longestMaximumDuration = \array_reduce(
$slowTestsToReport,
static function (Event\Telemetry\Duration $maximumDuration, SlowTest $slowTest): Event\Telemetry\Duration {
static function (Duration $maximumDuration, SlowTest $slowTest): Duration {
if ($maximumDuration->isLessThan($slowTest->maximumDuration())) {
return $slowTest->maximumDuration();
}

return $maximumDuration;
},
$this->maximumDuration->toTelemetryDuration(),
$this->maximumDuration->toDuration(),
);

$durationFormatter = $this->durationFormatter;
Expand Down
12 changes: 6 additions & 6 deletions src/SlowTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ final class SlowTest
{
private function __construct(
private readonly Event\Code\Test $test,
private readonly Event\Telemetry\Duration $duration,
private readonly Event\Telemetry\Duration $maximumDuration,
private readonly Duration $duration,
private readonly Duration $maximumDuration,
) {
}

public static function fromTestDurationAndMaximumDuration(
Event\Code\Test $test,
Event\Telemetry\Duration $duration,
Event\Telemetry\Duration $maximumDuration,
Duration $duration,
Duration $maximumDuration,
): self {
return new self(
$test,
Expand All @@ -44,12 +44,12 @@ public function test(): Event\Code\Test
return $this->test;
}

public function duration(): Event\Telemetry\Duration
public function duration(): Duration
{
return $this->duration;
}

public function maximumDuration(): Event\Telemetry\Duration
public function maximumDuration(): Duration
{
return $this->maximumDuration;
}
Expand Down
7 changes: 4 additions & 3 deletions src/Subscriber/TestPassedSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace Ergebnis\PHPUnit\SlowTestDetector\Subscriber;

use Ergebnis\PHPUnit\SlowTestDetector\Collector;
use Ergebnis\PHPUnit\SlowTestDetector\Duration;
use Ergebnis\PHPUnit\SlowTestDetector\MaximumDuration;
use Ergebnis\PHPUnit\SlowTestDetector\SlowTest;
use Ergebnis\PHPUnit\SlowTestDetector\TimeKeeper;
Expand Down Expand Up @@ -54,7 +55,7 @@ public function notify(Event\Test\Passed $event): void
$this->collector->collect($slowTest);
}

private function resolveMaximumDuration(Event\Code\Test $test): Event\Telemetry\Duration
private function resolveMaximumDuration(Event\Code\Test $test): Duration
{
$annotations = [
'maximumDuration',
Expand Down Expand Up @@ -84,9 +85,9 @@ private function resolveMaximumDuration(Event\Code\Test $test): Event\Telemetry\
continue;
}

return MaximumDuration::fromMilliseconds((int) $maximumDuration)->toTelemetryDuration();
return MaximumDuration::fromMilliseconds((int) $maximumDuration)->toDuration();
}

return $this->maximumDuration->toTelemetryDuration();
return $this->maximumDuration->toDuration();
}
}
11 changes: 8 additions & 3 deletions src/TimeKeeper.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ public function start(
public function stop(
Event\Code\Test $test,
Event\Telemetry\HRTime $stoppedTime,
): Event\Telemetry\Duration {
): Duration {
$key = $test->id();

if (!\array_key_exists($key, $this->startedTimes)) {
return Event\Telemetry\Duration::fromSecondsAndNanoseconds(
return Duration::fromSecondsAndNanoseconds(

Check warning on line 44 in src/TimeKeeper.php

View check run for this annotation

Codecov / codecov/patch

src/TimeKeeper.php#L44

Added line #L44 was not covered by tests
0,
0,
);
Expand All @@ -51,6 +51,11 @@ public function stop(

unset($this->startedTimes[$key]);

return $stoppedTime->duration($startedTime);
$duration = $stoppedTime->duration($startedTime);

return Duration::fromSecondsAndNanoseconds(
$duration->seconds(),
$duration->nanoseconds(),
);
}
}
Loading

0 comments on commit b389732

Please sign in to comment.