init
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
/**
|
||||
* Config class for use in the tests.
|
||||
*
|
||||
* The Config class contains a number of static properties.
|
||||
* As the value of these static properties will be retained between instantiations of the class,
|
||||
* config values set in one test can influence the results for another test, which makes tests unstable.
|
||||
*
|
||||
* This class is a "double" of the Config class which prevents this from happening.
|
||||
* In _most_ cases, tests should be using this class instead of the "normal" Config,
|
||||
* with the exception of select tests for the Config class itself.
|
||||
*
|
||||
* @author Juliette Reinders Folmer <phpcs_nospam@adviesenzo.nl>
|
||||
* @copyright 2023 PHPCSStandards and contributors
|
||||
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/HEAD/licence.txt BSD Licence
|
||||
*/
|
||||
|
||||
namespace PHP_CodeSniffer\Tests;
|
||||
|
||||
use PHP_CodeSniffer\Config;
|
||||
use ReflectionProperty;
|
||||
|
||||
final class ConfigDouble extends Config
|
||||
{
|
||||
|
||||
/**
|
||||
* Whether or not the setting of a standard should be skipped.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $skipSettingStandard = false;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a clean Config object and populates it with command line values.
|
||||
*
|
||||
* @param array<string> $cliArgs An array of values gathered from CLI args.
|
||||
* @param bool $skipSettingStandard Whether to skip setting a standard to prevent
|
||||
* the Config class trying to auto-discover a ruleset file.
|
||||
* Should only be set to `true` for tests which actually test
|
||||
* the ruleset auto-discovery.
|
||||
* Note: there is no need to set this to `true` when a standard
|
||||
* is being passed via the `$cliArgs`. Those settings will always
|
||||
* be respected.
|
||||
* Defaults to `false`. Will result in the standard being set
|
||||
* to "PSR1" if not provided via `$cliArgs`.
|
||||
* @param bool $skipSettingReportWidth Whether to skip setting a report-width to prevent
|
||||
* the Config class trying to auto-discover the screen width.
|
||||
* Should only be set to `true` for tests which actually test
|
||||
* the screen width auto-discovery.
|
||||
* Note: there is no need to set this to `true` when a report-width
|
||||
* is being passed via the `$cliArgs`. Those settings will always
|
||||
* respected.
|
||||
* Defaults to `false`. Will result in the reportWidth being set
|
||||
* to "80" if not provided via `$cliArgs`.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(array $cliArgs = [], bool $skipSettingStandard = false, bool $skipSettingReportWidth = false)
|
||||
{
|
||||
$this->skipSettingStandard = $skipSettingStandard;
|
||||
|
||||
$this->resetSelectProperties();
|
||||
$this->preventReadingCodeSnifferConfFile();
|
||||
|
||||
parent::__construct($cliArgs);
|
||||
|
||||
if ($skipSettingReportWidth !== true) {
|
||||
$this->preventAutoDiscoveryScreenWidth();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ensures the static properties in the Config class are reset to their default values
|
||||
* when the ConfigDouble is no longer used.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
$this->setStaticConfigProperty('executablePaths', []);
|
||||
$this->setStaticConfigProperty('configData', null);
|
||||
$this->setStaticConfigProperty('configDataFile', null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the command line values and optionally prevents a file system search for a custom ruleset.
|
||||
*
|
||||
* @param array<string> $args An array of command line arguments to set.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCommandLineValues($args)
|
||||
{
|
||||
parent::setCommandLineValues($args);
|
||||
|
||||
if ($this->skipSettingStandard !== true) {
|
||||
$this->preventSearchingForRuleset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reset select properties on the Config class to their default values.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function resetSelectProperties()
|
||||
{
|
||||
$this->setStaticConfigProperty('executablePaths', []);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prevent the values in a potentially available user-specific `CodeSniffer.conf` file
|
||||
* from influencing the tests.
|
||||
*
|
||||
* This also prevents some file system calls which can influence the test runtime.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function preventReadingCodeSnifferConfFile()
|
||||
{
|
||||
$this->setStaticConfigProperty('configData', []);
|
||||
$this->setStaticConfigProperty('configDataFile', '');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prevent searching for a custom ruleset by setting a standard, but only if the test
|
||||
* being run doesn't set a standard itself.
|
||||
*
|
||||
* This also prevents some file system calls which can influence the test runtime.
|
||||
*
|
||||
* The standard being set is the smallest one available so the ruleset initialization
|
||||
* will be the fastest possible.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function preventSearchingForRuleset()
|
||||
{
|
||||
$overriddenDefaults = $this->getStaticConfigProperty('overriddenDefaults');
|
||||
if (isset($overriddenDefaults['standards']) === false) {
|
||||
$this->standards = ['PSR1'];
|
||||
$overriddenDefaults['standards'] = true;
|
||||
}
|
||||
|
||||
self::setStaticConfigProperty('overriddenDefaults', $overriddenDefaults);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prevent a call to stty to figure out the screen width, but only if the test being run
|
||||
* doesn't set a report width itself.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function preventAutoDiscoveryScreenWidth()
|
||||
{
|
||||
$settings = $this->getSettings();
|
||||
if ($settings['reportWidth'] === 'auto') {
|
||||
$this->reportWidth = self::DEFAULT_REPORT_WIDTH;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to retrieve the value of a private static property on the Config class.
|
||||
*
|
||||
* @param string $name The name of the property to retrieve.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function getStaticConfigProperty(string $name)
|
||||
{
|
||||
$property = new ReflectionProperty(Config::class, $name);
|
||||
(PHP_VERSION_ID < 80100) && $property->setAccessible(true);
|
||||
|
||||
if ($name === 'overriddenDefaults') {
|
||||
return $property->getValue($this);
|
||||
}
|
||||
|
||||
return $property->getValue();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to set the value of a private static property on the Config class.
|
||||
*
|
||||
* @param string $name The name of the property to set.
|
||||
* @param mixed $value The value to set the property to.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function setStaticConfigProperty(string $name, $value)
|
||||
{
|
||||
$property = new ReflectionProperty(Config::class, $name);
|
||||
(PHP_VERSION_ID < 80100) && $property->setAccessible(true);
|
||||
|
||||
if ($name === 'overriddenDefaults') {
|
||||
$property->setValue($this, $value);
|
||||
} else {
|
||||
$property->setValue(null, $value);
|
||||
}
|
||||
|
||||
(PHP_VERSION_ID < 80100) && $property->setAccessible(false);
|
||||
}
|
||||
}
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
/**
|
||||
* Base class to use when testing utility methods.
|
||||
*
|
||||
* @author Juliette Reinders Folmer <phpcs_nospam@adviesenzo.nl>
|
||||
* @copyright 2018-2019 Juliette Reinders Folmer. All rights reserved.
|
||||
* @copyright 2023 PHPCSStandards and contributors
|
||||
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/HEAD/licence.txt BSD Licence
|
||||
*/
|
||||
|
||||
namespace PHP_CodeSniffer\Tests\Core;
|
||||
|
||||
use Exception;
|
||||
use PHP_CodeSniffer\Exceptions\RuntimeException;
|
||||
use PHP_CodeSniffer\Files\File;
|
||||
use PHP_CodeSniffer\Files\LocalFile;
|
||||
use PHP_CodeSniffer\Ruleset;
|
||||
use PHP_CodeSniffer\Tests\ConfigDouble;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
abstract class AbstractMethodTestCase extends TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* The tab width setting to use when tokenizing the file.
|
||||
*
|
||||
* This allows for test case files to use a different tab width than the default.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected static $tabWidth = 4;
|
||||
|
||||
/**
|
||||
* The \PHP_CodeSniffer\Files\File object containing the parsed contents of the test case file.
|
||||
*
|
||||
* @var \PHP_CodeSniffer\Files\File
|
||||
*/
|
||||
protected static $phpcsFile;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize & tokenize \PHP_CodeSniffer\Files\File with code from the test case file.
|
||||
*
|
||||
* The test case file for a unit test class has to be in the same directory
|
||||
* directory and use the same file name as the test class, using the .inc extension.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
$_SERVER['argv'] = [];
|
||||
$config = new ConfigDouble();
|
||||
// Also set a tab-width to enable testing tab-replaced vs `orig_content`.
|
||||
$config->tabWidth = static::$tabWidth;
|
||||
|
||||
$ruleset = new Ruleset($config);
|
||||
|
||||
// Default to a file with the same name as the test class. Extension is property based.
|
||||
$relativeCN = str_replace(__NAMESPACE__, '', static::class);
|
||||
$relativePath = str_replace('\\', DIRECTORY_SEPARATOR, $relativeCN);
|
||||
$pathToTestFile = realpath(__DIR__) . $relativePath . '.inc';
|
||||
|
||||
self::$phpcsFile = new LocalFile($pathToTestFile, $ruleset, $config);
|
||||
self::$phpcsFile->parse();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clean up after finished test by resetting all static properties on the class to their default values.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function tearDownAfterClass(): void
|
||||
{
|
||||
// Explicitly trigger __destruct() on the ConfigDouble to reset the Config statics.
|
||||
// The explicit method call prevents potential stray test-local references to the $config object
|
||||
// preventing the destructor from running the clean up (which without stray references would be
|
||||
// automagically triggered when `self::$phpcsFile` is reset, but we can't definitively rely on that).
|
||||
if (isset(self::$phpcsFile) === true) {
|
||||
self::$phpcsFile->config->__destruct();
|
||||
}
|
||||
|
||||
self::$tabWidth = 4;
|
||||
self::$phpcsFile = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test QA: verify that a test case file does not contain any duplicate test markers.
|
||||
*
|
||||
* When a test case file contains a lot of test cases, it is easy to overlook that a test marker name
|
||||
* is already in use.
|
||||
* A test wouldn't necessarily fail on this, but would not be testing what is intended to be tested as
|
||||
* it would be verifying token properties for the wrong token.
|
||||
*
|
||||
* This test safeguards against this.
|
||||
*
|
||||
* @coversNothing
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testTestMarkersAreUnique()
|
||||
{
|
||||
$this->assertTestMarkersAreUnique(self::$phpcsFile);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Assertion to verify that a test case file does not contain any duplicate test markers.
|
||||
*
|
||||
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file to validate.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function assertTestMarkersAreUnique(File $phpcsFile)
|
||||
{
|
||||
$tokens = $phpcsFile->getTokens();
|
||||
|
||||
// Collect all marker comments in the file.
|
||||
$seenComments = [];
|
||||
for ($i = 0; $i < $phpcsFile->numTokens; $i++) {
|
||||
if ($tokens[$i]['code'] !== T_COMMENT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (stripos($tokens[$i]['content'], '/* test') !== 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$seenComments[] = $tokens[$i]['content'];
|
||||
}
|
||||
|
||||
self::assertSame(array_unique($seenComments), $seenComments, 'Duplicate test markers found.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the token pointer for a target token based on a specific comment found on the line before.
|
||||
*
|
||||
* Note: the test delimiter comment MUST start with "/* test" to allow this function to
|
||||
* distinguish between comments used *in* a test and test delimiters.
|
||||
*
|
||||
* @param string $commentString The delimiter comment to look for.
|
||||
* @param int|string|array<int|string> $tokenType The type of token(s) to look for.
|
||||
* @param string $tokenContent Optional. The token content for the target token.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getTargetToken($commentString, $tokenType, $tokenContent = null)
|
||||
{
|
||||
return self::getTargetTokenFromFile(self::$phpcsFile, $commentString, $tokenType, $tokenContent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the token pointer for a target token based on a specific comment found on the line before.
|
||||
*
|
||||
* Note: the test delimiter comment MUST start with "/* test" to allow this function to
|
||||
* distinguish between comments used *in* a test and test delimiters.
|
||||
*
|
||||
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file to find the token in.
|
||||
* @param string $commentString The delimiter comment to look for.
|
||||
* @param int|string|array<int|string> $tokenType The type of token(s) to look for.
|
||||
* @param string $tokenContent Optional. The token content for the target token.
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @throws \Exception When the test delimiter comment is not found.
|
||||
* @throws \Exception When the test target token is not found.
|
||||
*/
|
||||
public static function getTargetTokenFromFile(File $phpcsFile, $commentString, $tokenType, $tokenContent = null)
|
||||
{
|
||||
$start = ($phpcsFile->numTokens - 1);
|
||||
$comment = $phpcsFile->findPrevious(
|
||||
T_COMMENT,
|
||||
$start,
|
||||
null,
|
||||
false,
|
||||
$commentString
|
||||
);
|
||||
|
||||
if ($comment === false) {
|
||||
throw new Exception(
|
||||
sprintf('Failed to find the test marker: %s in test case file %s', $commentString, $phpcsFile->getFilename())
|
||||
);
|
||||
}
|
||||
|
||||
$tokens = $phpcsFile->getTokens();
|
||||
$end = ($start + 1);
|
||||
|
||||
// Limit the token finding to between this and the next delimiter comment.
|
||||
for ($i = ($comment + 1); $i < $end; $i++) {
|
||||
if ($tokens[$i]['code'] !== T_COMMENT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (stripos($tokens[$i]['content'], '/* test') === 0) {
|
||||
$end = $i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$target = $phpcsFile->findNext(
|
||||
$tokenType,
|
||||
($comment + 1),
|
||||
$end,
|
||||
false,
|
||||
$tokenContent
|
||||
);
|
||||
|
||||
if ($target === false) {
|
||||
$msg = 'Failed to find test target token for comment string: ' . $commentString;
|
||||
if ($tokenContent !== null) {
|
||||
$msg .= ' with token content: ' . $tokenContent;
|
||||
}
|
||||
|
||||
throw new Exception($msg);
|
||||
}
|
||||
|
||||
return $target;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to tell PHPUnit to expect a PHPCS RuntimeException in a PHPUnit cross-version
|
||||
* compatible manner.
|
||||
*
|
||||
* @param string $message The expected exception message.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function expectRunTimeException($message)
|
||||
{
|
||||
$this->expectException(RuntimeException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function tear_down() {
|
||||
rm -f tests/EndToEnd/Fixtures/*.fixed
|
||||
}
|
||||
|
||||
function test_phpcs_exit_code_clean_file() {
|
||||
bin/phpcs --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassOneWithoutStyleError.inc
|
||||
assert_exit_code 0
|
||||
}
|
||||
function test_phpcs_exit_code_clean_stdin() {
|
||||
bin/phpcs --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist < tests/EndToEnd/Fixtures/ClassOneWithoutStyleError.inc
|
||||
assert_exit_code 0
|
||||
}
|
||||
function test_phpcbf_exit_code_clean_file() {
|
||||
bin/phpcbf --suffix=.fixed --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassOneWithoutStyleError.inc
|
||||
assert_exit_code 0
|
||||
}
|
||||
function test_phpcbf_exit_code_clean_stdin() {
|
||||
bin/phpcbf --suffix=.fixed --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist < tests/EndToEnd/Fixtures/ClassOneWithoutStyleError.inc
|
||||
assert_exit_code 0
|
||||
}
|
||||
|
||||
function test_phpcs_exit_code_fixable_file() {
|
||||
bin/phpcs --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassWithStyleError.inc
|
||||
assert_exit_code 1
|
||||
}
|
||||
function test_phpcs_exit_code_fixable_stdin() {
|
||||
bin/phpcs --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist < tests/EndToEnd/Fixtures/ClassWithStyleError.inc
|
||||
assert_exit_code 1
|
||||
}
|
||||
function test_phpcbf_exit_code_fixable_file() {
|
||||
bin/phpcbf --suffix=.fixed --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassWithStyleError.inc
|
||||
assert_exit_code 0
|
||||
}
|
||||
function test_phpcbf_exit_code_fixable_stdin() {
|
||||
bin/phpcbf --suffix=.fixed --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist < tests/EndToEnd/Fixtures/ClassWithStyleError.inc
|
||||
assert_exit_code 0
|
||||
}
|
||||
|
||||
function test_phpcs_exit_code_non_fixable_file() {
|
||||
bin/phpcs --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassWithUnfixableStyleError.inc
|
||||
assert_exit_code 2
|
||||
}
|
||||
function test_phpcs_exit_code_non_fixable_stdin() {
|
||||
bin/phpcs --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist < tests/EndToEnd/Fixtures/ClassWithUnfixableStyleError.inc
|
||||
assert_exit_code 2
|
||||
}
|
||||
function test_phpcbf_exit_code_non_fixable_file() {
|
||||
bin/phpcbf --suffix=.fixed --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassWithUnfixableStyleError.inc
|
||||
assert_exit_code 2
|
||||
}
|
||||
function test_phpcbf_exit_code_non_fixable_stdin() {
|
||||
bin/phpcbf --suffix=.fixed --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist < tests/EndToEnd/Fixtures/ClassWithUnfixableStyleError.inc
|
||||
assert_exit_code 2
|
||||
}
|
||||
|
||||
function test_phpcs_exit_code_fixable_and_non_fixable_file() {
|
||||
bin/phpcs --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassWithTwoStyleErrors.inc
|
||||
assert_exit_code 3
|
||||
}
|
||||
function test_phpcs_exit_code_fixable_and_non_fixable_stdin() {
|
||||
bin/phpcs --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist < tests/EndToEnd/Fixtures/ClassWithTwoStyleErrors.inc
|
||||
assert_exit_code 3
|
||||
}
|
||||
function test_phpcbf_exit_code_fixable_and_non_fixable_file() {
|
||||
bin/phpcbf --suffix=.fixed --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassWithTwoStyleErrors.inc
|
||||
assert_exit_code 2
|
||||
}
|
||||
function test_phpcbf_exit_code_fixable_and_non_fixable_stdin() {
|
||||
bin/phpcbf --suffix=.fixed --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist < tests/EndToEnd/Fixtures/ClassWithTwoStyleErrors.inc
|
||||
assert_exit_code 2
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function tear_down() {
|
||||
rm -f tests/EndToEnd/Fixtures/*.fixed
|
||||
}
|
||||
|
||||
function test_phpcs_out_of_memory_error_handling() {
|
||||
OUTPUT="$( { bin/phpcs -d memory_limit=4M --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/; } 2>&1)"
|
||||
# The exact exit code is not our concern, just that it's non-zero.
|
||||
assert_unsuccessful_code
|
||||
|
||||
assert_contains "The PHP_CodeSniffer \"phpcs\" command ran out of memory." "$OUTPUT"
|
||||
assert_contains "Either raise the \"memory_limit\" of PHP in the php.ini file or raise the memory limit at runtime" "$OUTPUT"
|
||||
assert_contains "using \"phpcs -d memory_limit=512M\" (replace 512M with the desired memory limit)." "$OUTPUT"
|
||||
}
|
||||
|
||||
function test_phpcbf_out_of_memory_error_handling() {
|
||||
OUTPUT="$( { bin/phpcbf -d memory_limit=4M --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ --suffix=.fixed; } 2>&1)"
|
||||
# The exact exit code is not our concern, just that it's non-zero.
|
||||
assert_unsuccessful_code
|
||||
|
||||
assert_contains "The PHP_CodeSniffer \"phpcbf\" command ran out of memory." "$OUTPUT"
|
||||
assert_contains "Either raise the \"memory_limit\" of PHP in the php.ini file or raise the memory limit at runtime" "$OUTPUT"
|
||||
assert_contains "using \"phpcbf -d memory_limit=512M\" (replace 512M with the desired memory limit)." "$OUTPUT"
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function tear_down() {
|
||||
rm -rf tests/EndToEnd/Fixtures/*.fixed
|
||||
}
|
||||
|
||||
function test_phpcbf_is_working() {
|
||||
OUTPUT="$( { bin/phpcbf --no-cache --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassOneWithoutStyleError.inc tests/EndToEnd/Fixtures/ClassTwoWithoutStyleError.inc; } 2>&1 )"
|
||||
|
||||
assert_successful_code
|
||||
assert_contains "No violations were found" "$OUTPUT"
|
||||
}
|
||||
|
||||
function test_phpcbf_is_working_in_parallel() {
|
||||
OUTPUT="$( { bin/phpcbf --no-cache --parallel=2 --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassOneWithoutStyleError.inc tests/EndToEnd/Fixtures/ClassTwoWithoutStyleError.inc; } 2>&1 )"
|
||||
|
||||
assert_successful_code
|
||||
assert_contains "No violations were found" "$OUTPUT"
|
||||
}
|
||||
|
||||
function test_phpcbf_returns_error_on_issues() {
|
||||
OUTPUT="$( { bin/phpcbf --no-colors --parallel=1 --no-cache --suffix=.fixed --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassWithStyleError.inc; } 2>&1 )"
|
||||
assert_successful_code
|
||||
|
||||
assert_contains "F 1 / 1 (100%)" "$OUTPUT"
|
||||
assert_contains "A TOTAL OF 1 ERROR WERE FIXED IN 1 FILE" "$OUTPUT"
|
||||
}
|
||||
|
||||
function test_phpcbf_progressbar_shows_fixes_with_parallel_on() {
|
||||
OUTPUT="$( { bin/phpcbf --no-colors --parallel=10 --no-cache --suffix=.fixed --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassWithStyleError.inc; } 2>&1 )"
|
||||
assert_successful_code
|
||||
|
||||
assert_contains "F 1 / 1 (100%)" "$OUTPUT"
|
||||
}
|
||||
|
||||
function test_phpcbf_bug_1112() {
|
||||
# See https://github.com/PHPCSStandards/PHP_CodeSniffer/issues/1112
|
||||
if [[ "$(uname)" == "Darwin" ]]; then
|
||||
# Perform some magic with `& fg` to prevent the processes from turning into a background job.
|
||||
assert_successful_code "$(bash -ic 'bash --init-file <(echo "echo \"Subprocess\"") -c "bin/phpcbf --no-cache --parallel=2 --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassOneWithoutStyleError.inc tests/EndToEnd/Fixtures/ClassTwoWithoutStyleError.inc" & fg')"
|
||||
else
|
||||
# This is not needed on Linux / GitHub Actions
|
||||
assert_successful_code "$(bash -ic 'bash --init-file <(echo "echo \"Subprocess\"") -c "bin/phpcbf --no-cache --parallel=2 --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassOneWithoutStyleError.inc tests/EndToEnd/Fixtures/ClassTwoWithoutStyleError.inc"')"
|
||||
fi
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function test_phpcs_is_working() {
|
||||
assert_successful_code "$(bin/phpcs --no-cache --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassOneWithoutStyleError.inc tests/EndToEnd/Fixtures/ClassTwoWithoutStyleError.inc)"
|
||||
}
|
||||
|
||||
function test_phpcs_is_working_in_parallel() {
|
||||
assert_successful_code "$(bin/phpcs --no-cache --parallel=2 --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassOneWithoutStyleError.inc tests/EndToEnd/Fixtures/ClassTwoWithoutStyleError.inc)"
|
||||
}
|
||||
|
||||
function test_phpcs_returns_error_on_issues() {
|
||||
OUTPUT="$( { bin/phpcs --no-colors --no-cache --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassWithStyleError.inc; } 2>&1 )"
|
||||
assert_exit_code 1
|
||||
|
||||
assert_contains "E 1 / 1 (100%)" "$OUTPUT"
|
||||
assert_contains "FOUND 1 ERROR AFFECTING 1 LINE" "$OUTPUT"
|
||||
}
|
||||
|
||||
function test_phpcs_bug_1112() {
|
||||
# See https://github.com/PHPCSStandards/PHP_CodeSniffer/issues/1112
|
||||
if [[ "$(uname)" == "Darwin" ]]; then
|
||||
# Perform some magic with `& fg` to prevent the processes from turning into a background job.
|
||||
assert_successful_code "$(bash -ic 'bash --init-file <(echo "echo \"Subprocess\"") -c "bin/phpcs --no-cache --parallel=2 --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassOneWithoutStyleError.inc tests/EndToEnd/Fixtures/ClassTwoWithoutStyleError.inc" & fg')"
|
||||
else
|
||||
# This is not needed on Linux / GitHub Actions
|
||||
assert_successful_code "$(bash -ic 'bash --init-file <(echo "echo \"Subprocess\"") -c "bin/phpcs --no-cache --parallel=2 --standard=tests/EndToEnd/Fixtures/endtoend.xml.dist tests/EndToEnd/Fixtures/ClassOneWithoutStyleError.inc tests/EndToEnd/Fixtures/ClassTwoWithoutStyleError.inc"')"
|
||||
fi
|
||||
}
|
||||
+470
@@ -0,0 +1,470 @@
|
||||
<?php
|
||||
/**
|
||||
* An abstract class that all sniff unit tests must extend.
|
||||
*
|
||||
* A sniff unit test checks a .inc file for expected violations of a single
|
||||
* coding standard. Expected errors and warnings that are not found, or
|
||||
* warnings and errors that are not expected, are considered test failures.
|
||||
*
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2023 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @copyright 2023 PHPCSStandards and contributors
|
||||
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/HEAD/licence.txt BSD Licence
|
||||
*/
|
||||
|
||||
namespace PHP_CodeSniffer\Tests\Standards;
|
||||
|
||||
use DirectoryIterator;
|
||||
use PHP_CodeSniffer\Config;
|
||||
use PHP_CodeSniffer\Exceptions\RuntimeException;
|
||||
use PHP_CodeSniffer\Files\LocalFile;
|
||||
use PHP_CodeSniffer\Ruleset;
|
||||
use PHP_CodeSniffer\Tests\ConfigDouble;
|
||||
use PHP_CodeSniffer\Util\Common;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ReflectionClass;
|
||||
|
||||
abstract class AbstractSniffTestCase extends TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* Ruleset template with placeholders.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private const RULESET_TEMPLATE = <<<'TEMPLATE'
|
||||
<?xml version="1.0"?>
|
||||
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="[STANDARDNAME]" xsi:noNamespaceSchemaLocation="../../phpcs.xsd">
|
||||
<description>Temporary ruleset used by the AbstractSniffUnitTest class.</description>
|
||||
|
||||
<rule ref="[SNIFFFILEREF]"/>
|
||||
|
||||
</ruleset>
|
||||
TEMPLATE;
|
||||
|
||||
/**
|
||||
* Placeholders used in the ruleset template which need to be replaced.
|
||||
*
|
||||
* @var array<string>
|
||||
*/
|
||||
private const SEARCH_FOR = [
|
||||
'[STANDARDNAME]',
|
||||
'[SNIFFFILEREF]',
|
||||
];
|
||||
|
||||
/**
|
||||
* Location where the temporary ruleset file will be saved.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private const RULESET_FILENAME = __DIR__ . '/sniffStnd.xml';
|
||||
|
||||
/**
|
||||
* Cache for the Config object.
|
||||
*
|
||||
* @var \PHP_CodeSniffer\Tests\ConfigDouble
|
||||
*/
|
||||
private static $config;
|
||||
|
||||
/**
|
||||
* Extensions to disregard when gathering the test files.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private $ignoreExtensions = [
|
||||
'php' => 'php',
|
||||
'fixed' => 'fixed',
|
||||
'bak' => 'bak',
|
||||
'orig' => 'orig',
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Clean up temporary ruleset file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function tearDownAfterClass(): void
|
||||
{
|
||||
@unlink(self::RULESET_FILENAME);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of all test files to check.
|
||||
*
|
||||
* These will have the same base as the sniff name but different extensions.
|
||||
* We ignore the .php file as it is the test class.
|
||||
*
|
||||
* @param string $testFileBase The base path that the unit tests files will have.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getTestFiles(string $testFileBase)
|
||||
{
|
||||
$testFiles = [];
|
||||
|
||||
$dir = dirname($testFileBase);
|
||||
$di = new DirectoryIterator($dir);
|
||||
|
||||
foreach ($di as $file) {
|
||||
$path = $file->getPathname();
|
||||
if (substr($path, 0, strlen($testFileBase)) === $testFileBase) {
|
||||
$extension = $file->getExtension();
|
||||
if (isset($this->ignoreExtensions[$extension]) === false) {
|
||||
$testFiles[] = $path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Put them in order.
|
||||
sort($testFiles, SORT_NATURAL);
|
||||
|
||||
return $testFiles;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Should this test be skipped for some reason.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function shouldSkipTest()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests the extending classes Sniff class.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \PHP_CodeSniffer\Exceptions\RuntimeException
|
||||
*/
|
||||
final public function testSniff()
|
||||
{
|
||||
// Skip this test if we can't run in this environment.
|
||||
if ($this->shouldSkipTest() === true) {
|
||||
$this->markTestSkipped();
|
||||
}
|
||||
|
||||
$sniffCode = Common::getSniffCode(static::class);
|
||||
$sniffCodeParts = explode('.', $sniffCode);
|
||||
$standardName = $sniffCodeParts[0];
|
||||
|
||||
$testFileBase = (new ReflectionClass(static::class))->getFileName();
|
||||
$testFileBase = substr($testFileBase, 0, -3);
|
||||
|
||||
// Get a list of all test files to check.
|
||||
$testFiles = $this->getTestFiles($testFileBase);
|
||||
if (empty($testFiles) === true) {
|
||||
$this->markTestIncomplete('No test case files found for ' . static::class);
|
||||
}
|
||||
|
||||
$sniffFile = preg_replace('`[/\\\\]Tests[/\\\\]`', DIRECTORY_SEPARATOR . 'Sniffs' . DIRECTORY_SEPARATOR, $testFileBase);
|
||||
$sniffFile = str_replace('UnitTest.', 'Sniff.php', $sniffFile);
|
||||
|
||||
if (file_exists($sniffFile) === false) {
|
||||
$this->fail(sprintf('ERROR: Sniff file %s for test %s does not appear to exist', $sniffFile, static::class));
|
||||
}
|
||||
|
||||
$replacements = [
|
||||
$standardName,
|
||||
$sniffFile,
|
||||
];
|
||||
$rulesetContents = str_replace(self::SEARCH_FOR, $replacements, self::RULESET_TEMPLATE);
|
||||
|
||||
if (file_put_contents(self::RULESET_FILENAME, $rulesetContents) === false) {
|
||||
throw new RuntimeException('Failed to write custom ruleset file');
|
||||
}
|
||||
|
||||
if (isset(self::$config) === true) {
|
||||
$config = self::$config;
|
||||
} else {
|
||||
$config = new ConfigDouble();
|
||||
$config->cache = false;
|
||||
self::$config = $config;
|
||||
}
|
||||
|
||||
$config->standards = [self::RULESET_FILENAME];
|
||||
$config->sniffs = [$sniffCode];
|
||||
$config->ignored = [];
|
||||
|
||||
$ruleset = new Ruleset($config);
|
||||
|
||||
$failureMessages = [];
|
||||
foreach ($testFiles as $testFile) {
|
||||
$filename = basename($testFile);
|
||||
$oldConfig = $config->getSettings();
|
||||
|
||||
try {
|
||||
$this->setCliValues($filename, $config);
|
||||
$phpcsFile = new LocalFile($testFile, $ruleset, $config);
|
||||
$phpcsFile->process();
|
||||
} catch (RuntimeException $e) {
|
||||
$this->fail('An unexpected exception has been caught: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
$failures = $this->generateFailureMessages($phpcsFile);
|
||||
$failureMessages = array_merge($failureMessages, $failures);
|
||||
|
||||
if ($phpcsFile->getFixableCount() > 0) {
|
||||
// Attempt to fix the errors.
|
||||
$phpcsFile->fixer->fixFile();
|
||||
$fixable = $phpcsFile->getFixableCount();
|
||||
if ($fixable > 0) {
|
||||
$failureMessages[] = "Failed to fix $fixable fixable violations in $filename";
|
||||
}
|
||||
|
||||
// Check for a .fixed file to check for accuracy of fixes.
|
||||
$fixedFile = $testFile . '.fixed';
|
||||
$filename = basename($testFile);
|
||||
if (file_exists($fixedFile) === true) {
|
||||
if ($phpcsFile->fixer->getContents() !== file_get_contents($fixedFile)) {
|
||||
// Only generate the (expensive) diff if a difference is expected.
|
||||
$diff = $phpcsFile->fixer->generateDiff($fixedFile);
|
||||
if (trim($diff) !== '') {
|
||||
$fixedFilename = basename($fixedFile);
|
||||
$failureMessages[] = "Fixed version of $filename does not match expected version in $fixedFilename; the diff is\n$diff";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$diff = trim($phpcsFile->fixer->generateDiff($testFile));
|
||||
$failureMessages[] = "Missing fixed version of $filename to verify the accuracy of fixes, while the sniff is making fixes against the test case file; the diff is\n$diff";
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the config.
|
||||
$config->setSettings($oldConfig);
|
||||
}
|
||||
|
||||
if (empty($failureMessages) === false) {
|
||||
$this->fail(implode(PHP_EOL, $failureMessages));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate a list of test failures for a given sniffed file.
|
||||
*
|
||||
* @param \PHP_CodeSniffer\Files\LocalFile $file The file being tested.
|
||||
*
|
||||
* @return array
|
||||
* @throws \PHP_CodeSniffer\Exceptions\RuntimeException
|
||||
*/
|
||||
public function generateFailureMessages(LocalFile $file)
|
||||
{
|
||||
$testFile = $file->getFilename();
|
||||
|
||||
$foundErrors = $file->getErrors();
|
||||
$foundWarnings = $file->getWarnings();
|
||||
$expectedErrors = $this->getErrorList(basename($testFile));
|
||||
$expectedWarnings = $this->getWarningList(basename($testFile));
|
||||
|
||||
if (is_array($expectedErrors) === false) {
|
||||
throw new RuntimeException('getErrorList() must return an array');
|
||||
}
|
||||
|
||||
if (is_array($expectedWarnings) === false) {
|
||||
throw new RuntimeException('getWarningList() must return an array');
|
||||
}
|
||||
|
||||
/*
|
||||
We merge errors and warnings together to make it easier
|
||||
to iterate over them and produce the errors string. In this way,
|
||||
we can report on errors and warnings in the same line even though
|
||||
it's not really structured to allow that.
|
||||
*/
|
||||
|
||||
$allProblems = [];
|
||||
$failureMessages = [];
|
||||
|
||||
foreach ($foundErrors as $line => $lineErrors) {
|
||||
foreach ($lineErrors as $column => $errors) {
|
||||
if (isset($allProblems[$line]) === false) {
|
||||
$allProblems[$line] = [
|
||||
'expected_errors' => 0,
|
||||
'expected_warnings' => 0,
|
||||
'found_errors' => [],
|
||||
'found_warnings' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$foundErrorsTemp = [];
|
||||
foreach ($allProblems[$line]['found_errors'] as $foundError) {
|
||||
$foundErrorsTemp[] = $foundError;
|
||||
}
|
||||
|
||||
$errorsTemp = [];
|
||||
foreach ($errors as $foundError) {
|
||||
$errorsTemp[] = $foundError['message'] . ' (' . $foundError['source'] . ')';
|
||||
}
|
||||
|
||||
$allProblems[$line]['found_errors'] = array_merge($foundErrorsTemp, $errorsTemp);
|
||||
}
|
||||
|
||||
if (isset($expectedErrors[$line]) === true) {
|
||||
$allProblems[$line]['expected_errors'] = $expectedErrors[$line];
|
||||
} else {
|
||||
$allProblems[$line]['expected_errors'] = 0;
|
||||
}
|
||||
|
||||
unset($expectedErrors[$line]);
|
||||
}
|
||||
|
||||
foreach ($expectedErrors as $line => $numErrors) {
|
||||
if (isset($allProblems[$line]) === false) {
|
||||
$allProblems[$line] = [
|
||||
'expected_errors' => 0,
|
||||
'expected_warnings' => 0,
|
||||
'found_errors' => [],
|
||||
'found_warnings' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$allProblems[$line]['expected_errors'] = $numErrors;
|
||||
}
|
||||
|
||||
foreach ($foundWarnings as $line => $lineWarnings) {
|
||||
foreach ($lineWarnings as $column => $warnings) {
|
||||
if (isset($allProblems[$line]) === false) {
|
||||
$allProblems[$line] = [
|
||||
'expected_errors' => 0,
|
||||
'expected_warnings' => 0,
|
||||
'found_errors' => [],
|
||||
'found_warnings' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$foundWarningsTemp = [];
|
||||
foreach ($allProblems[$line]['found_warnings'] as $foundWarning) {
|
||||
$foundWarningsTemp[] = $foundWarning;
|
||||
}
|
||||
|
||||
$warningsTemp = [];
|
||||
foreach ($warnings as $warning) {
|
||||
$warningsTemp[] = $warning['message'] . ' (' . $warning['source'] . ')';
|
||||
}
|
||||
|
||||
$allProblems[$line]['found_warnings'] = array_merge($foundWarningsTemp, $warningsTemp);
|
||||
}
|
||||
|
||||
if (isset($expectedWarnings[$line]) === true) {
|
||||
$allProblems[$line]['expected_warnings'] = $expectedWarnings[$line];
|
||||
} else {
|
||||
$allProblems[$line]['expected_warnings'] = 0;
|
||||
}
|
||||
|
||||
unset($expectedWarnings[$line]);
|
||||
}
|
||||
|
||||
foreach ($expectedWarnings as $line => $numWarnings) {
|
||||
if (isset($allProblems[$line]) === false) {
|
||||
$allProblems[$line] = [
|
||||
'expected_errors' => 0,
|
||||
'expected_warnings' => 0,
|
||||
'found_errors' => [],
|
||||
'found_warnings' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$allProblems[$line]['expected_warnings'] = $numWarnings;
|
||||
}
|
||||
|
||||
// Order the messages by line number.
|
||||
ksort($allProblems);
|
||||
|
||||
foreach ($allProblems as $line => $problems) {
|
||||
$numErrors = count($problems['found_errors']);
|
||||
$numWarnings = count($problems['found_warnings']);
|
||||
$expectedErrors = $problems['expected_errors'];
|
||||
$expectedWarnings = $problems['expected_warnings'];
|
||||
|
||||
$errors = '';
|
||||
$foundString = '';
|
||||
|
||||
if ($expectedErrors !== $numErrors || $expectedWarnings !== $numWarnings) {
|
||||
$lineMessage = "[LINE $line]";
|
||||
$expectedMessage = 'Expected ';
|
||||
$foundMessage = 'in ' . basename($testFile) . ' but found ';
|
||||
|
||||
if ($expectedErrors !== $numErrors) {
|
||||
$expectedMessage .= "$expectedErrors error(s)";
|
||||
$foundMessage .= "$numErrors error(s)";
|
||||
if ($numErrors !== 0) {
|
||||
$foundString .= 'error(s)';
|
||||
$errors .= implode(PHP_EOL . ' -> ', $problems['found_errors']);
|
||||
}
|
||||
|
||||
if ($expectedWarnings !== $numWarnings) {
|
||||
$expectedMessage .= ' and ';
|
||||
$foundMessage .= ' and ';
|
||||
if ($numWarnings !== 0) {
|
||||
if ($foundString !== '') {
|
||||
$foundString .= ' and ';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($expectedWarnings !== $numWarnings) {
|
||||
$expectedMessage .= "$expectedWarnings warning(s)";
|
||||
$foundMessage .= "$numWarnings warning(s)";
|
||||
if ($numWarnings !== 0) {
|
||||
$foundString .= 'warning(s)';
|
||||
if (empty($errors) === false) {
|
||||
$errors .= PHP_EOL . ' -> ';
|
||||
}
|
||||
|
||||
$errors .= implode(PHP_EOL . ' -> ', $problems['found_warnings']);
|
||||
}
|
||||
}
|
||||
|
||||
$fullMessage = "$lineMessage $expectedMessage $foundMessage.";
|
||||
if ($errors !== '') {
|
||||
$fullMessage .= " The $foundString found were:" . PHP_EOL . " -> $errors";
|
||||
}
|
||||
|
||||
$failureMessages[] = $fullMessage;
|
||||
}
|
||||
}
|
||||
|
||||
return $failureMessages;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of CLI values to set before the file is tested.
|
||||
*
|
||||
* @param string $testFile The name of the file being tested.
|
||||
* @param \PHP_CodeSniffer\Config $config The config data for the run.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCliValues(string $testFile, Config $config)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the lines where errors should occur.
|
||||
*
|
||||
* The key of the array should represent the line number and the value
|
||||
* should represent the number of errors that should occur on that line.
|
||||
*
|
||||
* @return array<int, int>
|
||||
*/
|
||||
abstract protected function getErrorList();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the lines where warnings should occur.
|
||||
*
|
||||
* The key of the array should represent the line number and the value
|
||||
* should represent the number of warnings that should occur on that line.
|
||||
*
|
||||
* @return array<int, int>
|
||||
*/
|
||||
abstract protected function getWarningList();
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* Bootstrap file for PHP_CodeSniffer unit tests.
|
||||
*
|
||||
* @author Greg Sherwood <gsherwood@squiz.net>
|
||||
* @copyright 2006-2023 Squiz Pty Ltd (ABN 77 084 670 600)
|
||||
* @copyright 2023 PHPCSStandards and contributors
|
||||
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/HEAD/licence.txt BSD Licence
|
||||
*/
|
||||
|
||||
use PHP_CodeSniffer\Autoload;
|
||||
use PHP_CodeSniffer\Util\Standards;
|
||||
use PHP_CodeSniffer\Util\Tokens;
|
||||
|
||||
if (defined('PHP_CODESNIFFER_IN_TESTS') === false) {
|
||||
define('PHP_CODESNIFFER_IN_TESTS', true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine whether the test suite should be run in CBF mode.
|
||||
*
|
||||
* Use `<php><env name="PHP_CODESNIFFER_CBF" value="1"/></php>` in a `phpunit.xml` file
|
||||
* or set the ENV variable at an OS-level to enable CBF mode.
|
||||
*
|
||||
* To run the CBF specific tests, use the following command:
|
||||
* vendor/bin/phpunit --group CBF --exclude-group nothing
|
||||
*
|
||||
* If the ENV variable has not been set, or is set to "false", the tests will run in CS mode.
|
||||
*/
|
||||
|
||||
if (defined('PHP_CODESNIFFER_CBF') === false) {
|
||||
$cbfMode = getenv('PHP_CODESNIFFER_CBF');
|
||||
if ($cbfMode === '1') {
|
||||
define('PHP_CODESNIFFER_CBF', true);
|
||||
echo 'Note: Tests are running in "CBF" mode' . PHP_EOL . PHP_EOL;
|
||||
} else {
|
||||
define('PHP_CODESNIFFER_CBF', false);
|
||||
echo 'Note: Tests are running in "CS" mode' . PHP_EOL . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
if (defined('PHP_CODESNIFFER_VERBOSITY') === false) {
|
||||
define('PHP_CODESNIFFER_VERBOSITY', 0);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/../autoload.php';
|
||||
|
||||
// Make sure all installed standards are autoloadable.
|
||||
$installedStandards = Standards::getInstalledStandardDetails();
|
||||
foreach ($installedStandards as $standardDetails) {
|
||||
Autoload::addSearchPath($standardDetails['path'], $standardDetails['namespace']);
|
||||
}
|
||||
|
||||
$tokens = new Tokens();
|
||||
Reference in New Issue
Block a user