Skip to content

Commit

Permalink
Fix --exclude-filter CLI option
Browse files Browse the repository at this point in the history
Co-authored-by: Sebastian Bergmann <sb@sebastian-bergmann.de>
Co-authored-by: Arne Blankerts <Arne@Blankerts.de>
Co-authored-by: Andreas Möller <am@localheinz.com>
Co-authored-by: Sebastian Heuer <sebastian@phpeople.de>
Co-authored-by: Fabian Blechschmidt <blechschmidt@fabian-blechschmidt.de>
Co-authored-by: Frank Sons <frank.sons@code-quality.de>
  • Loading branch information
6 people committed Mar 8, 2024
1 parent 400a39a commit 697b867
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 101 deletions.
7 changes: 7 additions & 0 deletions ChangeLog-11.0.md
Expand Up @@ -2,6 +2,12 @@

All notable changes of the PHPUnit 11.0 release series are documented in this file using the [Keep a CHANGELOG](https://keepachangelog.com/) principles.

## [11.0.5] - 2024-MM-DD

### Fixed

* `--exclude-filter` CLI option does not work

## [11.0.4] - 2024-02-29

### Fixed
Expand Down Expand Up @@ -105,6 +111,7 @@ All notable changes of the PHPUnit 11.0 release series are documented in this fi
* `PHPUnit\TextUI\Configuration\Configuration::registerMockObjectsFromTestArgumentsRecursively()`
* `PHPUnit\Framework\Constraint\Constraint::exporter()`

[11.0.5]: https://github.com/sebastianbergmann/phpunit/compare/11.0.4...11.0
[11.0.4]: https://github.com/sebastianbergmann/phpunit/compare/11.0.3...11.0.4
[11.0.3]: https://github.com/sebastianbergmann/phpunit/compare/11.0.2...11.0.3
[11.0.2]: https://github.com/sebastianbergmann/phpunit/compare/11.0.1...11.0.2
Expand Down
28 changes: 2 additions & 26 deletions src/Runner/Filter/ExcludeNameFilterIterator.php
Expand Up @@ -9,37 +9,13 @@
*/
namespace PHPUnit\Runner\Filter;

use function preg_match;
use function sprintf;
use function str_replace;

/**
* @internal This class is not covered by the backward compatibility promise for PHPUnit
*/
final class ExcludeNameFilterIterator extends NameFilterIterator
{
/**
* @psalm-param non-empty-string $filter
*
* @psalm-return array{regularExpression: non-empty-string, dataSetMinimum: ?int, dataSetMaximum: ?int}
*/
protected function prepareFilter(string $filter): array
protected function doAccept(bool $result): bool
{
if (@preg_match($filter, '') === false) {
$filter = sprintf(
'/^(?:(?!%s).)*/i',
str_replace(
'/',
'\\/',
$filter,
),
);
}

return [
'regularExpression' => $filter,
'dataSetMinimum' => null,
'dataSetMaximum' => null,
];
return !$result;
}
}
63 changes: 2 additions & 61 deletions src/Runner/Filter/IncludeNameFilterIterator.php
Expand Up @@ -9,72 +9,13 @@
*/
namespace PHPUnit\Runner\Filter;

use function preg_match;
use function sprintf;
use function str_replace;

/**
* @internal This class is not covered by the backward compatibility promise for PHPUnit
*/
final class IncludeNameFilterIterator extends NameFilterIterator
{
/**
* @psalm-param non-empty-string $filter
*
* @psalm-return array{regularExpression: non-empty-string, dataSetMinimum: ?int, dataSetMaximum: ?int}
*/
protected function prepareFilter(string $filter): array
protected function doAccept(bool $result): bool
{
$dataSetMinimum = null;
$dataSetMaximum = null;

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],
);

$dataSetMinimum = (int) $matches[2];
$dataSetMaximum = (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,
),
);
}

return [
'regularExpression' => $filter,
'dataSetMinimum' => $dataSetMinimum,
'dataSetMaximum' => $dataSetMaximum,
];
return $result;
}
}
65 changes: 61 additions & 4 deletions src/Runner/Filter/NameFilterIterator.php
Expand Up @@ -11,9 +11,11 @@

use function end;
use function preg_match;
use function sprintf;
use function str_replace;
use PHPUnit\Framework\Test;
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\TestSuite;
use PHPUnit\Runner\PhptTestCase;
use RecursiveFilterIterator;
use RecursiveIterator;

Expand Down Expand Up @@ -60,7 +62,7 @@ public function accept(): bool
return true;
}

if (!$test instanceof TestCase) {
if ($test instanceof PhptTestCase) {
return false;
}

Expand All @@ -73,13 +75,68 @@ public function accept(): bool
$accepted = $set >= $this->dataSetMinimum && $set <= $this->dataSetMaximum;
}

return $accepted;
return $this->doAccept($accepted);
}

abstract protected function doAccept(bool $result): bool;

/**
* @psalm-param non-empty-string $filter
*
* @psalm-return array{regularExpression: non-empty-string, dataSetMinimum: ?int, dataSetMaximum: ?int}
*/
abstract protected function prepareFilter(string $filter): array;
private function prepareFilter(string $filter): array
{
$dataSetMinimum = null;
$dataSetMaximum = null;

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],
);

$dataSetMinimum = (int) $matches[2];
$dataSetMaximum = (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,
),
);
}

return [
'regularExpression' => $filter,
'dataSetMinimum' => $dataSetMinimum,
'dataSetMaximum' => $dataSetMaximum,
];
}
}
16 changes: 6 additions & 10 deletions tests/end-to-end/cli/exclude-filter/match.phpt
@@ -1,5 +1,5 @@
--TEST--
phpunit --exclude-filter one tests/FooTest.php
phpunit --exclude-filter testThree ../../_files/groups/tests/FooTest.php
--FILE--
<?php declare(strict_types=1);
$traceFile = tempnam(sys_get_temp_dir(), __FILE__);
Expand All @@ -10,7 +10,7 @@ $_SERVER['argv'][] = '--no-output';
$_SERVER['argv'][] = '--log-events-text';
$_SERVER['argv'][] = $traceFile;
$_SERVER['argv'][] = '--exclude-filter';
$_SERVER['argv'][] = 'testone';
$_SERVER['argv'][] = 'testThree';
$_SERVER['argv'][] = __DIR__ . '/../../_files/groups/tests/FooTest.php';

require_once __DIR__ . '/../../../bootstrap.php';
Expand All @@ -27,9 +27,9 @@ Test Suite Loaded (3 tests)
Event Facade Sealed
Test Runner Started
Test Suite Sorted
Test Suite Filtered (3 tests)
Test Runner Execution Started (3 tests)
Test Suite Started (PHPUnit\TestFixture\Groups\FooTest, 3 tests)
Test Suite Filtered (2 tests)
Test Runner Execution Started (2 tests)
Test Suite Started (PHPUnit\TestFixture\Groups\FooTest, 2 tests)
Test Preparation Started (PHPUnit\TestFixture\Groups\FooTest::testOne)
Test Prepared (PHPUnit\TestFixture\Groups\FooTest::testOne)
Test Passed (PHPUnit\TestFixture\Groups\FooTest::testOne)
Expand All @@ -38,11 +38,7 @@ Test Preparation Started (PHPUnit\TestFixture\Groups\FooTest::testTwo)
Test Prepared (PHPUnit\TestFixture\Groups\FooTest::testTwo)
Test Passed (PHPUnit\TestFixture\Groups\FooTest::testTwo)
Test Finished (PHPUnit\TestFixture\Groups\FooTest::testTwo)
Test Preparation Started (PHPUnit\TestFixture\Groups\FooTest::testThree)
Test Prepared (PHPUnit\TestFixture\Groups\FooTest::testThree)
Test Passed (PHPUnit\TestFixture\Groups\FooTest::testThree)
Test Finished (PHPUnit\TestFixture\Groups\FooTest::testThree)
Test Suite Finished (PHPUnit\TestFixture\Groups\FooTest, 3 tests)
Test Suite Finished (PHPUnit\TestFixture\Groups\FooTest, 2 tests)
Test Runner Execution Finished
Test Runner Finished
PHPUnit Finished (Shell Exit Code: 0)

0 comments on commit 697b867

Please sign in to comment.