mirror of
https://github.com/pestphp/pest.git
synced 2026-03-06 07:47:22 +01:00
Merge pull request #1295 from jshayes/nested-describe
Support for nested describe blocks
This commit is contained in:
@ -61,8 +61,10 @@ trait Testable
|
||||
|
||||
/**
|
||||
* The test's describing, if any.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
public ?string $__describing = null;
|
||||
public array $__describing = [];
|
||||
|
||||
/**
|
||||
* Whether the test has ran or not.
|
||||
|
||||
@ -31,8 +31,10 @@ final class TestCaseMethodFactory
|
||||
|
||||
/**
|
||||
* The test's describing, if any.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
public ?string $describing = null;
|
||||
public array $describing = [];
|
||||
|
||||
/**
|
||||
* The test's description, if any.
|
||||
@ -201,7 +203,7 @@ final class TestCaseMethodFactory
|
||||
];
|
||||
|
||||
foreach ($this->depends as $depend) {
|
||||
$depend = Str::evaluable($this->describing !== null ? Str::describe($this->describing, $depend) : $depend);
|
||||
$depend = Str::evaluable($this->describing === [] ? $depend : Str::describe($this->describing, $depend));
|
||||
|
||||
$this->attributes[] = new Attribute(
|
||||
\PHPUnit\Framework\Attributes\Depends::class,
|
||||
|
||||
@ -43,7 +43,7 @@ if (! function_exists('beforeAll')) {
|
||||
*/
|
||||
function beforeAll(Closure $closure): void
|
||||
{
|
||||
if (! is_null(DescribeCall::describing())) {
|
||||
if (DescribeCall::describing() !== []) {
|
||||
$filename = Backtrace::file();
|
||||
|
||||
throw new BeforeAllWithinDescribe($filename);
|
||||
@ -205,7 +205,7 @@ if (! function_exists('afterAll')) {
|
||||
*/
|
||||
function afterAll(Closure $closure): void
|
||||
{
|
||||
if (! is_null(DescribeCall::describing())) {
|
||||
if (DescribeCall::describing() !== []) {
|
||||
$filename = Backtrace::file();
|
||||
|
||||
throw new AfterAllWithinDescribe($filename);
|
||||
|
||||
@ -6,6 +6,7 @@ namespace Pest\PendingCalls;
|
||||
|
||||
use Closure;
|
||||
use Pest\PendingCalls\Concerns\Describable;
|
||||
use Pest\Support\Arr;
|
||||
use Pest\Support\Backtrace;
|
||||
use Pest\Support\ChainableClosure;
|
||||
use Pest\Support\HigherOrderMessageCollection;
|
||||
@ -54,7 +55,7 @@ final class AfterEachCall
|
||||
$proxies = $this->proxies;
|
||||
|
||||
$afterEachTestCase = ChainableClosure::boundWhen(
|
||||
fn (): bool => is_null($describing) || $this->__describing === $describing,
|
||||
fn (): bool => $describing === [] || in_array(Arr::last($describing), $this->__describing, true),
|
||||
ChainableClosure::bound(fn () => $proxies->chain($this), $this->closure)->bindTo($this, self::class), // @phpstan-ignore-line
|
||||
)->bindTo($this, self::class);
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ namespace Pest\PendingCalls;
|
||||
use Closure;
|
||||
use Pest\Exceptions\AfterBeforeTestFunction;
|
||||
use Pest\PendingCalls\Concerns\Describable;
|
||||
use Pest\Support\Arr;
|
||||
use Pest\Support\Backtrace;
|
||||
use Pest\Support\ChainableClosure;
|
||||
use Pest\Support\HigherOrderMessageCollection;
|
||||
@ -63,12 +64,12 @@ final class BeforeEachCall
|
||||
|
||||
$beforeEachTestCall = function (TestCall $testCall) use ($describing): void {
|
||||
|
||||
if ($this->describing !== null) {
|
||||
if ($describing !== $this->describing) {
|
||||
if ($this->describing !== []) {
|
||||
if (Arr::last($describing) !== Arr::last($this->describing)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($describing !== $testCall->describing) {
|
||||
if (! in_array(Arr::last($describing), $testCall->describing, true)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -77,7 +78,7 @@ final class BeforeEachCall
|
||||
};
|
||||
|
||||
$beforeEachTestCase = ChainableClosure::boundWhen(
|
||||
fn (): bool => is_null($describing) || $this->__describing === $describing,
|
||||
fn (): bool => $describing === [] || in_array(Arr::last($describing), $this->__describing, true),
|
||||
ChainableClosure::bound(fn () => $testCaseProxies->chain($this), $this->closure)->bindTo($this, self::class), // @phpstan-ignore-line
|
||||
)->bindTo($this, self::class);
|
||||
|
||||
@ -96,7 +97,7 @@ final class BeforeEachCall
|
||||
*/
|
||||
public function after(Closure $closure): self
|
||||
{
|
||||
if ($this->describing === null) {
|
||||
if ($this->describing === []) {
|
||||
throw new AfterBeforeTestFunction($this->filename);
|
||||
}
|
||||
|
||||
|
||||
@ -11,11 +11,15 @@ trait Describable
|
||||
{
|
||||
/**
|
||||
* Note: this is property is not used; however, it gets added automatically by rector php.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
public string $__describing;
|
||||
public array $__describing;
|
||||
|
||||
/**
|
||||
* The describing of the test case.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
public ?string $describing = null;
|
||||
public array $describing = [];
|
||||
}
|
||||
|
||||
@ -15,8 +15,10 @@ final class DescribeCall
|
||||
{
|
||||
/**
|
||||
* The current describe call.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
private static ?string $describing = null;
|
||||
private static array $describing = [];
|
||||
|
||||
/**
|
||||
* The describe "before each" call.
|
||||
@ -37,8 +39,10 @@ final class DescribeCall
|
||||
|
||||
/**
|
||||
* What is the current describing.
|
||||
*
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public static function describing(): ?string
|
||||
public static function describing(): array
|
||||
{
|
||||
return self::$describing;
|
||||
}
|
||||
@ -50,12 +54,12 @@ final class DescribeCall
|
||||
{
|
||||
unset($this->currentBeforeEachCall);
|
||||
|
||||
self::$describing = $this->description;
|
||||
self::$describing[] = $this->description;
|
||||
|
||||
try {
|
||||
($this->tests)();
|
||||
} finally {
|
||||
self::$describing = null;
|
||||
array_pop(self::$describing);
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,7 +75,7 @@ final class DescribeCall
|
||||
if (! $this->currentBeforeEachCall instanceof \Pest\PendingCalls\BeforeEachCall) {
|
||||
$this->currentBeforeEachCall = new BeforeEachCall(TestSuite::getInstance(), $filename);
|
||||
|
||||
$this->currentBeforeEachCall->describing = $this->description;
|
||||
$this->currentBeforeEachCall->describing[] = $this->description;
|
||||
}
|
||||
|
||||
$this->currentBeforeEachCall->{$name}(...$arguments); // @phpstan-ignore-line
|
||||
|
||||
@ -76,7 +76,7 @@ final class TestCall // @phpstan-ignore-line
|
||||
throw new TestDescriptionMissing($this->filename);
|
||||
}
|
||||
|
||||
$description = is_null($this->describing)
|
||||
$description = $this->describing === []
|
||||
? $this->description
|
||||
: Str::describe($this->describing, $this->description);
|
||||
|
||||
@ -683,7 +683,7 @@ final class TestCall // @phpstan-ignore-line
|
||||
throw new TestDescriptionMissing($this->filename);
|
||||
}
|
||||
|
||||
if (! is_null($this->describing)) {
|
||||
if ($this->describing !== []) {
|
||||
$this->testCaseMethod->describing = $this->describing;
|
||||
$this->testCaseMethod->description = Str::describe($this->describing, $this->description);
|
||||
} else {
|
||||
|
||||
@ -81,4 +81,14 @@ final class Arr
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the last element or false for empty array
|
||||
*
|
||||
* @param array<array-key, mixed> $array
|
||||
*/
|
||||
public static function last(array $array): mixed
|
||||
{
|
||||
return end($array);
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,10 +103,14 @@ final class Str
|
||||
|
||||
/**
|
||||
* Creates a describe block as `$describeDescription` → `$testDescription` format.
|
||||
*
|
||||
* @param array<int, string> $describeDescriptions
|
||||
*/
|
||||
public static function describe(string $describeDescription, string $testDescription): string
|
||||
public static function describe(array $describeDescriptions, string $testDescription): string
|
||||
{
|
||||
return sprintf('`%s` → %s', $describeDescription, $testDescription);
|
||||
$descriptionComponents = [...$describeDescriptions, $testDescription];
|
||||
|
||||
return sprintf(str_repeat('`%s` → ', count($describeDescriptions)).'%s', ...$descriptionComponents);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user