Skip to content

Commit

Permalink
fix: assertion count
Browse files Browse the repository at this point in the history
  • Loading branch information
nunomaduro committed Jul 24, 2023
1 parent 843ab88 commit f44834b
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 17 deletions.
21 changes: 17 additions & 4 deletions src/Blueprint.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Pest\Arch\Factories\LayerFactory;
use Pest\Arch\Options\LayerOptions;
use Pest\Arch\Repositories\ObjectsRepository;
use Pest\Arch\Support\AssertLocker;
use Pest\Arch\Support\Composer;
use Pest\Arch\ValueObjects\Dependency;
use Pest\Arch\ValueObjects\Targets;
Expand Down Expand Up @@ -59,6 +60,8 @@ public static function make(Targets $target, Dependencies $dependencies): self
*/
public function expectToUse(LayerOptions $options, callable $failure): void
{
AssertLocker::incrementAndLock();

foreach ($this->target->value as $targetValue) {
$targetLayer = $this->layerFactory->make($options, $targetValue);

Expand All @@ -74,6 +77,8 @@ public function expectToUse(LayerOptions $options, callable $failure): void
$failure($targetValue, $dependency->value);
}
}

AssertLocker::unlock();
}

/**
Expand All @@ -85,6 +90,8 @@ public function expectToUse(LayerOptions $options, callable $failure): void
*/
public function targeted(callable $callback, LayerOptions $options, callable $failure, callable $lineFinder): void
{
AssertLocker::incrementAndLock();

foreach ($this->target->value as $targetValue) {
$targetLayer = $this->layerFactory->make($options, $targetValue);

Expand All @@ -96,8 +103,6 @@ public function targeted(callable $callback, LayerOptions $options, callable $fa
}

if ($callback($object)) {
self::assertTrue(true);

continue;
}

Expand All @@ -108,6 +113,8 @@ public function targeted(callable $callback, LayerOptions $options, callable $fa
$failure(new Violation($path, $line, $line));
}
}

AssertLocker::unlock();
}

/**
Expand All @@ -117,6 +124,8 @@ public function targeted(callable $callback, LayerOptions $options, callable $fa
*/
public function expectToOnlyUse(LayerOptions $options, callable $failure): void
{
AssertLocker::incrementAndLock();

foreach ($this->target->value as $targetValue) {
$allowedUses = array_merge(
...array_map(fn (Layer $layer): array => array_map(
Expand All @@ -140,9 +149,9 @@ public function expectToOnlyUse(LayerOptions $options, callable $failure): void
}
}
}

self::assertTrue(true);
}

AssertLocker::unlock();
}

/**
Expand All @@ -152,6 +161,8 @@ public function expectToOnlyUse(LayerOptions $options, callable $failure): void
*/
public function expectToOnlyBeUsedIn(LayerOptions $options, callable $failure): void
{
AssertLocker::incrementAndLock();

foreach (Composer::userNamespaces() as $namespace) {
$namespaceLayer = $this->layerFactory->make($options, $namespace);

Expand All @@ -172,6 +183,8 @@ public function expectToOnlyBeUsedIn(LayerOptions $options, callable $failure):
}
}
}

AssertLocker::unlock();
}

/**
Expand Down
19 changes: 19 additions & 0 deletions src/Contracts/ArchExpectation.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Pest\Arch\Contracts;

use Pest\Expectation;
use PHPUnit\Architecture\Elements\ObjectDescription;

/**
* @internal
Expand All @@ -27,4 +28,22 @@ public function ignoring(array|string $targetsOrDependencies): self;
* @return $this
*/
public function ignoringGlobalFunctions(): self;

/**
* Merge the given exclude callbacks.
*
* @param array<int, callable(ObjectDescription): bool> $callbacks
*
* @internal
*/
public function mergeExcludeCallbacks(array $callbacks): void;

/**
* Returns the exclude callbacks.
*
* @return array<int, callable(ObjectDescription): bool>
*
* @internal
*/
public function excludeCallbacks(): array;
}
21 changes: 21 additions & 0 deletions src/GroupArchExpectation.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Pest\Arch;

use Closure;
use Pest\Arch\Contracts\ArchExpectation;
use Pest\Expectation;

/**
Expand Down Expand Up @@ -100,6 +101,26 @@ public function __get(string $name): mixed
return $this->original->$name; // @phpstan-ignore-line
}

/**
* {@inheritDoc}
*/
public function mergeExcludeCallbacks(array $excludeCallbacks): void
{
foreach ($this->expectations as $expectation) {
$expectation->mergeExcludeCallbacks($excludeCallbacks);
}
}

/**
* {@inheritDoc}
*/
public function excludeCallbacks(): array
{
return array_merge(...array_map(
fn (ArchExpectation $expectation): array => $expectation->excludeCallbacks(), $this->expectations,
));
}

/**
* Ensures the lazy expectation is verified when the object is destructed.
*/
Expand Down
5 changes: 2 additions & 3 deletions src/Options/LayerOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Pest\Arch\Options;

use Closure;
use Pest\Arch\SingleArchExpectation;
use PHPUnit\Architecture\Elements\ObjectDescription;

Expand All @@ -15,7 +14,7 @@ final class LayerOptions
{
/**
* @param array<int, string> $exclude
* @param array<int, Closure(ObjectDescription): bool> $excludeCallbacks
* @param array<int, callable(ObjectDescription): bool> $excludeCallbacks
*/
private function __construct(
public readonly array $exclude,
Expand All @@ -34,6 +33,6 @@ public static function fromExpectation(SingleArchExpectation $expectation): self
$expectation->ignoring,
);

return new self($exclude, $expectation->excludeCallbacks);
return new self($exclude, $expectation->excludeCallbacks());
}
}
14 changes: 9 additions & 5 deletions src/PendingArchExpectation.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Closure;
use Pest\Arch\Contracts\ArchExpectation;
use Pest\Expectation;
use Pest\Expectations\HigherOrderExpectation;
use PHPUnit\Architecture\Elements\ObjectDescription;

/**
Expand Down Expand Up @@ -37,7 +38,7 @@ public function __construct(
*/
public function classes(): self
{
$this->excludeCallbacks[] = fn (ObjectDescription $object): bool => ! class_exists($object->name);
$this->excludeCallbacks[] = fn (ObjectDescription $object): bool => ! class_exists($object->name) || enum_exists($object->name);

return $this;
}
Expand Down Expand Up @@ -94,10 +95,13 @@ public function __call(string $name, array $arguments): ArchExpectation
/** @var $archExpectation SingleArchExpectation */
$archExpectation = $expectation->{$name}(...$arguments); // @phpstan-ignore-line

$archExpectation->excludeCallbacks = array_merge(
$archExpectation->excludeCallbacks,
$this->excludeCallbacks,
);
if ($archExpectation instanceof HigherOrderExpectation) {
$originalExpectation = (fn (): \Pest\Expectation => $this->original)->call($archExpectation);
} else {
$originalExpectation = $archExpectation;
}

$originalExpectation->mergeExcludeCallbacks($this->excludeCallbacks);

return $archExpectation;
}
Expand Down
22 changes: 18 additions & 4 deletions src/SingleArchExpectation.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,9 @@ final class SingleArchExpectation implements Contracts\ArchExpectation
/**
* The ignored list of layers.
*
* @var array<int, Closure(ObjectDescription): bool>
*
* @internal
* @var array<int, callable(ObjectDescription): bool>
*/
public array $excludeCallbacks = [];
private array $excludeCallbacks = [];

/**
* Creates a new Arch Expectation instance.
Expand Down Expand Up @@ -118,6 +116,22 @@ public function __get(string $name): mixed
return $this->expectation->$name; // @phpstan-ignore-line
}

/**
* {@inheritDoc}
*/
public function mergeExcludeCallbacks(array $callbacks): void
{
$this->excludeCallbacks = [...$this->excludeCallbacks, ...$callbacks];
}

/**
* {@inheritDoc}
*/
public function excludeCallbacks(): array
{
return $this->excludeCallbacks;
}

/**
* Ensures the lazy expectation is verified when the object is destructed.
*/
Expand Down
53 changes: 53 additions & 0 deletions src/Support/AssertLocker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace Pest\Arch\Support;

use PHPUnit\Framework\Assert;
use ReflectionClass;
use ReflectionProperty;

/**
* @internal
*/
final class AssertLocker
{
/**
* The current assert count.
*/
private static int $count = 0;

/**
* Locks the assert count.
*/
public static function incrementAndLock(): void
{
Assert::assertTrue(true);

self::$count = Assert::getCount();
}

/**
* Unlocks the assert count.
*/
public static function unlock(): void
{
$reflection = self::reflection();

$reflection->setValue(null, self::$count);
}

/**
* Gets the current assert count reflection.
*/
private static function reflection(): ReflectionProperty
{
$reflectionClass = new ReflectionClass(Assert::class);

$property = $reflectionClass->getProperty('count');
$property->setAccessible(true);

return $property;
}
}
2 changes: 1 addition & 1 deletion tests/Fixtures/Contracts/NotUsed.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Tests\Fixtures\Contracts\Models;
namespace Tests\Fixtures\Contracts;

interface NotUsed
{
Expand Down

0 comments on commit f44834b

Please sign in to comment.