Merge pull request #269 from jordanbrauer/multiple-suffix-extensions

fix: allow multiple file extensions in test suffix (prevent class & file name syntax errors)
This commit is contained in:
Nuno Maduro
2021-03-13 10:36:02 +00:00
committed by GitHub
11 changed files with 101 additions and 11 deletions

View File

@ -5,14 +5,17 @@ declare(strict_types=1);
namespace Pest\Factories;
use Closure;
use ParseError;
use Pest\Concerns;
use Pest\Contracts\HasPrintableTestCaseName;
use Pest\Datasets;
use Pest\Exceptions\ShouldNotHappen;
use Pest\Support\HigherOrderMessageCollection;
use Pest\Support\NullClosure;
use Pest\Support\Str;
use Pest\TestSuite;
use PHPUnit\Framework\TestCase;
use RuntimeException;
/**
* @internal
@ -168,7 +171,7 @@ final class TestCaseFactory
}, $filename);
}
$filename = (string) realpath($filename);
$filename = str_replace('\\\\', '\\', addslashes((string) realpath($filename)));
$rootPath = TestSuite::getInstance()->rootPath;
$relativePath = str_replace($rootPath . DIRECTORY_SEPARATOR, '', $filename);
$relativePath = dirname(ucfirst($relativePath)) . DIRECTORY_SEPARATOR . basename($relativePath, '.php');
@ -176,8 +179,12 @@ final class TestCaseFactory
// Strip out any %-encoded octets.
$relativePath = (string) preg_replace('|%[a-fA-F0-9][a-fA-F0-9]|', '', $relativePath);
// Remove escaped quote sequences (maintain namespace)
$relativePath = str_replace(array_map(function (string $quote): string {
return sprintf('\\%s', $quote);
}, ['\'', '"']), '', $relativePath);
// Limit to A-Z, a-z, 0-9, '_', '-'.
$relativePath = (string) preg_replace('/[^A-Za-z0-9.\\\]/', '', $relativePath);
$relativePath = (string) preg_replace('/[^A-Za-z0-9\\\\]/', '', $relativePath);
$classFQN = 'P\\' . $relativePath;
if (class_exists($classFQN)) {
@ -194,6 +201,12 @@ final class TestCaseFactory
$namespace = implode('\\', $partsFQN);
$baseClass = sprintf('\%s', $this->class);
if ('' === trim($className)) {
$className = 'InvalidTestName' . Str::random();
$classFQN .= $className;
}
try {
eval("
namespace $namespace;
@ -203,6 +216,9 @@ final class TestCaseFactory
private static \$__filename = '$filename';
}
");
} catch (ParseError $caught) {
throw new RuntimeException(sprintf('Unable to create test case for test file at %s', $filename), 1, $caught);
}
return $classFQN;
}

View File

@ -9,6 +9,25 @@ namespace Pest\Support;
*/
final class Str
{
/**
* Pool of alpha-numeric characters for generating (unsafe) random strings
* from.
*/
private const POOL = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
/**
* Create a (unsecure & non-cryptographically safe) random alpha-numeric
* string value.
*
* @param int $length the length of the resulting randomized string
*
* @see https://github.com/laravel/framework/blob/4.2/src/Illuminate/Support/Str.php#L240-L242
*/
public static function random(int $length = 16): string
{
return substr(str_shuffle(str_repeat(self::POOL, 5)), 0, $length);
}
/**
* Checks if the given `$target` starts with the given `$search`.
*/

View File

@ -103,6 +103,27 @@
PASS Tests\Fixtures\ExampleTest
✓ it example 2
PASS Tests\PHPUnit\CustomAffixes\InvalidTestName
✓ it runs file names like `@#$%^&()-_=+.php`
PASS Tests\PHPUnit\CustomAffixes\ATestWithSpaces
✓ it runs file names like `A Test With Spaces.php`
PASS Tests\PHPUnit\CustomAffixes\AdditionalFileExtensionspec
✓ it runs file names like `AdditionalFileExtension.spec.php`
PASS Tests\PHPUnit\CustomAffixes\ManyExtensionsclasstest
✓ it runs file names like `ManyExtensions.class.test.php`
PASS Tests\PHPUnit\CustomAffixes\TestCaseWithQuotes
✓ it runs file names like `Test 'Case' With Quotes.php`
PASS Tests\PHPUnit\CustomAffixes\kebabcasespec
✓ it runs file names like `kebab-case-spec.php`
PASS Tests\PHPUnit\CustomAffixes\snakecasespec
✓ it runs file names like `snake_case_spec.php`
PASS Tests\PHPUnit\CustomTestCase\UsesPerDirectory
✓ closure was bound to CustomTestCase
@ -188,5 +209,5 @@
✓ it is a test
✓ it uses correct parent class
Tests: 7 skipped, 108 passed
Tests: 7 skipped, 115 passed

View File

@ -0,0 +1,10 @@
<?php
/*
* NOTE: To preserve cross-platform testing compatibility we cannot use ! * and
* other Windows reserved characters in this test's filename.
*
* See https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions
*/
it(sprintf('runs file names like `%s`', basename(__FILE__)))->assertTrue(true);

View File

@ -0,0 +1,3 @@
<?php
it(sprintf('runs file names like `%s`', basename(__FILE__)))->assertTrue(true);

View File

@ -0,0 +1,3 @@
<?php
it(sprintf('runs file names like `%s`', basename(__FILE__)))->assertTrue(true);

View File

@ -0,0 +1,3 @@
<?php
it(sprintf('runs file names like `%s`', basename(__FILE__)))->assertTrue(true);

View File

@ -0,0 +1,3 @@
<?php
it(sprintf('runs file names like `%s`', basename(__FILE__)))->assertTrue(true);

View File

@ -0,0 +1,3 @@
<?php
it(sprintf('runs file names like `%s`', basename(__FILE__)))->assertTrue(true);

View File

@ -0,0 +1,3 @@
<?php
it(sprintf('runs file names like `%s`', basename(__FILE__)))->assertTrue(true);

View File

@ -13,7 +13,13 @@ test('visual snapshot of test suite on success', function () {
$process->run();
return preg_replace('#\\x1b[[][^A-Za-z]*[A-Za-z]#', '', $process->getOutput());
return preg_replace([
'#\\x1b[[][^A-Za-z]*[A-Za-z]#',
'/(Tests\\\PHPUnit\\\CustomAffixes\\\InvalidTestName)([A-Za-z0-9]*)/',
], [
'',
'$1',
], $process->getOutput());
};
if (getenv('REBUILD_SNAPSHOTS')) {