mirror of
https://github.com/pestphp/pest.git
synced 2026-04-26 00:47:27 +02:00
feat(describe): improves logic around hooks
This commit is contained in:
@ -5,6 +5,8 @@ declare(strict_types=1);
|
||||
namespace Pest\PendingCalls;
|
||||
|
||||
use Closure;
|
||||
use Pest\PendingCalls;
|
||||
use Pest\PendingCalls\Concerns\Describable;
|
||||
use Pest\Support\Backtrace;
|
||||
use Pest\Support\ChainableClosure;
|
||||
use Pest\Support\HigherOrderMessageCollection;
|
||||
@ -16,6 +18,8 @@ use Pest\TestSuite;
|
||||
*/
|
||||
final class AfterEachCall
|
||||
{
|
||||
use Describable;
|
||||
|
||||
/**
|
||||
* The "afterEach" closure.
|
||||
*/
|
||||
@ -44,14 +48,23 @@ final class AfterEachCall
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$proxies = $this->proxies;
|
||||
PendingCalls::afterEach($this, function (string $describing = null) {
|
||||
$proxies = $this->proxies;
|
||||
|
||||
$afterEachTestCase = ChainableClosure::when(
|
||||
fn () => is_null($describing) || $this->__describeDescription === $describing, // @phpstan-ignore-line
|
||||
ChainableClosure::from(fn () => $proxies->chain($this), $this->closure)->bindTo($this, self::class), // @phpstan-ignore-line
|
||||
)->bindTo($this, self::class);
|
||||
|
||||
assert($afterEachTestCase instanceof Closure);
|
||||
|
||||
$this->testSuite->afterEach->set(
|
||||
$this->filename,
|
||||
$this,
|
||||
$afterEachTestCase,
|
||||
);
|
||||
});
|
||||
|
||||
$this->testSuite->afterEach->set(
|
||||
$this->filename,
|
||||
ChainableClosure::from(function () use ($proxies): void {
|
||||
$proxies->chain($this);
|
||||
}, $this->closure)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -5,6 +5,8 @@ declare(strict_types=1);
|
||||
namespace Pest\PendingCalls;
|
||||
|
||||
use Closure;
|
||||
use Pest\PendingCalls;
|
||||
use Pest\PendingCalls\Concerns\Describable;
|
||||
use Pest\Support\Backtrace;
|
||||
use Pest\Support\ChainableClosure;
|
||||
use Pest\Support\HigherOrderMessageCollection;
|
||||
@ -16,6 +18,8 @@ use Pest\TestSuite;
|
||||
*/
|
||||
final class BeforeEachCall
|
||||
{
|
||||
use Describable;
|
||||
|
||||
/**
|
||||
* Holds the before each closure.
|
||||
*/
|
||||
@ -35,7 +39,7 @@ final class BeforeEachCall
|
||||
* Creates a new Pending Call.
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly TestSuite $testSuite,
|
||||
public readonly TestSuite $testSuite,
|
||||
private readonly string $filename,
|
||||
Closure $closure = null
|
||||
) {
|
||||
@ -50,17 +54,29 @@ final class BeforeEachCall
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$testCaseProxies = $this->testCaseProxies;
|
||||
PendingCalls::beforeEach($this, function (string $describing = null) {
|
||||
$testCaseProxies = $this->testCaseProxies;
|
||||
|
||||
$this->testSuite->beforeEach->set(
|
||||
$this->filename,
|
||||
function (TestCall $testCall): void {
|
||||
$this->testCallProxies->chain($testCall);
|
||||
},
|
||||
ChainableClosure::from(function () use ($testCaseProxies): void {
|
||||
$testCaseProxies->chain($this);
|
||||
}, $this->closure),
|
||||
);
|
||||
$beforeEachTestCall = function (TestCall $testCall) use ($describing): void {
|
||||
if (is_null($describing) || ($this->describing === $testCall->describing && $testCall->describing === $describing)) {
|
||||
$this->testCallProxies->chain($testCall);
|
||||
}
|
||||
};
|
||||
|
||||
$beforeEachTestCase = ChainableClosure::when(
|
||||
fn () => is_null($describing) || $this->__describeDescription === $describing, // @phpstan-ignore-line
|
||||
ChainableClosure::from(fn () => $testCaseProxies->chain($this), $this->closure)->bindTo($this, self::class), // @phpstan-ignore-line
|
||||
)->bindTo($this, self::class);
|
||||
|
||||
assert($beforeEachTestCase instanceof Closure);
|
||||
|
||||
$this->testSuite->beforeEach->set(
|
||||
$this->filename,
|
||||
$this,
|
||||
$beforeEachTestCall,
|
||||
$beforeEachTestCase,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,6 +86,7 @@ final class BeforeEachCall
|
||||
*/
|
||||
public function __call(string $name, array $arguments): self
|
||||
{
|
||||
|
||||
if (method_exists(TestCall::class, $name)) {
|
||||
$this->testCallProxies->add(Backtrace::file(), Backtrace::line(), $name, $arguments);
|
||||
|
||||
|
||||
13
src/PendingCalls/Concerns/Describable.php
Normal file
13
src/PendingCalls/Concerns/Describable.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Pest\PendingCalls\Concerns;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
trait Describable
|
||||
{
|
||||
public string|null $describing = null;
|
||||
}
|
||||
46
src/PendingCalls/DescribeCall.php
Normal file
46
src/PendingCalls/DescribeCall.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Pest\PendingCalls;
|
||||
|
||||
use Closure;
|
||||
use Pest\PendingCalls;
|
||||
use Pest\TestSuite;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class DescribeCall
|
||||
{
|
||||
/**
|
||||
* Creates a new Pending Call.
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly TestSuite $testSuite,
|
||||
public readonly string $filename,
|
||||
public readonly string $description,
|
||||
public readonly Closure $tests
|
||||
) {
|
||||
//
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
PendingCalls::endDescribe($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically calls methods on each test call.
|
||||
*
|
||||
* @param array<int, mixed> $arguments
|
||||
*/
|
||||
public function __call(string $name, array $arguments): self
|
||||
{
|
||||
foreach (PendingCalls::$testCalls as [$testCall]) {
|
||||
$testCall->{$name}(...$arguments); // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,8 @@ use Pest\Factories\Covers\CoversClass;
|
||||
use Pest\Factories\Covers\CoversFunction;
|
||||
use Pest\Factories\Covers\CoversNothing;
|
||||
use Pest\Factories\TestCaseMethodFactory;
|
||||
use Pest\PendingCalls;
|
||||
use Pest\PendingCalls\Concerns\Describable;
|
||||
use Pest\Plugins\Only;
|
||||
use Pest\Support\Backtrace;
|
||||
use Pest\Support\Exporter;
|
||||
@ -25,10 +27,12 @@ use PHPUnit\Framework\TestCase;
|
||||
*/
|
||||
final class TestCall
|
||||
{
|
||||
use Describable;
|
||||
|
||||
/**
|
||||
* The Test Case Factory.
|
||||
*/
|
||||
private readonly TestCaseMethodFactory $testCaseMethod;
|
||||
public readonly TestCaseMethodFactory $testCaseMethod;
|
||||
|
||||
/**
|
||||
* If test call is descriptionLess.
|
||||
@ -48,7 +52,7 @@ final class TestCall
|
||||
|
||||
$this->descriptionLess = $description === null;
|
||||
|
||||
$this->testSuite->beforeEach->get($filename)[0]($this);
|
||||
$this->testSuite->beforeEach->get($this->filename)[0]($this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -316,12 +320,14 @@ final class TestCall
|
||||
private function addChain(string $file, int $line, string $name, array $arguments = null): self
|
||||
{
|
||||
$exporter = Exporter::default();
|
||||
|
||||
$this->testCaseMethod
|
||||
->chains
|
||||
->add($file, $line, $name, $arguments);
|
||||
|
||||
if ($this->descriptionLess) {
|
||||
Exporter::default();
|
||||
|
||||
if ($this->testCaseMethod->description !== null) {
|
||||
$this->testCaseMethod->description .= ' → ';
|
||||
}
|
||||
@ -338,6 +344,10 @@ final class TestCall
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->testSuite->tests->set($this->testCaseMethod);
|
||||
PendingCalls::test($this, function () {
|
||||
$this->testCaseMethod->describing = $this->describing;
|
||||
|
||||
$this->testSuite->tests->set($this->testCaseMethod);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user