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 Seconds #362

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
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 @@
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 @@
$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 @@
$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
Loading