diff --git a/src/Concerns/TestCase.php b/src/Concerns/TestCase.php index 9581ae57..cc6a5f8d 100644 --- a/src/Concerns/TestCase.php +++ b/src/Concerns/TestCase.php @@ -55,6 +55,15 @@ trait TestCase $this->setGroups($groups); } + /** + * Add a shared/"global" before each test hook that will execute **before** + * the test defined `beforeEach` hook. + */ + public function addBeforeEach(?Closure $hook): void + { + $this->beforeEach = $hook; + } + /** * Add dependencies to the test case and map them to instances of ExecutionOrderDependency. */ @@ -121,6 +130,10 @@ trait TestCase parent::setUp(); + if ($this->beforeEach instanceof Closure) { + $this->__callClosure($this->beforeEach, func_get_args()); + } + $beforeEach = TestSuite::getInstance()->beforeEach->get(self::$__filename); $this->__callClosure($beforeEach, func_get_args()); diff --git a/src/PendingObjects/UsesCall.php b/src/PendingObjects/UsesCall.php index f9418fd5..d0b33b38 100644 --- a/src/PendingObjects/UsesCall.php +++ b/src/PendingObjects/UsesCall.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Pest\PendingObjects; +use Closure; use Pest\Exceptions\InvalidUsesPath; use Pest\TestSuite; @@ -12,6 +13,13 @@ use Pest\TestSuite; */ final class UsesCall { + /** + * Contains a global before each hook closure to be executed. + * + * @var Closure + */ + private $beforeEach; + /** * Holds the class and traits. * @@ -97,11 +105,26 @@ final class UsesCall return $this; } + /** + * Sets the global beforeEach test hook + */ + public function beforeEach(Closure $hook): UsesCall + { + $this->beforeEach = $hook; + + return $this; + } + /** * Dispatch the creation of uses. */ public function __destruct() { - TestSuite::getInstance()->tests->use($this->classAndTraits, $this->groups, $this->targets); + TestSuite::getInstance()->tests->use( + $this->classAndTraits, + $this->groups, + $this->targets, + $this->beforeEach, + ); } } diff --git a/src/Repositories/TestRepository.php b/src/Repositories/TestRepository.php index cf36319e..f8107247 100644 --- a/src/Repositories/TestRepository.php +++ b/src/Repositories/TestRepository.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Pest\Repositories; +use Closure; use Pest\Exceptions\ShouldNotHappen; use Pest\Exceptions\TestAlreadyExist; use Pest\Exceptions\TestCaseAlreadyInUse; @@ -46,8 +47,9 @@ final class TestRepository }; foreach ($this->uses as $path => $uses) { - [$classOrTraits, $groups] = $uses; - $setClassName = function (TestCaseFactory $testCase, string $key) use ($path, $classOrTraits, $groups, $startsWith): void { + [$classOrTraits, $groups, $beforeEach] = $uses; + + $setClassName = function (TestCaseFactory $testCase, string $key) use ($path, $classOrTraits, $groups, $startsWith, $beforeEach): void { [$filename] = explode('@', $key); if ((!is_dir($path) && $filename === $path) || (is_dir($path) && $startsWith($filename, $path))) { @@ -62,10 +64,9 @@ final class TestRepository } } - $testCase - ->factoryProxies - // Consider set the real line here. - ->add($filename, 0, 'addGroups', [$groups]); + // IDEA: Consider set the real lines on these. + $testCase->factoryProxies->add($filename, 0, 'addBeforeEach', [$beforeEach]); + $testCase->factoryProxies->add($filename, 0, 'addGroups', [$groups]); } }; @@ -81,7 +82,7 @@ final class TestRepository $state = count($onlyState) > 0 ? $onlyState : $this->state; foreach ($state as $testFactory) { - /* @var TestCaseFactory $testFactory */ + /** @var TestCaseFactory $testFactory */ $tests = $testFactory->build($testSuite); foreach ($tests as $test) { $each($test); @@ -95,8 +96,9 @@ final class TestRepository * @param array $classOrTraits * @param array $groups * @param array $paths + * @param Closure|null $beforeEach */ - public function use(array $classOrTraits, array $groups, array $paths): void + public function use(array $classOrTraits, array $groups, array $paths, ?Closure $beforeEach): void { foreach ($classOrTraits as $classOrTrait) { if (!class_exists($classOrTrait) && !trait_exists($classOrTrait)) { @@ -109,9 +111,10 @@ final class TestRepository $this->uses[$path] = [ array_merge($this->uses[$path][0], $classOrTraits), array_merge($this->uses[$path][1], $groups), + $this->uses[$path][2] ?? $beforeEach, ]; } else { - $this->uses[$path] = [$classOrTraits, $groups]; + $this->uses[$path] = [$classOrTraits, $groups, $beforeEach]; } } }