You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
3.8 KiB
140 lines
3.8 KiB
<?php declare(strict_types=1);
|
|
/*
|
|
* This file is part of PHPUnit.
|
|
*
|
|
* (c) Sebastian Bergmann <sebastian@phpunit.de>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
namespace PHPUnit\Runner\Filter;
|
|
|
|
use function end;
|
|
use function implode;
|
|
use function preg_match;
|
|
use function sprintf;
|
|
use function str_replace;
|
|
use Exception;
|
|
use PHPUnit\Framework\SelfDescribing;
|
|
use PHPUnit\Framework\Test;
|
|
use PHPUnit\Framework\TestCase;
|
|
use PHPUnit\Framework\TestSuite;
|
|
use RecursiveFilterIterator;
|
|
use RecursiveIterator;
|
|
|
|
/**
|
|
* @internal This class is not covered by the backward compatibility promise for PHPUnit
|
|
*/
|
|
final class NameFilterIterator extends RecursiveFilterIterator
|
|
{
|
|
private ?string $filter = null;
|
|
private ?int $filterMin = null;
|
|
private ?int $filterMax = null;
|
|
|
|
/**
|
|
* @psalm-param RecursiveIterator<int, Test> $iterator
|
|
* @psalm-param non-empty-string $filter
|
|
*
|
|
* @throws Exception
|
|
*/
|
|
public function __construct(RecursiveIterator $iterator, string $filter)
|
|
{
|
|
parent::__construct($iterator);
|
|
|
|
$this->setFilter($filter);
|
|
}
|
|
|
|
public function accept(): bool
|
|
{
|
|
$test = $this->getInnerIterator()->current();
|
|
|
|
if ($test instanceof TestSuite) {
|
|
return true;
|
|
}
|
|
|
|
$tmp = $this->describe($test);
|
|
|
|
if ($tmp[0] !== '') {
|
|
$name = implode('::', $tmp);
|
|
} else {
|
|
$name = $tmp[1];
|
|
}
|
|
|
|
$accepted = @preg_match($this->filter, $name, $matches);
|
|
|
|
if ($accepted && isset($this->filterMax)) {
|
|
$set = end($matches);
|
|
$accepted = $set >= $this->filterMin && $set <= $this->filterMax;
|
|
}
|
|
|
|
return (bool) $accepted;
|
|
}
|
|
|
|
/**
|
|
* @throws Exception
|
|
*/
|
|
private function setFilter(string $filter): void
|
|
{
|
|
if (@preg_match($filter, '') === false) {
|
|
// Handles:
|
|
// * testAssertEqualsSucceeds#4
|
|
// * testAssertEqualsSucceeds#4-8
|
|
if (preg_match('/^(.*?)#(\d+)(?:-(\d+))?$/', $filter, $matches)) {
|
|
if (isset($matches[3]) && $matches[2] < $matches[3]) {
|
|
$filter = sprintf(
|
|
'%s.*with data set #(\d+)$',
|
|
$matches[1],
|
|
);
|
|
|
|
$this->filterMin = (int) $matches[2];
|
|
$this->filterMax = (int) $matches[3];
|
|
} else {
|
|
$filter = sprintf(
|
|
'%s.*with data set #%s$',
|
|
$matches[1],
|
|
$matches[2],
|
|
);
|
|
}
|
|
} // Handles:
|
|
// * testDetermineJsonError@JSON_ERROR_NONE
|
|
// * testDetermineJsonError@JSON.*
|
|
elseif (preg_match('/^(.*?)@(.+)$/', $filter, $matches)) {
|
|
$filter = sprintf(
|
|
'%s.*with data set "%s"$',
|
|
$matches[1],
|
|
$matches[2],
|
|
);
|
|
}
|
|
|
|
// Escape delimiters in regular expression. Do NOT use preg_quote,
|
|
// to keep magic characters.
|
|
$filter = sprintf(
|
|
'/%s/i',
|
|
str_replace(
|
|
'/',
|
|
'\\/',
|
|
$filter,
|
|
),
|
|
);
|
|
}
|
|
|
|
$this->filter = $filter;
|
|
}
|
|
|
|
/**
|
|
* @psalm-return array{0: string, 1: string}
|
|
*/
|
|
private function describe(Test $test): array
|
|
{
|
|
if ($test instanceof TestCase) {
|
|
return [$test::class, $test->nameWithDataSet()];
|
|
}
|
|
|
|
if ($test instanceof SelfDescribing) {
|
|
return ['', $test->toString()];
|
|
}
|
|
|
|
return ['', $test::class];
|
|
}
|
|
}
|