Skip to content

Commit

Permalink
Enhancement: Extract Seconds
Browse files Browse the repository at this point in the history
  • Loading branch information
localheinz committed Nov 7, 2023
1 parent b6178e7 commit 670531e
Show file tree
Hide file tree
Showing 21 changed files with 250 additions and 122 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.4.0...main`][2.4.0...main].

### Changed

- Extracted `Seconds` ([#362]), by [@localheinz]

## [`2.4.0`][2.4.0]

For a full diff see [`2.3.2...2.4.0`][2.3.2...2.4.0].
Expand Down Expand Up @@ -195,5 +199,6 @@ For a full diff see [`7afa59c...1.0.0`][7afa59c...1.0.0].
[#354]: https://github.com/ergebnis/phpunit-slow-test-detector/pull/354
[#355]: https://github.com/ergebnis/phpunit-slow-test-detector/pull/355
[#357]: https://github.com/ergebnis/phpunit-slow-test-detector/pull/357
[#362]: https://github.com/ergebnis/phpunit-slow-test-detector/pull/362

[@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 @@ -10,7 +10,7 @@
</file>
<file src="src/Formatter/DefaultDurationFormatter.php">
<InvalidOperand>
<code><![CDATA[$duration->seconds() * 1_000 + $duration->nanoseconds() / 1_000_000]]></code>
<code><![CDATA[$duration->seconds()->toInt() * 1_000 + $duration->nanoseconds() / 1_000_000]]></code>
<code>$durationInMilliseconds - $hoursInMilliseconds</code>
<code>$durationInMilliseconds - $hoursInMilliseconds</code>
<code>$durationInMilliseconds / 60</code>
Expand Down
25 changes: 10 additions & 15 deletions src/Duration.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,18 @@
final class Duration
{
private function __construct(
private readonly int $seconds,
private readonly Seconds $seconds,
private readonly int $nanoseconds,
) {
}

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

if (0 > $nanoseconds) {
throw Exception\InvalidNanoseconds::notGreaterThanOrEqualToZero($nanoseconds);
}
Expand Down Expand Up @@ -64,20 +59,20 @@ public static function fromMilliseconds(int $milliseconds): self
throw Exception\InvalidMilliseconds::notGreaterThanZero($milliseconds);
}

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

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

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

public function seconds(): int
public function seconds(): Seconds
{
return $this->seconds;
}
Expand All @@ -89,11 +84,11 @@ public function nanoseconds(): int

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

if ($this->seconds === $other->seconds) {
if ($this->seconds->toInt() === $other->seconds->toInt()) {
return $this->nanoseconds < $other->nanoseconds;
}

Expand All @@ -102,11 +97,11 @@ public function isLessThan(self $other): bool

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

if ($this->seconds === $other->seconds) {
if ($this->seconds->toInt() === $other->seconds->toInt()) {
return $this->nanoseconds > $other->nanoseconds;
}

Expand Down
9 changes: 8 additions & 1 deletion src/Exception/InvalidSeconds.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,15 @@ public static function notGreaterThanZero(int $value): self
));
}

public static function notGreaterThanOrEqualToZero(int $value): self
public static function notGreaterThanOrEqualToZero(float|int $value): self
{
if (\is_float($value)) {
return new self(\sprintf(
'Value should be greater than or equal to 0, but %f is not.',
$value,
));
}

return new self(\sprintf(
'Value should be greater than or equal to 0, but %d is not.',
$value,
Expand Down
4 changes: 2 additions & 2 deletions src/Extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ public function executeAfterSuccessfulTest(
string $test,
float $time,
): void {
$seconds = (int) \floor($time);
$nanoseconds = (int) (($time - $seconds) * 1_000_000_000);
$seconds = Seconds::fromFloat($time);
$nanoseconds = (int) (($time - $seconds->toInt()) * 1_000_000_000);

Check warning on line 127 in src/Extension.php

View check run for this annotation

Codecov / codecov/patch

src/Extension.php#L126-L127

Added lines #L126 - L127 were not covered by tests

$duration = Duration::fromSecondsAndNanoseconds(
$seconds,
Expand Down
2 changes: 1 addition & 1 deletion src/Formatter/DefaultDurationFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ final class DefaultDurationFormatter implements DurationFormatter
*/
public function format(Duration $duration): string
{
$durationInMilliseconds = $duration->seconds() * 1_000 + $duration->nanoseconds() / 1_000_000;
$durationInMilliseconds = $duration->seconds()->toInt() * 1_000 + $duration->nanoseconds() / 1_000_000;

$hours = (int) \floor($durationInMilliseconds / 60 / 60 / 1_000);
$hoursInMilliseconds = $hours * 60 * 60 * 1_000;
Expand Down
53 changes: 53 additions & 0 deletions src/Seconds.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?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 Seconds
{
private function __construct(private readonly int $value)
{
}

/**
* @throws Exception\InvalidSeconds
*/
public static function fromFloat(float $value): self
{
if (0 > $value) {
throw Exception\InvalidSeconds::notGreaterThanOrEqualToZero($value);
}

return new self((int) \floor($value));
}

/**
* @throws Exception\InvalidSeconds
*/
public static function fromInt(int $value): self
{
if (0 > $value) {
throw Exception\InvalidSeconds::notGreaterThanOrEqualToZero($value);
}

return new self($value);
}

public function toInt(): int
{
return $this->value;
}
}
3 changes: 2 additions & 1 deletion src/Subscriber/TestPassedSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use Ergebnis\PHPUnit\SlowTestDetector\Collector;
use Ergebnis\PHPUnit\SlowTestDetector\Duration;
use Ergebnis\PHPUnit\SlowTestDetector\Seconds;
use Ergebnis\PHPUnit\SlowTestDetector\SlowTest;
use Ergebnis\PHPUnit\SlowTestDetector\TestIdentifier;
use Ergebnis\PHPUnit\SlowTestDetector\Time;
Expand Down Expand Up @@ -43,7 +44,7 @@ public function notify(Event\Test\Passed $event): void
$duration = $this->timeKeeper->stop(
$testIdentifier,
Time::fromSecondsAndNanoseconds(
$time->seconds(),
Seconds::fromInt($time->seconds()),

Check warning on line 47 in src/Subscriber/TestPassedSubscriber.php

View check run for this annotation

Codecov / codecov/patch

src/Subscriber/TestPassedSubscriber.php#L47

Added line #L47 was not covered by tests
$time->nanoseconds(),
),
);
Expand Down
3 changes: 2 additions & 1 deletion src/Subscriber/TestPreparedSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace Ergebnis\PHPUnit\SlowTestDetector\Subscriber;

use Ergebnis\PHPUnit\SlowTestDetector\Seconds;
use Ergebnis\PHPUnit\SlowTestDetector\TestIdentifier;
use Ergebnis\PHPUnit\SlowTestDetector\Time;
use Ergebnis\PHPUnit\SlowTestDetector\TimeKeeper;
Expand All @@ -34,7 +35,7 @@ public function notify(Event\Test\Prepared $event): void
$this->timeKeeper->start(
TestIdentifier::fromString($event->test()->id()),
Time::fromSecondsAndNanoseconds(
$time->seconds(),
Seconds::fromInt($time->seconds()),

Check warning on line 38 in src/Subscriber/TestPreparedSubscriber.php

View check run for this annotation

Codecov / codecov/patch

src/Subscriber/TestPreparedSubscriber.php#L38

Added line #L38 was not covered by tests
$time->nanoseconds(),
),
);
Expand Down
15 changes: 5 additions & 10 deletions src/Time.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,18 @@
final class Time
{
private function __construct(
private readonly int $seconds,
private readonly Seconds $seconds,
private readonly int $nanoseconds,
) {
}

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

if (0 > $nanoseconds) {
throw Exception\InvalidNanoseconds::notGreaterThanOrEqualToZero($nanoseconds);
}
Expand All @@ -55,7 +50,7 @@ public static function fromSecondsAndNanoseconds(
);
}

public function seconds(): int
public function seconds(): Seconds
{
return $this->seconds;
}
Expand All @@ -70,7 +65,7 @@ public function nanoseconds(): int
*/
public function duration(self $start): Duration
{
$seconds = $this->seconds - $start->seconds;
$seconds = $this->seconds->toInt() - $start->seconds->toInt();
$nanoseconds = $this->nanoseconds - $start->nanoseconds;

if (0 > $nanoseconds) {
Expand All @@ -84,7 +79,7 @@ public function duration(self $start): Duration
}

return Duration::fromSecondsAndNanoseconds(
$seconds,
Seconds::fromInt($seconds),
$nanoseconds,
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/TimeKeeper.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function stop(

if (!\array_key_exists($key, $this->startedTimes)) {
return Duration::fromSecondsAndNanoseconds(
0,
Seconds::fromInt(0),
0,
);
}
Expand Down
2 changes: 2 additions & 0 deletions test/Unit/Collector/DefaultCollectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@

use Ergebnis\PHPUnit\SlowTestDetector\Collector;
use Ergebnis\PHPUnit\SlowTestDetector\Duration;
use Ergebnis\PHPUnit\SlowTestDetector\Seconds;
use Ergebnis\PHPUnit\SlowTestDetector\SlowTest;
use Ergebnis\PHPUnit\SlowTestDetector\Test;
use Ergebnis\PHPUnit\SlowTestDetector\TestIdentifier;
use PHPUnit\Framework;

#[Framework\Attributes\CoversClass(Collector\DefaultCollector::class)]
#[Framework\Attributes\UsesClass(Duration::class)]
#[Framework\Attributes\UsesClass(Seconds::class)]
#[Framework\Attributes\UsesClass(SlowTest::class)]
#[Framework\Attributes\UsesClass(TestIdentifier::class)]
final class DefaultCollectorTest extends Framework\TestCase
Expand Down
14 changes: 8 additions & 6 deletions test/Unit/Comparator/DurationComparatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,26 @@

use Ergebnis\PHPUnit\SlowTestDetector\Comparator;
use Ergebnis\PHPUnit\SlowTestDetector\Duration;
use Ergebnis\PHPUnit\SlowTestDetector\Seconds;
use Ergebnis\PHPUnit\SlowTestDetector\Test;
use PHPUnit\Framework;

#[Framework\Attributes\CoversClass(Comparator\DurationComparator::class)]
#[Framework\Attributes\UsesClass(Duration::class)]
#[Framework\Attributes\UsesClass(Seconds::class)]
final class DurationComparatorTest extends Framework\TestCase
{
use Test\Util\Helper;

public function testReturnsMinusOneWhenOneIsLessThanTwo(): void
{
$one = Duration::fromSecondsAndNanoseconds(
5,
Seconds::fromInt(5),
0,
);

$two = Duration::fromSecondsAndNanoseconds(
5,
Seconds::fromInt(5),
1,
);

Expand All @@ -44,12 +46,12 @@ public function testReturnsMinusOneWhenOneIsLessThanTwo(): void
public function testReturnsZeroWhenOneEqualsTwo(): void
{
$one = Duration::fromSecondsAndNanoseconds(
5,
Seconds::fromInt(5),
0,
);

$two = Duration::fromSecondsAndNanoseconds(
5,
Seconds::fromInt(5),
0,
);

Expand All @@ -61,12 +63,12 @@ public function testReturnsZeroWhenOneEqualsTwo(): void
public function testReturnsPlusOneWhenOneIsGreaterThanTwo(): void
{
$one = Duration::fromSecondsAndNanoseconds(
5,
Seconds::fromInt(5),
1,
);

$two = Duration::fromSecondsAndNanoseconds(
5,
Seconds::fromInt(5),
0,
);

Expand Down
Loading

0 comments on commit 670531e

Please sign in to comment.