File: /var/www/admin.fixgini.com/vendor/pestphp/pest/src/Repositories/TestRepository.php
<?php
declare(strict_types=1);
namespace Pest\Repositories;
use Closure;
use Pest\Contracts\TestCaseFilter;
use Pest\Contracts\TestCaseMethodFilter;
use Pest\Exceptions\TestCaseAlreadyInUse;
use Pest\Exceptions\TestCaseClassOrTraitNotFound;
use Pest\Factories\Attribute;
use Pest\Factories\TestCaseFactory;
use Pest\Factories\TestCaseMethodFactory;
use Pest\Support\Str;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\TestCase;
/**
* @internal
*/
final class TestRepository
{
/**
* @var array<string, TestCaseFactory>
*/
private array $testCases = [];
/**
* @var array<string, array{0: array<int, string>, 1: array<int, string>, 2: array<int, array<int, string|Closure>>}>
*/
private array $uses = [];
/**
* @var array<int, TestCaseFilter>
*/
private array $testCaseFilters = [];
/**
* @var array<int, TestCaseMethodFilter>
*/
private array $testCaseMethodFilters = [];
/**
* Counts the number of test cases.
*/
public function count(): int
{
return count($this->testCases);
}
/**
* Returns the filename of each test that should be executed in the suite.
*
* @return array<int, string>
*/
public function getFilenames(): array
{
return array_values(array_map(static fn (TestCaseFactory $factory): string => $factory->filename, $this->testCases));
}
/**
* Uses the given `$testCaseClass` on the given `$paths`.
*
* @param array<int, string> $classOrTraits
* @param array<int, string> $groups
* @param array<int, string> $paths
* @param array<int, Closure> $hooks
*/
public function use(array $classOrTraits, array $groups, array $paths, array $hooks): void
{
foreach ($classOrTraits as $classOrTrait) {
if (class_exists($classOrTrait)) {
continue;
}
if (trait_exists($classOrTrait)) {
continue;
}
throw new TestCaseClassOrTraitNotFound($classOrTrait);
}
$hooks = array_map(fn (Closure $hook): array => [$hook], $hooks);
foreach ($paths as $path) {
if (array_key_exists($path, $this->uses)) {
$this->uses[$path] = [
[...$this->uses[$path][0], ...$classOrTraits],
[...$this->uses[$path][1], ...$groups],
array_map(
fn (int $index): array => [...$this->uses[$path][2][$index] ?? [], ...($hooks[$index] ?? [])],
range(0, 3),
),
];
} else {
$this->uses[$path] = [$classOrTraits, $groups, $hooks];
}
}
}
/**
* Filters the test cases using the given filter.
*/
public function addTestCaseFilter(TestCaseFilter $filter): void
{
$this->testCaseFilters[] = $filter;
}
/**
* Filters the test cases using the given filter.
*/
public function addTestCaseMethodFilter(TestCaseMethodFilter $filter): void
{
$this->testCaseMethodFilters[] = $filter;
}
/**
* Gets the test case factory from the given filename.
*/
public function get(string $filename): ?TestCaseFactory
{
return $this->testCases[$filename] ?? null;
}
/**
* Sets a new test case method.
*/
public function set(TestCaseMethodFactory $method): void
{
foreach ($this->testCaseFilters as $filter) {
if (! $filter->accept($method->filename)) {
return;
}
}
foreach ($this->testCaseMethodFilters as $filter) {
if (! $filter->accept($method)) {
return;
}
}
if (! array_key_exists($method->filename, $this->testCases)) {
$this->testCases[$method->filename] = new TestCaseFactory($method->filename);
}
$this->testCases[$method->filename]->addMethod($method);
}
/**
* Makes a Test Case from the given filename, if exists.
*/
public function makeIfNeeded(string $filename): void
{
if (! array_key_exists($filename, $this->testCases)) {
return;
}
foreach ($this->testCaseFilters as $filter) {
if (! $filter->accept($filename)) {
return;
}
}
$this->make($this->testCases[$filename]);
}
/**
* Makes a Test Case using the given factory.
*/
private function make(TestCaseFactory $testCase): void
{
$startsWith = static fn (string $target, string $directory): bool => Str::startsWith($target, $directory.DIRECTORY_SEPARATOR);
foreach ($this->uses as $path => $uses) {
[$classOrTraits, $groups, $hooks] = $uses;
if ((! is_dir($path) && $testCase->filename === $path) || (is_dir($path) && $startsWith($testCase->filename, $path))) {
foreach ($classOrTraits as $class) {
/** @var string $class */
if (class_exists($class)) {
if ($testCase->class !== TestCase::class) {
throw new TestCaseAlreadyInUse($testCase->class, $class, $testCase->filename);
}
$testCase->class = $class;
} elseif (trait_exists($class)) {
$testCase->traits[] = $class;
}
}
foreach ($testCase->methods as $method) {
foreach ($groups as $group) {
$method->attributes[] = new Attribute(
Group::class,
[$group],
);
}
}
foreach ($testCase->methods as $method) {
$method->groups = [...$groups, ...$method->groups];
}
foreach (['__addBeforeAll', '__addBeforeEach', '__addAfterEach', '__addAfterAll'] as $index => $name) {
foreach ($hooks[$index] ?? [null] as $hook) {
$testCase->factoryProxies->add($testCase->filename, 0, $name, [$hook]);
}
}
}
}
$testCase->make();
}
}