Skip to content

Commit

Permalink
Enhancement: Implement StartedPhase and Phase
Browse files Browse the repository at this point in the history
  • Loading branch information
localheinz committed Dec 16, 2023
1 parent 3ddec39 commit 86a915c
Show file tree
Hide file tree
Showing 11 changed files with 439 additions and 42 deletions.
25 changes: 25 additions & 0 deletions src/Exception/InvalidPhaseIdentifier.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?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 InvalidPhaseIdentifier extends \InvalidArgumentException
{
public static function blankOrEmpty(): self

Check warning on line 21 in src/Exception/InvalidPhaseIdentifier.php

View check run for this annotation

Codecov / codecov/patch

src/Exception/InvalidPhaseIdentifier.php#L21

Added line #L21 was not covered by tests
{
return new self('Value can not be blank or empty.');

Check warning on line 23 in src/Exception/InvalidPhaseIdentifier.php

View check run for this annotation

Codecov / codecov/patch

src/Exception/InvalidPhaseIdentifier.php#L23

Added line #L23 was not covered by tests
}
}
70 changes: 70 additions & 0 deletions src/Phase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?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 Phase
{
private PhaseIdentifier $phaseIdentifier;
private Time $startTime;
private Time $stopTime;
private Duration $duration;

private function __construct(
PhaseIdentifier $phaseIdentifier,
Time $startTime,
Time $stopTime,
Duration $duration
) {
$this->phaseIdentifier = $phaseIdentifier;
$this->startTime = $startTime;
$this->stopTime = $stopTime;
$this->duration = $duration;
}

public static function create(
PhaseIdentifier $phaseIdentifier,
Time $startTime,
Time $stopTime
): self {
return new self(
$phaseIdentifier,
$startTime,
$stopTime,
$stopTime->duration($startTime),
);
}

public function phaseIdentifier(): PhaseIdentifier
{
return $this->phaseIdentifier;
}

public function startTime(): Time
{
return $this->startTime;
}

public function stopTime(): Time
{
return $this->stopTime;
}

public function duration(): Duration
{
return $this->duration;
}
}
44 changes: 44 additions & 0 deletions src/PhaseIdentifier.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?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 PhaseIdentifier
{
private string $value;

private function __construct(string $value)
{
$this->value = $value;
}

/**
* @throws Exception\InvalidPhaseIdentifier
*/
public static function fromString(string $value): self
{
if ('' === \trim($value)) {
throw Exception\InvalidPhaseIdentifier::blankOrEmpty();
}

return new self($value);
}

public function toString(): string
{
return $this->value;
}
}
51 changes: 51 additions & 0 deletions src/StartedPhase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?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 StartedPhase
{
private PhaseIdentifier $phaseIdentifier;
private Time $startTime;

private function __construct(
PhaseIdentifier $phaseIdentifier,
Time $startTime
) {
$this->phaseIdentifier = $phaseIdentifier;
$this->startTime = $startTime;
}

public static function create(
PhaseIdentifier $phaseIdentifier,
Time $startTime
): self {
return new self(
$phaseIdentifier,
$startTime,
);
}

public function phaseIdentifier(): PhaseIdentifier
{
return $this->phaseIdentifier;
}

public function startTime(): Time
{
return $this->startTime;
}
}
4 changes: 2 additions & 2 deletions src/Subscriber/TestPreparedSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace Ergebnis\PHPUnit\SlowTestDetector\Subscriber;

use Ergebnis\PHPUnit\SlowTestDetector\TestIdentifier;
use Ergebnis\PHPUnit\SlowTestDetector\PhaseIdentifier;
use Ergebnis\PHPUnit\SlowTestDetector\Time;
use Ergebnis\PHPUnit\SlowTestDetector\TimeKeeper;
use PHPUnit\Event;
Expand All @@ -38,7 +38,7 @@ public function notify(Event\Test\Prepared $event): void
$time = $event->telemetryInfo()->time();

$this->timeKeeper->start(
TestIdentifier::fromString($event->test()->id()),
PhaseIdentifier::fromString($event->test()->id()),
Time::fromSecondsAndNanoseconds(
$time->seconds(),
$time->nanoseconds(),
Expand Down
44 changes: 26 additions & 18 deletions src/TimeKeeper.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,44 @@
final class TimeKeeper
{
/**
* @var array<string, Time>
* @var array<string, StartedPhase>
*/
private array $startedTimes = [];
private array $startedPhases = [];

public function start(
TestIdentifier $testIdentifier,
Time $startedTime
PhaseIdentifier $phaseIdentifier,
Time $startTime
): void {
$key = $testIdentifier->toString();
$key = $phaseIdentifier->toString();

$this->startedTimes[$key] = $startedTime;
$this->startedPhases[$key] = StartedPhase::create(
$phaseIdentifier,
$startTime,
);
}

public function stop(
TestIdentifier $testIdentifier,
Time $stoppedTime
): Duration {
$key = $testIdentifier->toString();

if (!\array_key_exists($key, $this->startedTimes)) {
return Duration::fromSecondsAndNanoseconds(
0,
0,
PhaseIdentifier $phaseIdentifier,
Time $endTime
): Phase {
$key = $phaseIdentifier->toString();

if (!\array_key_exists($key, $this->startedPhases)) {
return Phase::create(
$phaseIdentifier,
$endTime,
$endTime,
);
}

$startedTime = $this->startedTimes[$key];
$startedPhase = $this->startedPhases[$key];

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

return $stoppedTime->duration($startedTime);
return Phase::create(
$phaseIdentifier,
$startedPhase->startTime(),
$endTime,
);
}
}
33 changes: 33 additions & 0 deletions test/Unit/Exception/InvalidPhaseIdentifierTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?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\Test\Unit\Exception;

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

/**
* @covers \Ergebnis\PHPUnit\SlowTestDetector\Exception\InvalidTestIdentifier
*/
final class InvalidPhaseIdentifierTest extends Framework\TestCase
{
use Test\Util\Helper;

public function testBlankOrEmptyReturnsException(): void
{
$exception = Exception\InvalidTestIdentifier::blankOrEmpty();

self::assertSame('Value can not be blank or empty.', $exception->getMessage());
}
}
50 changes: 50 additions & 0 deletions test/Unit/PhaseIdentifierTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?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\Test\Unit;

use Ergebnis\DataProvider;
use Ergebnis\PHPUnit\SlowTestDetector\Exception;
use Ergebnis\PHPUnit\SlowTestDetector\PhaseIdentifier;
use Ergebnis\PHPUnit\SlowTestDetector\Test;
use PHPUnit\Framework;

/**
* @covers \Ergebnis\PHPUnit\SlowTestDetector\PhaseIdentifier
*
* @uses \Ergebnis\PHPUnit\SlowTestDetector\Exception\InvalidPhaseIdentifier
*/
final class PhaseIdentifierTest extends Framework\TestCase
{
use Test\Util\Helper;

/**
* @dataProvider \Ergebnis\DataProvider\StringProvider::blank
* @dataProvider \Ergebnis\DataProvider\StringProvider::empty
*/
public function testFromStringRejectsInvalidValue(string $value): void
{
$this->expectException(Exception\InvalidPhaseIdentifier::class);

PhaseIdentifier::fromString($value);
}

public function testFromStringReturnsPhaseIdentifier(): void
{
$value = self::faker()->word();

$testIdentifier = PhaseIdentifier::fromString($value);

self::assertSame($value, $testIdentifier->tostring());
}
}
Loading

0 comments on commit 86a915c

Please sign in to comment.