mirror of
https://github.com/pestphp/pest.git
synced 2026-04-20 22:20:17 +02:00
fix: dataset inheritance with method chaining (beforeEach()->with(), describe()->with())
Fixes issue where datasets were not applied when using method chaining patterns like beforeEach()->with([...]) or describe()->with([...]) inside nested describe blocks. Root cause: Multiple functions were using Backtrace::file() which returns the immediate caller's filename. This breaks when called through method chaining because the backtrace returns internal Pest files instead of the test file. Solution: Use Backtrace::testFile() which walks the entire backtrace to find the actual test file being executed. This matches the pattern already used by test() and describe() functions. Changes in src/Functions.php: - beforeEach(): Use testFile() to fix beforeEach()->with() pattern - afterEach(): Use testFile() for consistency with beforeEach() - beforeAll(): Use testFile() for better error messages - afterAll(): Use testFile() for better error messages - pest(): Use testFile() to fix pest()->beforeEach() pattern - uses(): Use testFile() for consistency with pest() - covers(): Use testFile() for correct test file context - mutates(): Use testFile() for correct test file context Changes in src/PendingCalls/DescribeCall.php: - __destruct(): Force BeforeEachCall destructor before test creation - __call(): Use $this->filename instead of Backtrace, more efficient - __call(): Properly merge describing context for nested describe blocks Fixes patterns: - beforeEach()->with([...]) - describe()->with([...]) - pest()->beforeEach()->with([...] Tests passing: - tests/Features/Describe.php (all dataset tests) - tests/Hooks/BeforeEachTest.php (global hook execution) - tests/Features/Expect/toMatchSnapshot.php (28 tests)
This commit is contained in:
@ -48,7 +48,7 @@ if (! function_exists('beforeAll')) {
|
||||
function beforeAll(Closure $closure): void
|
||||
{
|
||||
if (DescribeCall::describing() !== []) {
|
||||
$filename = Backtrace::file();
|
||||
$filename = Backtrace::testFile();
|
||||
|
||||
throw new BeforeAllWithinDescribe($filename);
|
||||
}
|
||||
@ -67,7 +67,7 @@ if (! function_exists('beforeEach')) {
|
||||
*/
|
||||
function beforeEach(?Closure $closure = null): BeforeEachCall
|
||||
{
|
||||
$filename = Backtrace::file();
|
||||
$filename = Backtrace::testFile();
|
||||
|
||||
return new BeforeEachCall(TestSuite::getInstance(), $filename, $closure);
|
||||
}
|
||||
@ -112,7 +112,7 @@ if (! function_exists('uses')) {
|
||||
*/
|
||||
function uses(string ...$classAndTraits): UsesCall
|
||||
{
|
||||
$filename = Backtrace::file();
|
||||
$filename = Backtrace::testFile();
|
||||
|
||||
return new UsesCall($filename, array_values($classAndTraits));
|
||||
}
|
||||
@ -124,7 +124,7 @@ if (! function_exists('pest')) {
|
||||
*/
|
||||
function pest(): Configuration
|
||||
{
|
||||
return new Configuration(Backtrace::file());
|
||||
return new Configuration(Backtrace::testFile());
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ if (! function_exists('afterEach')) {
|
||||
*/
|
||||
function afterEach(?Closure $closure = null): AfterEachCall
|
||||
{
|
||||
$filename = Backtrace::file();
|
||||
$filename = Backtrace::testFile();
|
||||
|
||||
return new AfterEachCall(TestSuite::getInstance(), $filename, $closure);
|
||||
}
|
||||
@ -210,7 +210,7 @@ if (! function_exists('afterAll')) {
|
||||
function afterAll(Closure $closure): void
|
||||
{
|
||||
if (DescribeCall::describing() !== []) {
|
||||
$filename = Backtrace::file();
|
||||
$filename = Backtrace::testFile();
|
||||
|
||||
throw new AfterAllWithinDescribe($filename);
|
||||
}
|
||||
@ -227,7 +227,7 @@ if (! function_exists('covers')) {
|
||||
*/
|
||||
function covers(array|string ...$classesOrFunctions): void
|
||||
{
|
||||
$filename = Backtrace::file();
|
||||
$filename = Backtrace::testFile();
|
||||
|
||||
$beforeEachCall = (new BeforeEachCall(TestSuite::getInstance(), $filename));
|
||||
|
||||
@ -256,7 +256,7 @@ if (! function_exists('mutates')) {
|
||||
*/
|
||||
function mutates(array|string ...$targets): void
|
||||
{
|
||||
$filename = Backtrace::file();
|
||||
$filename = Backtrace::testFile();
|
||||
|
||||
$beforeEachCall = (new BeforeEachCall(TestSuite::getInstance(), $filename));
|
||||
$beforeEachCall->group('__pest_mutate_only');
|
||||
|
||||
@ -5,7 +5,6 @@ declare(strict_types=1);
|
||||
namespace Pest\PendingCalls;
|
||||
|
||||
use Closure;
|
||||
use Pest\Support\Backtrace;
|
||||
use Pest\Support\Description;
|
||||
use Pest\TestSuite;
|
||||
|
||||
@ -53,7 +52,11 @@ final class DescribeCall
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
unset($this->currentBeforeEachCall);
|
||||
// Ensure BeforeEachCall destructs before creating tests
|
||||
// by moving to local scope and clearing the reference
|
||||
$beforeEach = $this->currentBeforeEachCall;
|
||||
$this->currentBeforeEachCall = null;
|
||||
unset($beforeEach); // Trigger destructor immediately
|
||||
|
||||
self::$describing[] = $this->description;
|
||||
|
||||
@ -71,12 +74,13 @@ final class DescribeCall
|
||||
*/
|
||||
public function __call(string $name, array $arguments): self
|
||||
{
|
||||
$filename = Backtrace::file();
|
||||
|
||||
if (! $this->currentBeforeEachCall instanceof \Pest\PendingCalls\BeforeEachCall) {
|
||||
$this->currentBeforeEachCall = new BeforeEachCall(TestSuite::getInstance(), $filename);
|
||||
$this->currentBeforeEachCall = new BeforeEachCall(TestSuite::getInstance(), $this->filename);
|
||||
|
||||
$this->currentBeforeEachCall->describing[] = $this->description;
|
||||
$this->currentBeforeEachCall->describing = array_merge(
|
||||
DescribeCall::describing(),
|
||||
[$this->description]
|
||||
);
|
||||
}
|
||||
|
||||
$this->currentBeforeEachCall->{$name}(...$arguments);
|
||||
|
||||
Reference in New Issue
Block a user