Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: Extract TestDuration and MaximumDuration #662

Merged
merged 1 commit into from
Feb 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@
private $suites = 0;

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

Expand All @@ -59,10 +59,10 @@
$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 @@
$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 @@
\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 @@
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 @@
$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 @@
$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 @@
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 @@
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 @@
$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;
}
}
26 changes: 13 additions & 13 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 @@ -113,13 +113,13 @@ private function list(SlowTest ...$slowTests): string
$this->maximumCount->toInt()
);

/** @var SlowTest $slowTestWithLongestDuration */
$slowTestWithLongestDuration = \reset($slowTestsToReport);
/** @var SlowTest $slowTestWithLongestTestDuration */
$slowTestWithLongestTestDuration = \reset($slowTestsToReport);

$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($slowTestWithLongestTestDuration->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
Loading