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:
Louis
2025-11-05 17:46:52 +01:00
parent 00990efc97
commit 26345fd9f4
2 changed files with 18 additions and 14 deletions

View File

@ -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');