Skip to content

Commit

Permalink
Add limit metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
paulbalandan committed Aug 30, 2023
1 parent 3c52f6b commit 3a89f51
Show file tree
Hide file tree
Showing 9 changed files with 453 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

- Added `DurationFormatter` class
- Added parameter value objects: `Limit`, `Precision`, `ReportCount`
- Added `Limit` metadata objects
- Added `SlowTest` object and its collection
- Added `Stopwatch` class

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

declare(strict_types=1);

/**
* This file is part of Nexus Tachycardia.
*
* (c) 2021 John Paul E. Balandan, CPA <[email protected]>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace Nexus\PHPUnit\Tachycardia\Metadata;

use PHPUnit\Event\Telemetry\Duration;

/**
* @internal
*/
interface Limit
{
public function hasTimeLimit(): bool;

public function getTimeLimit(): Duration;

public function isMoreImportantThan(self $other): bool;
}
94 changes: 94 additions & 0 deletions src/Metadata/LimitCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

declare(strict_types=1);

/**
* This file is part of Nexus Tachycardia.
*
* (c) 2021 John Paul E. Balandan, CPA <[email protected]>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace Nexus\PHPUnit\Tachycardia\Metadata;

use Nexus\PHPUnit\Tachycardia\Parameter\Limit as LimitParameter;

/**
* @internal
*
* @immutable
*
* @implements \IteratorAggregate<int, Limit>
*/
final class LimitCollection implements \Countable, \IteratorAggregate
{
/**
* @var array<int, Limit>
*/
private readonly array $limits;

private function __construct(Limit ...$limits)
{
$this->limits = array_values($limits);
}

/**
* @param array<int, Limit> $limits
*/
public static function fromArray(array $limits): self
{
return new self(...$limits);
}

/**
* @return array<int, Limit>
*/
public function asArray(): array
{
return $this->limits;
}

public function count(): int
{
return \count($this->limits);
}

public function empty(): bool
{
return [] === $this->limits;
}

public function getIterator(): LimitCollectionIterator
{
return new LimitCollectionIterator($this);
}

public function mergeWith(self $other): self
{
return new self(...[
...$this->asArray(),
...$other->asArray(),
]);
}

public function reduce(LimitParameter $limitParameter): Limit
{
return array_reduce(
$this->limits,
static function (?Limit $initial, Limit $limit): Limit {
if ($initial === null) {
return $limit;
}

if ($limit->isMoreImportantThan($initial)) {
return $limit;
}

return $initial;
},
null
) ?? new TimeLimitForMethod($limitParameter->duration()->asFloat());
}
}
59 changes: 59 additions & 0 deletions src/Metadata/LimitCollectionIterator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

/**
* This file is part of Nexus Tachycardia.
*
* (c) 2021 John Paul E. Balandan, CPA <[email protected]>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace Nexus\PHPUnit\Tachycardia\Metadata;

/**
* @internal
*
* @implements \Iterator<int, Limit>
*/
final class LimitCollectionIterator implements \Iterator
{
/**
* @var array<int, Limit>
*/
private readonly array $limits;

private int $position = 0;

public function __construct(LimitCollection $limitCollection)
{
$this->limits = $limitCollection->asArray();
}

public function rewind(): void
{
$this->position = 0;
}

public function valid(): bool
{
return $this->position < \count($this->limits);
}

public function key(): int
{
return $this->position;
}

public function current(): Limit
{
return $this->limits[$this->position];
}

public function next(): void
{
++$this->position;
}
}
41 changes: 41 additions & 0 deletions src/Metadata/NoTimeLimitForClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

/**
* This file is part of Nexus Tachycardia.
*
* (c) 2021 John Paul E. Balandan, CPA <[email protected]>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace Nexus\PHPUnit\Tachycardia\Metadata;

use PHPUnit\Event\Telemetry\Duration;

/**
* @internal
*/
final class NoTimeLimitForClass implements Limit
{
public function hasTimeLimit(): bool
{
return false;
}

public function getTimeLimit(): Duration
{
return Duration::fromSecondsAndNanoseconds(0, 0);
}

public function isMoreImportantThan(Limit $other): bool
{
if ($other->hasTimeLimit()) {
return true;
}

return ! $other instanceof NoTimeLimitForMethod;
}
}
41 changes: 41 additions & 0 deletions src/Metadata/NoTimeLimitForMethod.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

/**
* This file is part of Nexus Tachycardia.
*
* (c) 2021 John Paul E. Balandan, CPA <[email protected]>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace Nexus\PHPUnit\Tachycardia\Metadata;

use PHPUnit\Event\Telemetry\Duration;

/**
* @internal
*/
final class NoTimeLimitForMethod implements Limit
{
public function hasTimeLimit(): bool
{
return false;
}

public function getTimeLimit(): Duration
{
return Duration::fromSecondsAndNanoseconds(0, 0);
}

public function isMoreImportantThan(Limit $other): bool
{
if ($other->hasTimeLimit()) {
return true;
}

return $other instanceof NoTimeLimitForClass;
}
}
50 changes: 50 additions & 0 deletions src/Metadata/TimeLimitForClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

/**
* This file is part of Nexus Tachycardia.
*
* (c) 2021 John Paul E. Balandan, CPA <[email protected]>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace Nexus\PHPUnit\Tachycardia\Metadata;

use Nexus\PHPUnit\Tachycardia\Parameter\Limit as LimitParameter;
use PHPUnit\Event\Telemetry\Duration;

/**
* @internal
*/
final class TimeLimitForClass implements Limit
{
public function __construct(
private readonly float $seconds,
) {}

public function hasTimeLimit(): bool
{
return true;
}

public function getTimeLimit(): Duration
{
return LimitParameter::fromSeconds($this->seconds)->duration();
}

public function isMoreImportantThan(Limit $other): bool
{
if (! $other->hasTimeLimit()) {
return false;
}

if ($other instanceof TimeLimitForMethod) {
return false;
}

return $this->getTimeLimit()->isLessThan($other->getTimeLimit());
}
}
50 changes: 50 additions & 0 deletions src/Metadata/TimeLimitForMethod.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

/**
* This file is part of Nexus Tachycardia.
*
* (c) 2021 John Paul E. Balandan, CPA <[email protected]>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace Nexus\PHPUnit\Tachycardia\Metadata;

use Nexus\PHPUnit\Tachycardia\Parameter\Limit as LimitParameter;
use PHPUnit\Event\Telemetry\Duration;

/**
* @internal
*/
final class TimeLimitForMethod implements Limit
{
public function __construct(
private readonly float $seconds,
) {}

public function hasTimeLimit(): bool
{
return true;
}

public function getTimeLimit(): Duration
{
return LimitParameter::fromSeconds($this->seconds)->duration();
}

public function isMoreImportantThan(Limit $other): bool
{
if (! $other->hasTimeLimit()) {
return false;
}

if ($other instanceof TimeLimitForClass) {
return true;
}

return $this->getTimeLimit()->isLessThan($other->getTimeLimit());
}
}
Loading

0 comments on commit 3a89f51

Please sign in to comment.