google_forms/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/TestCase.php

237 lines
6.4 KiB
PHP

<?php declare(strict_types = 1);
namespace SlevomatCodingStandard\Sniffs;
use PHP_CodeSniffer\Config;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Files\LocalFile;
use PHP_CodeSniffer\Runner;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Util\Common;
use ReflectionClass;
use function array_map;
use function array_merge;
use function count;
use function define;
use function defined;
use function implode;
use function in_array;
use function preg_replace;
use function sprintf;
use function strlen;
use function strpos;
use function substr;
use function version_compare;
use const PHP_EOL;
/**
* @codeCoverageIgnore
*/
abstract class TestCase extends \PHPUnit\Framework\TestCase
{
/**
* @param array<string, string|int|bool|array<int|string, (string|int|bool|null)>> $sniffProperties
* @param list<string> $codesToCheck
* @param list<string> $cliArgs
*/
protected static function checkFile(string $filePath, array $sniffProperties = [], array $codesToCheck = [], array $cliArgs = []): File
{
if (defined('PHP_CODESNIFFER_CBF') === false) {
define('PHP_CODESNIFFER_CBF', false);
}
$codeSniffer = new Runner();
$codeSniffer->config = new Config(array_merge(['-s'], $cliArgs));
$codeSniffer->init();
if (count($sniffProperties) > 0) {
/** @phpstan-ignore-next-line */
if (version_compare(Config::VERSION, '3.8.0', '>=')) {
foreach ($sniffProperties as $name => $value) {
$sniffProperties[$name] = [
'value' => $value,
'scope' => 'sniff',
];
}
}
$codeSniffer->ruleset->ruleset[self::getSniffName()]['properties'] = $sniffProperties;
}
$sniffClassName = static::getSniffClassName();
/** @var Sniff $sniff */
$sniff = new $sniffClassName();
$codeSniffer->ruleset->sniffs = [$sniffClassName => $sniff];
if (count($codesToCheck) > 0) {
foreach (self::getSniffClassReflection()->getConstants() as $constantName => $constantValue) {
if (strpos($constantName, 'CODE_') !== 0 || in_array($constantValue, $codesToCheck, true)) {
continue;
}
$codeSniffer->ruleset->ruleset[sprintf('%s.%s', self::getSniffName(), $constantValue)]['severity'] = 0;
}
}
$codeSniffer->ruleset->populateTokenListeners();
$file = new LocalFile($filePath, $codeSniffer->ruleset, $codeSniffer->config);
$file->process();
return $file;
}
protected static function assertNoSniffErrorInFile(File $phpcsFile): void
{
$errors = $phpcsFile->getErrors();
self::assertEmpty($errors, sprintf('No errors expected, but %d errors found.', count($errors)));
}
protected static function assertNoSniffWarningInFile(File $phpcsFile): void
{
$warnings = $phpcsFile->getWarnings();
self::assertEmpty($warnings, sprintf('No warnings expected, but %d warnings found.', count($warnings)));
}
protected static function assertSniffError(File $phpcsFile, int $line, string $code, ?string $message = null): void
{
$errors = $phpcsFile->getErrors();
self::assertTrue(isset($errors[$line]), sprintf('Expected error on line %s, but none found.', $line));
$sniffCode = sprintf('%s.%s', self::getSniffName(), $code);
self::assertTrue(
self::hasError($errors[$line], $sniffCode, $message),
sprintf(
'Expected error %s%s, but none found on line %d.%sErrors found on line %d:%s%s%s',
$sniffCode,
$message !== null
? sprintf(' with message "%s"', $message)
: '',
$line,
PHP_EOL . PHP_EOL,
$line,
PHP_EOL,
self::getFormattedErrors($errors[$line]),
PHP_EOL
)
);
}
protected static function assertSniffWarning(File $phpcsFile, int $line, string $code, ?string $message = null): void
{
$errors = $phpcsFile->getWarnings();
self::assertTrue(isset($errors[$line]), sprintf('Expected warning on line %s, but none found.', $line));
$sniffCode = sprintf('%s.%s', self::getSniffName(), $code);
self::assertTrue(
self::hasError($errors[$line], $sniffCode, $message),
sprintf(
'Expected warning %s%s, but none found on line %d.%sWarnings found on line %d:%s%s%s',
$sniffCode,
$message !== null
? sprintf(' with message "%s"', $message)
: '',
$line,
PHP_EOL . PHP_EOL,
$line,
PHP_EOL,
self::getFormattedErrors($errors[$line]),
PHP_EOL
)
);
}
protected static function assertNoSniffError(File $phpcsFile, int $line): void
{
$errors = $phpcsFile->getErrors();
self::assertFalse(
isset($errors[$line]),
sprintf(
'Expected no error on line %s, but found:%s%s%s',
$line,
PHP_EOL . PHP_EOL,
isset($errors[$line]) ? self::getFormattedErrors($errors[$line]) : '',
PHP_EOL
)
);
}
protected static function assertAllFixedInFile(File $phpcsFile): void
{
$phpcsFile->disableCaching();
$phpcsFile->fixer->fixFile();
self::assertStringEqualsFile(preg_replace('~(\\.php)$~', '.fixed\\1', $phpcsFile->getFilename()), $phpcsFile->fixer->getContents());
}
/**
* @return class-string
*/
protected static function getSniffClassName(): string
{
/** @var class-string $sniffClassName */
$sniffClassName = substr(static::class, 0, -strlen('Test'));
return $sniffClassName;
}
protected static function getSniffName(): string
{
return Common::getSniffCode(static::getSniffClassName());
}
private static function getSniffClassReflection(): ReflectionClass
{
static $reflections = [];
$className = static::getSniffClassName();
return $reflections[$className] ?? $reflections[$className] = new ReflectionClass($className);
}
/**
* @param list<list<array{source: string, message: string}>> $errorsOnLine
*/
private static function hasError(array $errorsOnLine, string $sniffCode, ?string $message): bool
{
$hasError = false;
foreach ($errorsOnLine as $errorsOnPosition) {
foreach ($errorsOnPosition as $error) {
/** @var string $errorSource */
$errorSource = $error['source'];
/** @var string $errorMessage */
$errorMessage = $error['message'];
if (
$errorSource === $sniffCode
&& (
$message === null
|| strpos($errorMessage, $message) !== false
)
) {
$hasError = true;
break;
}
}
}
return $hasError;
}
/**
* @param list<list<array{source: string, message: string}>> $errors
*/
private static function getFormattedErrors(array $errors): string
{
return implode(PHP_EOL, array_map(static function (array $errors): string {
return implode(PHP_EOL, array_map(static function (array $error): string {
return sprintf("\t%s: %s", $error['source'], $error['message']);
}, $errors));
}, $errors));
}
}