Skip to content

Commit

Permalink
Enhancement: Implement MaximumDuration
Browse files Browse the repository at this point in the history
  • Loading branch information
localheinz committed Jan 26, 2021
1 parent 7c85a95 commit e6bd9ba
Show file tree
Hide file tree
Showing 11 changed files with 291 additions and 76 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ For a full diff see [`7afa59c...main`][7afa59c...main].
* Extracted `TimeKeeper` ([#22]), by [@localheinz]
* Extracted `Collector` ([#23]), by [@localheinz]
* Added `Subscriber\TestSuiteFinishedSubscriber` ([#34]), by [@localheinz]
* Added `MaximumDuration` ([#46]), by [@localheinz]

### Changed

Expand Down Expand Up @@ -55,5 +56,6 @@ For a full diff see [`7afa59c...main`][7afa59c...main].
[#36]: https://github.com/ergebnis/phpunit-slow-test-detector/pull/36
[#37]: https://github.com/ergebnis/phpunit-slow-test-detector/pull/37
[#38]: https://github.com/ergebnis/phpunit-slow-test-detector/pull/38
[#46]: https://github.com/ergebnis/phpunit-slow-test-detector/pull/46

[@localheinz]: https://github.com/localheinz
7 changes: 2 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ This extension provides three event subscribers for `phpunit/phpunit`:
These subscribers depend on the following:

- a `TimeKeeper` for keeping test prepared and passed times
- a maximum duration
- a `MaximumDuration`
- a `Collector\Collector` for collecting slow tests
- a `Reporter\Reporter` for reporting slow tests

Expand All @@ -54,10 +54,7 @@ $timeKeeper = new SlowTestDetector\TimeKeeper();

Event\Facade::registerSubscriber(new SlowTestDetector\Subscriber\TestPreparedSubscriber($timeKeeper));

$maximumDuration = Event\Telemetry\Duration::fromSecondsAndNanoseconds(
0,
500_000_000
);
$maximumDuration = SlowTestDetector\MaximumDuration::fromMilliseconds(500);

$collector = new SlowTestDetector\Collector\DefaultCollector();

Expand Down
25 changes: 25 additions & 0 deletions src/Exception/InvalidMaximumDuration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2021 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;

final class InvalidMaximumDuration extends \InvalidArgumentException
{
public static function notGreaterThanZero(int $value): self
{
return new self(\sprintf(
'Value should be greater than 0, but %d is not.',
$value
));
}
}
68 changes: 68 additions & 0 deletions src/MaximumDuration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2021 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;

use PHPUnit\Event;

final class MaximumDuration
{
private Event\Telemetry\Duration $duration;

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

/**
* @throws Exception\InvalidMaximumDuration
*/
public static function fromSeconds(int $seconds): self
{
if (0 >= $seconds) {
throw Exception\InvalidMaximumDuration::notGreaterThanZero($seconds);
}

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

/**
* @throws Exception\InvalidMaximumDuration
*/
public static function fromMilliseconds(int $milliseconds): self
{
if (0 >= $milliseconds) {
throw Exception\InvalidMaximumDuration::notGreaterThanZero($milliseconds);
}

$seconds = \intdiv(
$milliseconds,
1_000
);

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

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

public function toTelemetryDuration(): Event\Telemetry\Duration
{
return $this->duration;
}
}
7 changes: 4 additions & 3 deletions src/Reporter/DefaultReporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Ergebnis\PHPUnit\SlowTestDetector\Comparator;
use Ergebnis\PHPUnit\SlowTestDetector\Console;
use Ergebnis\PHPUnit\SlowTestDetector\Exception;
use Ergebnis\PHPUnit\SlowTestDetector\MaximumDuration;
use Ergebnis\PHPUnit\SlowTestDetector\SlowTest;
use PHPUnit\Event;

Expand All @@ -27,14 +28,14 @@ final class DefaultReporter implements Reporter

private int $maximumNumber;

private Event\Telemetry\Duration $maximumDuration;
private MaximumDuration $maximumDuration;

/**
* @throws Exception\MaximumNumberNotGreaterThanZero
*/
public function __construct(
Event\Telemetry\DurationFormatter $durationFormatter,
Event\Telemetry\Duration $maximumDuration,
MaximumDuration $maximumDuration,
int $maximumNumber
) {
if (0 >= $maximumNumber) {
Expand Down Expand Up @@ -117,7 +118,7 @@ static function (Event\Telemetry\Duration $maximumDuration, SlowTest $slowTest):

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

$durationFormatter = $this->durationFormatter;
Expand Down
9 changes: 5 additions & 4 deletions src/Subscriber/TestPassedSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,21 @@
namespace Ergebnis\PHPUnit\SlowTestDetector\Subscriber;

use Ergebnis\PHPUnit\SlowTestDetector\Collector;
use Ergebnis\PHPUnit\SlowTestDetector\MaximumDuration;
use Ergebnis\PHPUnit\SlowTestDetector\SlowTest;
use Ergebnis\PHPUnit\SlowTestDetector\TimeKeeper;
use PHPUnit\Event;

final class TestPassedSubscriber implements Event\Test\PassedSubscriber
{
private Event\Telemetry\Duration $maximumDuration;
private MaximumDuration$maximumDuration;

private TimeKeeper $timeKeeper;

private Collector\Collector $collector;

public function __construct(
Event\Telemetry\Duration $maximumDuration,
MaximumDuration $maximumDuration,
TimeKeeper $timeKeeper,
Collector\Collector $collector
) {
Expand All @@ -43,14 +44,14 @@ public function notify(Event\Test\Passed $event): void
$event->telemetryInfo()->time()
);

if (!$duration->isGreaterThan($this->maximumDuration)) {
if (!$duration->isGreaterThan($this->maximumDuration->toTelemetryDuration())) {
return;
}

$slowTest = SlowTest::fromTestDurationAndMaximumDuration(
$event->test(),
$duration,
$this->maximumDuration
$this->maximumDuration->toTelemetryDuration()
);

$this->collector->collect($slowTest);
Expand Down
5 changes: 1 addition & 4 deletions test/Example/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@
$maximumNumber = (int) \getenv('MAXIMUM_NUMBER');
}

$maximumDuration = Event\Telemetry\Duration::fromSecondsAndNanoseconds(
0,
125_000_000
);
$maximumDuration = SlowTestDetector\MaximumDuration::fromMilliseconds(125);

$collector = new SlowTestDetector\Collector\DefaultCollector();

Expand Down
42 changes: 42 additions & 0 deletions test/Unit/Exception/InvalidMaximumDurationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2021 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\Test\Unit\Exception;

use Ergebnis\PHPUnit\SlowTestDetector\Exception\InvalidMaximumDuration;
use Ergebnis\Test\Util;
use PHPUnit\Framework;

/**
* @internal
*
* @covers \Ergebnis\PHPUnit\SlowTestDetector\Exception\InvalidMaximumDuration
*/
final class InvalidMaximumDurationTest extends Framework\TestCase
{
use Util\Helper;

public function testNotGreaterThanReturnsException(): void
{
$value = self::faker()->numberBetween();

$exception = InvalidMaximumDuration::notGreaterThanZero($value);

$message = \sprintf(
'Value should be greater than 0, but %d is not.',
$value
);

self::assertSame($message, $exception->getMessage());
}
}
99 changes: 99 additions & 0 deletions test/Unit/MaximumDurationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2021 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\Test\Unit;

use Ergebnis\PHPUnit\SlowTestDetector\Exception;
use Ergebnis\PHPUnit\SlowTestDetector\MaximumDuration;
use Ergebnis\Test\Util;
use PHPUnit\Event;
use PHPUnit\Framework;

/**
* @internal
*
* @covers \Ergebnis\PHPUnit\SlowTestDetector\MaximumDuration
*
* @uses \Ergebnis\PHPUnit\SlowTestDetector\Exception\InvalidMaximumDuration
*/
final class MaximumDurationTest extends Framework\TestCase
{
use Util\Helper;

/**
* @dataProvider \Ergebnis\Test\Util\DataProvider\IntProvider::lessThanZero()
* @dataProvider \Ergebnis\Test\Util\DataProvider\IntProvider::zero()
*/
public function testFromMillisecondsRejectsInvalidValue(int $milliseconds): void
{
$this->expectException(Exception\InvalidMaximumDuration::class);

MaximumDuration::fromMilliseconds($milliseconds);
}

/**
* @dataProvider provideMillisecondsAndTelemetryDuration
*/
public function testFromMillisecondsReturnsMaximumDuration(int $milliseconds, Event\Telemetry\Duration $duration): void
{
$maximumDuration = MaximumDuration::fromMilliseconds($milliseconds);

self::assertEquals($duration, $maximumDuration->toTelemetryDuration());
}

/**
* @return \Generator<int, array{0: int, Event\Telemetry\Duration}>
*/
public function provideMillisecondsAndTelemetryDuration(): \Generator
{
$values = [
1 => Event\Telemetry\Duration::fromSecondsAndNanoseconds(0, 1_000_000),
999 => Event\Telemetry\Duration::fromSecondsAndNanoseconds(0, 999_000_000),
1_000 => Event\Telemetry\Duration::fromSecondsAndNanoseconds(1, 0),
1_234 => Event\Telemetry\Duration::fromSecondsAndNanoseconds(1, 234_000_000),
];

foreach ($values as $milliseconds => $duration) {
yield $milliseconds => [
$milliseconds,
$duration,
];
}
}

/**
* @dataProvider \Ergebnis\Test\Util\DataProvider\IntProvider::lessThanZero()
* @dataProvider \Ergebnis\Test\Util\DataProvider\IntProvider::zero()
*/
public function testFromSecondsRejectsInvalidValue(int $seconds): void
{
$this->expectException(Exception\InvalidMaximumDuration::class);

MaximumDuration::fromSeconds($seconds);
}

/**
* @dataProvider \Ergebnis\Test\Util\DataProvider\IntProvider::greaterThanZero()
*/
public function testFromSecondsReturnsMaximumDuration(int $seconds): void
{
$maximumDuration = MaximumDuration::fromSeconds($seconds);

$expected = Event\Telemetry\Duration::fromSecondsAndNanoseconds(
$seconds,
0
);

self::assertEquals($expected, $maximumDuration->toTelemetryDuration());
}
}
Loading

0 comments on commit e6bd9ba

Please sign in to comment.