Add ability to define multiple hooks for the same directory in Pest.php

This commit is contained in:
Bastien Philippe
2023-09-15 15:54:26 +02:00
committed by Nuno Maduro
parent 9c077ed352
commit 9d58e1a77e
6 changed files with 160 additions and 19 deletions

View File

@ -25,7 +25,7 @@ final class TestRepository
private array $testCases = []; private array $testCases = [];
/** /**
* @var array<string, array{0: array<int, string>, 1: array<int, string>, 2: array<int, string|Closure>}> * @var array<string, array{0: array<int, string>, 1: array<int, string>, 2: array<int, array<int, string|Closure>>}>
*/ */
private array $uses = []; private array $uses = [];
@ -77,12 +77,17 @@ final class TestRepository
throw new TestCaseClassOrTraitNotFound($classOrTrait); throw new TestCaseClassOrTraitNotFound($classOrTrait);
} }
$hooks = array_map(fn (Closure $hook): array => [$hook], $hooks);
foreach ($paths as $path) { foreach ($paths as $path) {
if (array_key_exists($path, $this->uses)) { if (array_key_exists($path, $this->uses)) {
$this->uses[$path] = [ $this->uses[$path] = [
[...$this->uses[$path][0], ...$classOrTraits], [...$this->uses[$path][0], ...$classOrTraits],
[...$this->uses[$path][1], ...$groups], [...$this->uses[$path][1], ...$groups],
$this->uses[$path][2] + $hooks, array_map(
fn (int $index): array => [...$this->uses[$path][2][$index] ?? [], ...($hooks[$index] ?? [])],
range(0, 3),
),
]; ];
} else { } else {
$this->uses[$path] = [$classOrTraits, $groups, $hooks]; $this->uses[$path] = [$classOrTraits, $groups, $hooks];
@ -189,10 +194,11 @@ final class TestRepository
$method->groups = [...$groups, ...$method->groups]; $method->groups = [...$groups, ...$method->groups];
} }
$testCase->factoryProxies->add($testCase->filename, 0, '__addBeforeAll', [$hooks[0] ?? null]); foreach (['__addBeforeAll', '__addBeforeEach', '__addAfterEach', '__addAfterAll'] as $index => $name) {
$testCase->factoryProxies->add($testCase->filename, 0, '__addBeforeEach', [$hooks[1] ?? null]); foreach ($hooks[$index] ?? [null] as $hook) {
$testCase->factoryProxies->add($testCase->filename, 0, '__addAfterEach', [$hooks[2] ?? null]); $testCase->factoryProxies->add($testCase->filename, 0, $name, [$hook]);
$testCase->factoryProxies->add($testCase->filename, 0, '__addAfterAll', [$hooks[3] ?? null]); }
}
} }
} }

View File

@ -0,0 +1,45 @@
<?php
uses()->afterAll(function () {
expect($_SERVER['globalHook'])
->toHaveProperty('afterAll')
->and($_SERVER['globalHook']->afterAll)
->toBe(1)
->and($_SERVER['globalHook']->calls)
->afterAll
->toBe(1);
$_SERVER['globalHook']->afterAll = 2;
$_SERVER['globalHook']->calls->afterAll++;
});
afterAll(function () {
expect($_SERVER['globalHook'])
->toHaveProperty('afterAll')
->and($_SERVER['globalHook']->afterAll)
->toBe(1)
->and($_SERVER['globalHook']->calls)
->afterAll
->toBe(2);
$_SERVER['globalHook']->afterAll = 2;
$_SERVER['globalHook']->calls->afterAll++;
});
test('global afterAll execution order', function () {
expect($_SERVER['globalHook'])
->not()
->toHaveProperty('afterAll')
->and($_SERVER['globalHook']->calls)
->afterAll
->toBe(0);
});
it('only gets called once per file', function () {
expect($_SERVER['globalHook'])
->not()
->toHaveProperty('afterAll')
->and($_SERVER['globalHook']->calls)
->afterAll
->toBe(0);
});

View File

@ -4,16 +4,16 @@ uses()->afterEach(function () {
expect($this) expect($this)
->toHaveProperty('ith') ->toHaveProperty('ith')
->and($this->ith) ->and($this->ith)
->toBe(0); ->toBe(1);
$this->ith = 1; $this->ith = 2;
}); });
afterEach(function () { afterEach(function () {
expect($this) expect($this)
->toHaveProperty('ith') ->toHaveProperty('ith')
->and($this->ith) ->and($this->ith)
->toBe(1); ->toBe(2);
}); });
test('global afterEach execution order', function () { test('global afterEach execution order', function () {

View File

@ -0,0 +1,55 @@
<?php
use Pest\Plugins\Parallel;
use Pest\Support\Str;
// HACK: we have to determine our $_SERVER['globalHook-]>calls baseline. This is because
// two other tests are executed before this one due to filename ordering.
$args = $_SERVER['argv'] ?? [];
$single = (isset($args[1]) && Str::endsWith(__FILE__, $args[1])) || Parallel::isWorker();
$offset = $single ? 0 : 2;
uses()->beforeAll(function () use ($offset) {
expect($_SERVER['globalHook'])
->toHaveProperty('beforeAll')
->and($_SERVER['globalHook']->beforeAll)
->toBe(1)
->and($_SERVER['globalHook']->calls)
->beforeAll
->toBe(1 + $offset);
$_SERVER['globalHook']->beforeAll = 2;
$_SERVER['globalHook']->calls->beforeAll++;
});
beforeAll(function () use ($offset) {
expect($_SERVER['globalHook'])
->toHaveProperty('beforeAll')
->and($_SERVER['globalHook']->beforeAll)
->toBe(2)
->and($_SERVER['globalHook']->calls)
->beforeAll
->toBe(2 + $offset);
$_SERVER['globalHook']->beforeAll = 3;
$_SERVER['globalHook']->calls->beforeAll++;
});
test('global beforeAll execution order', function () use ($offset) {
expect($_SERVER['globalHook'])
->toHaveProperty('beforeAll')
->and($_SERVER['globalHook']->beforeAll)
->toBe(3)
->and($_SERVER['globalHook']->calls)
->beforeAll
->toBe(3 + $offset);
});
it('only gets called once per file', function () use ($offset) {
expect($_SERVER['globalHook'])
->beforeAll
->toBe(3)
->and($_SERVER['globalHook']->calls)
->beforeAll
->toBe(3 + $offset);
});

View File

@ -1,15 +1,6 @@
<?php <?php
uses()->beforeEach(function () { uses()->beforeEach(function () {
expect($this)
->toHaveProperty('baz')
->and($this->baz)
->toBe(0);
$this->baz = 1;
});
beforeEach(function () {
expect($this) expect($this)
->toHaveProperty('baz') ->toHaveProperty('baz')
->and($this->baz) ->and($this->baz)
@ -18,9 +9,18 @@ beforeEach(function () {
$this->baz = 2; $this->baz = 2;
}); });
test('global beforeEach execution order', function () { beforeEach(function () {
expect($this) expect($this)
->toHaveProperty('baz') ->toHaveProperty('baz')
->and($this->baz) ->and($this->baz)
->toBe(2); ->toBe(2);
$this->baz = 3;
});
test('global beforeEach execution order', function () {
expect($this)
->toHaveProperty('baz')
->and($this->baz)
->toBe(3);
}); });

View File

@ -33,6 +33,41 @@ uses()
}) })
->in('Hooks'); ->in('Hooks');
uses()
->beforeEach(function () {
expect($this)
->toHaveProperty('baz')
->and($this->baz)
->toBe(0);
$this->baz = 1;
})
->beforeAll(function () {
expect($_SERVER['globalHook'])
->toHaveProperty('beforeAll')
->and($_SERVER['globalHook']->beforeAll)
->toBe(0);
$_SERVER['globalHook']->beforeAll = 1;
})
->afterEach(function () {
expect($this)
->toHaveProperty('ith')
->and($this->ith)
->toBe(0);
$this->ith = 1;
})
->afterAll(function () {
expect($_SERVER['globalHook'])
->toHaveProperty('afterAll')
->and($_SERVER['globalHook']->afterAll)
->toBe(0);
$_SERVER['globalHook']->afterAll = 1;
})
->in('Hooks');
function helper_returns_string() function helper_returns_string()
{ {
return 'string'; return 'string';