Skip to content

Commit

Permalink
Enhancement: Extract TestDuration and MaximumDuration
Browse files Browse the repository at this point in the history
  • Loading branch information
localheinz committed Feb 22, 2025
1 parent d874fcb commit 3b14ae8
Show file tree
Hide file tree
Showing 13 changed files with 330 additions and 133 deletions.
15 changes: 15 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,16 @@ parameters:
count: 1
path: test/Unit/Formatter/DefaultDurationFormatterTest.php

-
message: "#^Method Ergebnis\\\\PHPUnit\\\\SlowTestDetector\\\\Test\\\\Unit\\\\MaximumDurationTest\\:\\:testDefaultReturnsMaximumDuration\\(\\) has no return type specified\\.$#"
count: 1
path: test/Unit/MaximumDurationTest.php

-
message: "#^Method Ergebnis\\\\PHPUnit\\\\SlowTestDetector\\\\Test\\\\Unit\\\\MaximumDurationTest\\:\\:testFromDurationReturnsMaximumDuration\\(\\) has no return type specified\\.$#"
count: 1
path: test/Unit/MaximumDurationTest.php

-
message: "#^Method Ergebnis\\\\PHPUnit\\\\SlowTestDetector\\\\Test\\\\Unit\\\\PhaseIdentifierTest\\:\\:testFromStringRejectsInvalidValue\\(\\) has no return type specified\\.$#"
count: 1
Expand Down Expand Up @@ -310,6 +320,11 @@ parameters:
count: 1
path: test/Unit/TestDescriptionTest.php

-
message: "#^Method Ergebnis\\\\PHPUnit\\\\SlowTestDetector\\\\Test\\\\Unit\\\\TestDurationTest\\:\\:testFromDurationReturnsTestDuration\\(\\) has no return type specified\\.$#"
count: 1
path: test/Unit/TestDurationTest.php

-
message: "#^Method Ergebnis\\\\PHPUnit\\\\SlowTestDetector\\\\Test\\\\Unit\\\\TestIdentifierTest\\:\\:testFromStringRejectsInvalidValue\\(\\) has no return type specified\\.$#"
count: 1
Expand Down
2 changes: 1 addition & 1 deletion src/Collector/DefaultCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function collectSlowTest(SlowTest $slowTest)
if (\array_key_exists($key, $this->slowTests)) {
$previousSlowTest = $this->slowTests[$key];

if (!$slowTest->duration()->isGreaterThan($previousSlowTest->duration())) {
if (!$slowTest->testDuration()->toDuration()->isGreaterThan($previousSlowTest->testDuration()->toDuration())) {
return;
}

Expand Down
38 changes: 19 additions & 19 deletions src/Extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ final class Extension implements Framework\TestListener
private $suites = 0;

/**
* @var Duration
* @var MaximumDuration
*/
private $maximumDuration;

Expand All @@ -59,10 +59,10 @@ public function __construct(array $options = [])
$maximumCount = Count::fromInt((int) $options['maximum-count']);
}

$maximumDuration = Duration::fromMilliseconds(500);
$maximumDuration = MaximumDuration::default();

Check warning on line 62 in src/Extension.php

View check run for this annotation

Codecov / codecov/patch

src/Extension.php#L62

Added line #L62 was not covered by tests

if (\array_key_exists('maximum-duration', $options)) {
$maximumDuration = Duration::fromMilliseconds((int) $options['maximum-duration']);
$maximumDuration = MaximumDuration::fromDuration(Duration::fromMilliseconds((int) $options['maximum-duration']));

Check warning on line 65 in src/Extension.php

View check run for this annotation

Codecov / codecov/patch

src/Extension.php#L65

Added line #L65 was not covered by tests
}

$this->maximumDuration = $maximumDuration;
Expand Down Expand Up @@ -159,14 +159,14 @@ public function endTest(
$seconds = (int) \floor($time);
$nanoseconds = (int) (($time - $seconds) * 1000000000);

$duration = Duration::fromSecondsAndNanoseconds(
$testDuration = TestDuration::fromDuration(Duration::fromSecondsAndNanoseconds(

Check warning on line 162 in src/Extension.php

View check run for this annotation

Codecov / codecov/patch

src/Extension.php#L162

Added line #L162 was not covered by tests
$seconds,
$nanoseconds
);
));

Check warning on line 165 in src/Extension.php

View check run for this annotation

Codecov / codecov/patch

src/Extension.php#L165

Added line #L165 was not covered by tests

$maximumDuration = $this->resolveMaximumDuration($test);

if (!$duration->isGreaterThan($maximumDuration)) {
if (!$testDuration->toDuration()->isGreaterThan($maximumDuration->toDuration())) {

Check warning on line 169 in src/Extension.php

View check run for this annotation

Codecov / codecov/patch

src/Extension.php#L169

Added line #L169 was not covered by tests
return;
}

Expand All @@ -181,14 +181,14 @@ public function endTest(
\get_class($test),
$test->getName()
)),
$duration,
$testDuration,

Check warning on line 184 in src/Extension.php

View check run for this annotation

Codecov / codecov/patch

src/Extension.php#L184

Added line #L184 was not covered by tests
$maximumDuration
);

$this->collector->collectSlowTest($slowTest);
}

private function resolveMaximumDuration(Framework\Test $test): Duration
private function resolveMaximumDuration(Framework\Test $test): MaximumDuration
{
$annotations = [
'maximumDuration',
Expand Down Expand Up @@ -219,7 +219,7 @@ private function resolveMaximumDuration(Framework\Test $test): Duration
continue;
}

return Duration::fromMilliseconds((int) $maximumDuration);
return MaximumDuration::fromDuration(Duration::fromMilliseconds((int) $maximumDuration));

Check warning on line 222 in src/Extension.php

View check run for this annotation

Codecov / codecov/patch

src/Extension.php#L222

Added line #L222 was not covered by tests
}

return $this->maximumDuration;
Expand Down Expand Up @@ -267,10 +267,10 @@ public function __construct(array $options = [])
$maximumCount = Count::fromInt((int) $options['maximum-count']);
}

$maximumDuration = Duration::fromMilliseconds(500);
$maximumDuration = MaximumDuration::default();

Check warning on line 270 in src/Extension.php

View check run for this annotation

Codecov / codecov/patch

src/Extension.php#L270

Added line #L270 was not covered by tests

if (\array_key_exists('maximum-duration', $options)) {
$maximumDuration = Duration::fromMilliseconds((int) $options['maximum-duration']);
$maximumDuration = MaximumDuration::fromDuration(Duration::fromMilliseconds((int) $options['maximum-duration']));

Check warning on line 273 in src/Extension.php

View check run for this annotation

Codecov / codecov/patch

src/Extension.php#L273

Added line #L273 was not covered by tests
}

$this->maximumDuration = $maximumDuration;
Expand Down Expand Up @@ -306,21 +306,21 @@ public function executeAfterTest(
$seconds = (int) \floor($time);
$nanoseconds = (int) (($time - $seconds) * 1000000000);

$duration = Duration::fromSecondsAndNanoseconds(
$testDuration = TestDuration::fromDuration(Duration::fromSecondsAndNanoseconds(

Check warning on line 309 in src/Extension.php

View check run for this annotation

Codecov / codecov/patch

src/Extension.php#L309

Added line #L309 was not covered by tests
$seconds,
$nanoseconds
);
));

Check warning on line 312 in src/Extension.php

View check run for this annotation

Codecov / codecov/patch

src/Extension.php#L312

Added line #L312 was not covered by tests

$maximumDuration = $this->resolveMaximumDuration($test);

if (!$duration->isGreaterThan($maximumDuration)) {
if (!$testDuration->toDuration()->isGreaterThan($maximumDuration->toDuration())) {

Check warning on line 316 in src/Extension.php

View check run for this annotation

Codecov / codecov/patch

src/Extension.php#L316

Added line #L316 was not covered by tests
return;
}

$slowTest = SlowTest::create(
TestIdentifier::fromString($test),
TestDescription::fromString($test),
$duration,
$testDuration,

Check warning on line 323 in src/Extension.php

View check run for this annotation

Codecov / codecov/patch

src/Extension.php#L323

Added line #L323 was not covered by tests
$maximumDuration
);

Expand Down Expand Up @@ -354,7 +354,7 @@ public function executeAfterLastTest(): void
TXT;
}

private function resolveMaximumDuration(string $test): Duration
private function resolveMaximumDuration(string $test): MaximumDuration
{
list($testClassName, $testMethodName) = \explode(
'::',
Expand Down Expand Up @@ -390,7 +390,7 @@ private function resolveMaximumDuration(string $test): Duration
continue;
}

return Duration::fromMilliseconds((int) $maximumDuration);
return MaximumDuration::fromDuration(Duration::fromMilliseconds((int) $maximumDuration));

Check warning on line 393 in src/Extension.php

View check run for this annotation

Codecov / codecov/patch

src/Extension.php#L393

Added line #L393 was not covered by tests
}

return $this->maximumDuration;
Expand Down Expand Up @@ -421,10 +421,10 @@ public function bootstrap(
$maximumCount = Count::fromInt((int) $parameters->get('maximum-count'));
}

$maximumDuration = Duration::fromMilliseconds(500);
$maximumDuration = MaximumDuration::default();

Check warning on line 424 in src/Extension.php

View check run for this annotation

Codecov / codecov/patch

src/Extension.php#L424

Added line #L424 was not covered by tests

if ($parameters->has('maximum-duration')) {
$maximumDuration = Duration::fromMilliseconds((int) $parameters->get('maximum-duration'));
$maximumDuration = MaximumDuration::fromDuration(Duration::fromMilliseconds((int) $parameters->get('maximum-duration')));

Check warning on line 427 in src/Extension.php

View check run for this annotation

Codecov / codecov/patch

src/Extension.php#L427

Added line #L427 was not covered by tests
}

$timeKeeper = new TimeKeeper();
Expand Down
42 changes: 42 additions & 0 deletions src/MaximumDuration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2021-2025 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 MaximumDuration
{
private $duration;

private function __construct(Duration $duration)
{
$this->duration = $duration;
}

public static function fromDuration(Duration $duration): self
{
return new self($duration);
}

public static function default(): self
{
return new self(Duration::fromMilliseconds(500));
}

public function toDuration(): Duration
{
return $this->duration;
}
}
22 changes: 11 additions & 11 deletions src/Reporter/DefaultReporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

use Ergebnis\PHPUnit\SlowTestDetector\Comparator;
use Ergebnis\PHPUnit\SlowTestDetector\Count;
use Ergebnis\PHPUnit\SlowTestDetector\Duration;
use Ergebnis\PHPUnit\SlowTestDetector\Formatter;
use Ergebnis\PHPUnit\SlowTestDetector\MaximumDuration;
use Ergebnis\PHPUnit\SlowTestDetector\SlowTest;

/**
Expand All @@ -30,7 +30,7 @@ final class DefaultReporter implements Reporter
private $durationFormatter;

/**
* @var Duration
* @var MaximumDuration
*/
private $maximumDuration;

Expand All @@ -46,7 +46,7 @@ final class DefaultReporter implements Reporter

public function __construct(
Formatter\DurationFormatter $durationFormatter,
Duration $maximumDuration,
MaximumDuration $maximumDuration,
Count $maximumCount
) {
$this->durationFormatter = $durationFormatter;
Expand Down Expand Up @@ -102,8 +102,8 @@ private function list(SlowTest ...$slowTests): string

\usort($slowTests, static function (SlowTest $one, SlowTest $two) use ($durationComparator): int {
return $durationComparator->compare(
$two->duration(),
$one->duration()
$two->testDuration()->toDuration(),
$one->testDuration()->toDuration()
);
});

Expand All @@ -118,8 +118,8 @@ private function list(SlowTest ...$slowTests): string

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

Expand All @@ -131,8 +131,8 @@ static function (Duration $maximumDuration, SlowTest $slowTest): Duration {
$durationFormatter = $this->durationFormatter;

$numberWidth = \strlen((string) \count($slowTestsToReport));
$durationWidth = \strlen($durationFormatter->format($slowTestWithLongestDuration->duration()));
$maximumDurationWidth = \strlen($durationFormatter->format($longestMaximumDuration));
$durationWidth = \strlen($durationFormatter->format($slowTestWithLongestDuration->testDuration()->toDuration()));
$maximumDurationWidth = \strlen($durationFormatter->format($longestMaximumDuration->toDuration()));

$items = \array_map(static function (int $number, SlowTest $slowTest) use ($numberWidth, $durationFormatter, $durationWidth, $maximumDurationWidth): string {
$formattedNumber = \str_pad(
Expand All @@ -143,7 +143,7 @@ static function (Duration $maximumDuration, SlowTest $slowTest): Duration {
);

$formattedDuration = \str_pad(
$durationFormatter->format($slowTest->duration()),
$durationFormatter->format($slowTest->testDuration()->toDuration()),
$durationWidth,
' ',
\STR_PAD_LEFT
Expand All @@ -152,7 +152,7 @@ static function (Duration $maximumDuration, SlowTest $slowTest): Duration {
$formattedMaximumDuration = \sprintf(
'(%s)',
\str_pad(
$durationFormatter->format($slowTest->maximumDuration()),
$durationFormatter->format($slowTest->maximumDuration()->toDuration()),
$maximumDurationWidth,
' ',
\STR_PAD_LEFT
Expand Down
24 changes: 12 additions & 12 deletions src/SlowTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,37 +29,37 @@ final class SlowTest
private $testDescription;

/**
* @var Duration
* @var TestDuration
*/
private $duration;
private $testDuration;

/**
* @var Duration
* @var MaximumDuration
*/
private $maximumDuration;

private function __construct(
TestIdentifier $testIdentifier,
TestDescription $testDescription,
Duration $duration,
Duration $maximumDuration
TestDuration $testDuration,
MaximumDuration $maximumDuration
) {
$this->testIdentifier = $testIdentifier;
$this->testDescription = $testDescription;
$this->duration = $duration;
$this->testDuration = $testDuration;
$this->maximumDuration = $maximumDuration;
}

public static function create(
TestIdentifier $testIdentifier,
TestDescription $testDescription,
Duration $duration,
Duration $maximumDuration
TestDuration $testDuration,
MaximumDuration $maximumDuration
): self {
return new self(
$testIdentifier,
$testDescription,
$duration,
$testDuration,
$maximumDuration
);
}
Expand All @@ -74,12 +74,12 @@ public function testDescription(): TestDescription
return $this->testDescription;
}

public function duration(): Duration
public function testDuration(): TestDuration
{
return $this->duration;
return $this->testDuration;
}

public function maximumDuration(): Duration
public function maximumDuration(): MaximumDuration
{
return $this->maximumDuration;
}
Expand Down
Loading

0 comments on commit 3b14ae8

Please sign in to comment.