fix: global afterEach being called twice

This commit is contained in:
Nuno Maduro
2024-09-11 00:40:41 +01:00
parent ea72461f1b
commit 32881774d2
6 changed files with 104 additions and 23 deletions

View File

@ -116,7 +116,7 @@ trait Testable
self::$__latestIssues = $method->issues; self::$__latestIssues = $method->issues;
self::$__latestPrs = $method->prs; self::$__latestPrs = $method->prs;
$this->__describing = $method->describing; $this->__describing = $method->describing;
$this->__test = $method->getClosure($this); $this->__test = $method->getClosure();
} }
} }
@ -240,6 +240,8 @@ trait Testable
$method = TestSuite::getInstance()->tests->get(self::$__filename)->getMethod($this->name()); $method = TestSuite::getInstance()->tests->get(self::$__filename)->getMethod($this->name());
$method->setUp($this);
$description = $method->description; $description = $method->description;
if ($this->dataName()) { if ($this->dataName()) {
$description = str_contains((string) $description, ':dataset') $description = str_contains((string) $description, ':dataset')
@ -298,6 +300,9 @@ trait Testable
parent::tearDown(); parent::tearDown();
TestSuite::getInstance()->test = null; TestSuite::getInstance()->test = null;
$method = TestSuite::getInstance()->tests->get(self::$__filename)->getMethod($this->name());
$method->tearDown($this);
} }
} }
@ -392,11 +397,12 @@ trait Testable
fn (ReflectionParameter $reflectionParameter): string => $reflectionParameter->getName(), fn (ReflectionParameter $reflectionParameter): string => $reflectionParameter->getName(),
array_filter($testReflection->getParameters(), fn (ReflectionParameter $reflectionParameter): bool => ! $reflectionParameter->isOptional()), array_filter($testReflection->getParameters(), fn (ReflectionParameter $reflectionParameter): bool => ! $reflectionParameter->isOptional()),
); );
if (array_diff($testParameterNames, $datasetParameterNames) === []) { if (array_diff($testParameterNames, $datasetParameterNames) === []) {
return; return;
} }
if (isset($testParameterNames[0])
&& $suppliedParametersCount >= $requiredParametersCount) { if (isset($testParameterNames[0]) && $suppliedParametersCount >= $requiredParametersCount) {
return; return;
} }

View File

@ -118,9 +118,9 @@ final class TestCaseMethodFactory
} }
/** /**
* Creates the test's closure. * Sets the test's hooks, and runs any proxy to the test case.
*/ */
public function getClosure(TestCase $concrete): Closure public function setUp(TestCase $concrete): void
{ {
$concrete::flush(); // @phpstan-ignore-line $concrete::flush(); // @phpstan-ignore-line
@ -128,14 +128,29 @@ final class TestCaseMethodFactory
throw ShouldNotHappen::fromMessage('Description can not be empty.'); throw ShouldNotHappen::fromMessage('Description can not be empty.');
} }
$closure = $this->closure;
$testCase = TestSuite::getInstance()->tests->get($this->filename); $testCase = TestSuite::getInstance()->tests->get($this->filename);
assert($testCase instanceof TestCaseFactory); assert($testCase instanceof TestCaseFactory);
$testCase->factoryProxies->proxy($concrete); $testCase->factoryProxies->proxy($concrete);
$this->factoryProxies->proxy($concrete); $this->factoryProxies->proxy($concrete);
}
/**
* Flushes the test case.
*/
public function tearDown(TestCase $concrete): void
{
$concrete::flush(); // @phpstan-ignore-line
}
/**
* Creates the test's closure.
*/
public function getClosure(): Closure
{
$closure = $this->closure;
$testCase = TestSuite::getInstance()->tests->get($this->filename);
assert($testCase instanceof TestCaseFactory);
$method = $this; $method = $this;
return function (...$arguments) use ($testCase, $method, $closure): mixed { // @phpstan-ignore-line return function (...$arguments) use ($testCase, $method, $closure): mixed { // @phpstan-ignore-line
@ -209,10 +224,8 @@ final class TestCaseMethodFactory
$attributesCode $attributesCode
public function $methodName(...\$arguments) public function $methodName(...\$arguments)
{ {
\$test = \Pest\TestSuite::getInstance()->tests->get(self::\$__filename)->getMethod(\$this->name())->getClosure(\$this);
return \$this->__runTest( return \$this->__runTest(
\$test, \$this->__test,
...\$arguments, ...\$arguments,
); );
} }

View File

@ -1305,6 +1305,7 @@
✓ it executes tests in the Helpers directory ✓ it executes tests in the Helpers directory
PASS Tests\Hooks\AfterEachTest PASS Tests\Hooks\AfterEachTest
✓ nested → nested afterEach execution order
✓ global afterEach execution order ✓ global afterEach execution order
PASS Tests\Hooks\BeforeEachTest PASS Tests\Hooks\BeforeEachTest
@ -1573,4 +1574,4 @@
WARN Tests\Visual\Version WARN Tests\Visual\Version
- visual snapshot of help command output - visual snapshot of help command output
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 28 skipped, 1088 passed (2615 assertions) Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 28 skipped, 1089 passed (2637 assertions)

View File

@ -1,23 +1,79 @@
<?php <?php
beforeEach(function () {
$this->ith = 0;
});
pest()->afterEach(function () { pest()->afterEach(function () {
expect($this) expect($this)
->toHaveProperty('ith') ->toHaveProperty('ith')
->and($this->ith) ->and($this->ith)
->toBe(1); ->toBe(3);
$this->ith = 2; $this->ith++;
});
pest()->afterEach(function () {
expect($this)
->toHaveProperty('ith')
->and($this->ith)
->toBe(4);
$this->ith++;
}); });
afterEach(function () { afterEach(function () {
expect($this) expect($this)
->toHaveProperty('ith') ->toHaveProperty('ith')
->and($this->ith) ->and($this->ith)
->toBe(2); ->toBe(5);
$this->ith++;
});
describe('nested', function () {
afterEach(function () {
expect($this)
->toHaveProperty('ith')
->and($this->ith)
->toBe(6);
$this->ith++;
});
test('nested afterEach execution order', function () {
expect($this)
->toHaveProperty('ith')
->and($this->ith)
->toBe(0);
$this->ith++;
});
afterEach(function () {
expect($this)
->toHaveProperty('ith')
->and($this->ith)
->toBe(7);
$this->ith++;
});
});
afterEach(function () {
expect($this)
->toHaveProperty('ith')
->and($this->ith)
->toBeBetween(6, 8);
$this->ith++;
}); });
test('global afterEach execution order', function () { test('global afterEach execution order', function () {
expect($this) expect($this)
->not() ->toHaveProperty('ith')
->toHaveProperty('ith'); ->and($this->ith)
->toBe(0);
$this->ith++;
}); });

View File

@ -32,7 +32,12 @@ pest()
$_SERVER['globalHook']->calls->beforeAll++; $_SERVER['globalHook']->calls->beforeAll++;
}) })
->afterEach(function () { ->afterEach(function () {
$this->ith = 0; if (! isset($this->ith)) {
return;
}
assert($this->ith === 1, 'Expected $this->ith to be 1, but got '.$this->ith);
$this->ith++;
}) })
->afterAll(function () { ->afterAll(function () {
$_SERVER['globalHook']->afterAll = 0; $_SERVER['globalHook']->afterAll = 0;
@ -57,12 +62,12 @@ pest()->in('Hooks')
$_SERVER['globalHook']->beforeAll = 1; $_SERVER['globalHook']->beforeAll = 1;
}) })
->afterEach(function () { ->afterEach(function () {
expect($this) if (! isset($this->ith)) {
->toHaveProperty('ith') return;
->and($this->ith) }
->toBe(0);
$this->ith = 1; assert($this->ith === 2, 'Expected $this->ith to be 1, but got '.$this->ith);
$this->ith++;
}) })
->afterAll(function () { ->afterAll(function () {
expect($_SERVER['globalHook']) expect($_SERVER['globalHook'])

View File

@ -16,7 +16,7 @@ $run = function () {
test('parallel', function () use ($run) { test('parallel', function () use ($run) {
expect($run('--exclude-group=integration')) expect($run('--exclude-group=integration'))
->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 19 skipped, 1078 passed (2591 assertions)') ->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 17 todos, 19 skipped, 1079 passed (2613 assertions)')
->toContain('Parallel: 3 processes'); ->toContain('Parallel: 3 processes');
})->skipOnWindows(); })->skipOnWindows();