File: //usr/local/wp/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizers/PHP/BackfillEnumTest.php
<?php
/**
* Tests the support of PHP 8.1 "enum" keyword.
*
* @author Jaroslav HanslĂk <kukulich@kukulich.cz>
* @copyright 2021 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
namespace PHP_CodeSniffer\Tests\Core\Tokenizers\PHP;
use PHP_CodeSniffer\Tests\Core\Tokenizers\AbstractTokenizerTestCase;
final class BackfillEnumTest extends AbstractTokenizerTestCase
{
/**
* Test that the "enum" keyword is tokenized as such.
*
* @param string $testMarker The comment which prefaces the target token in the test file.
* @param string $testContent The token content to look for.
* @param int $openerOffset Offset to find expected scope opener.
* @param int $closerOffset Offset to find expected scope closer.
*
* @dataProvider dataEnums
* @covers PHP_CodeSniffer\Tokenizers\PHP::tokenize
*
* @return void
*/
public function testEnums($testMarker, $testContent, $openerOffset, $closerOffset)
{
$tokens = $this->phpcsFile->getTokens();
$enum = $this->getTargetToken($testMarker, [T_ENUM, T_STRING], $testContent);
$tokenArray = $tokens[$enum];
$this->assertSame(T_ENUM, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_ENUM (code)');
$this->assertSame('T_ENUM', $tokenArray['type'], 'Token tokenized as '.$tokenArray['type'].', not T_ENUM (type)');
$this->assertArrayHasKey('scope_condition', $tokenArray);
$this->assertArrayHasKey('scope_opener', $tokenArray);
$this->assertArrayHasKey('scope_closer', $tokenArray);
$this->assertSame($enum, $tokenArray['scope_condition']);
$scopeOpener = $tokenArray['scope_opener'];
$scopeCloser = $tokenArray['scope_closer'];
$expectedScopeOpener = ($enum + $openerOffset);
$expectedScopeCloser = ($enum + $closerOffset);
$this->assertSame($expectedScopeOpener, $scopeOpener);
$this->assertArrayHasKey('scope_condition', $tokens[$scopeOpener]);
$this->assertArrayHasKey('scope_opener', $tokens[$scopeOpener]);
$this->assertArrayHasKey('scope_closer', $tokens[$scopeOpener]);
$this->assertSame($enum, $tokens[$scopeOpener]['scope_condition']);
$this->assertSame($scopeOpener, $tokens[$scopeOpener]['scope_opener']);
$this->assertSame($scopeCloser, $tokens[$scopeOpener]['scope_closer']);
$this->assertSame($expectedScopeCloser, $scopeCloser);
$this->assertArrayHasKey('scope_condition', $tokens[$scopeCloser]);
$this->assertArrayHasKey('scope_opener', $tokens[$scopeCloser]);
$this->assertArrayHasKey('scope_closer', $tokens[$scopeCloser]);
$this->assertSame($enum, $tokens[$scopeCloser]['scope_condition']);
$this->assertSame($scopeOpener, $tokens[$scopeCloser]['scope_opener']);
$this->assertSame($scopeCloser, $tokens[$scopeCloser]['scope_closer']);
}//end testEnums()
/**
* Data provider.
*
* @see testEnums()
*
* @return array<string, array<string, string|int>>
*/
public static function dataEnums()
{
return [
'enum - pure' => [
'testMarker' => '/* testPureEnum */',
'testContent' => 'enum',
'openerOffset' => 4,
'closerOffset' => 12,
],
'enum - backed int' => [
'testMarker' => '/* testBackedIntEnum */',
'testContent' => 'enum',
'openerOffset' => 7,
'closerOffset' => 29,
],
'enum - backed string' => [
'testMarker' => '/* testBackedStringEnum */',
'testContent' => 'enum',
'openerOffset' => 8,
'closerOffset' => 30,
],
'enum - backed int + implements' => [
'testMarker' => '/* testComplexEnum */',
'testContent' => 'enum',
'openerOffset' => 11,
'closerOffset' => 72,
],
'enum keyword when "enum" is the name for the construct (yes, this is allowed)' => [
'testMarker' => '/* testEnumWithEnumAsClassName */',
'testContent' => 'enum',
'openerOffset' => 6,
'closerOffset' => 7,
],
'enum - keyword is case insensitive' => [
'testMarker' => '/* testEnumIsCaseInsensitive */',
'testContent' => 'EnUm',
'openerOffset' => 4,
'closerOffset' => 5,
],
'enum - declaration containing comment' => [
'testMarker' => '/* testDeclarationContainingComment */',
'testContent' => 'enum',
'openerOffset' => 6,
'closerOffset' => 14,
],
];
}//end dataEnums()
/**
* Test that "enum" when not used as the keyword is still tokenized as `T_STRING`.
*
* @param string $testMarker The comment which prefaces the target token in the test file.
* @param string $testContent The token content to look for.
*
* @dataProvider dataNotEnums
* @covers PHP_CodeSniffer\Tokenizers\PHP::tokenize
*
* @return void
*/
public function testNotEnums($testMarker, $testContent)
{
$tokens = $this->phpcsFile->getTokens();
$target = $this->getTargetToken($testMarker, [T_ENUM, T_STRING], $testContent);
$tokenArray = $tokens[$target];
$this->assertSame(T_STRING, $tokenArray['code'], 'Token tokenized as '.$tokenArray['type'].', not T_STRING (code)');
$this->assertSame('T_STRING', $tokenArray['type'], 'Token tokenized as '.$tokenArray['type'].', not T_STRING (type)');
}//end testNotEnums()
/**
* Data provider.
*
* @see testNotEnums()
*
* @return array<string, array<string, string>>
*/
public static function dataNotEnums()
{
return [
'not enum - construct named enum' => [
'testMarker' => '/* testEnumAsClassNameAfterEnumKeyword */',
'testContent' => 'Enum',
],
'not enum - class named enum' => [
'testMarker' => '/* testEnumUsedAsClassName */',
'testContent' => 'Enum',
],
'not enum - class constant named enum' => [
'testMarker' => '/* testEnumUsedAsClassConstantName */',
'testContent' => 'ENUM',
],
'not enum - method named enum' => [
'testMarker' => '/* testEnumUsedAsMethodName */',
'testContent' => 'enum',
],
'not enum - class property named enum' => [
'testMarker' => '/* testEnumUsedAsPropertyName */',
'testContent' => 'enum',
],
'not enum - global function named enum' => [
'testMarker' => '/* testEnumUsedAsFunctionName */',
'testContent' => 'enum',
],
'not enum - namespace named enum' => [
'testMarker' => '/* testEnumUsedAsNamespaceName */',
'testContent' => 'Enum',
],
'not enum - part of namespace named enum' => [
'testMarker' => '/* testEnumUsedAsPartOfNamespaceName */',
'testContent' => 'Enum',
],
'not enum - class instantiation for class enum' => [
'testMarker' => '/* testEnumUsedInObjectInitialization */',
'testContent' => 'Enum',
],
'not enum - function call' => [
'testMarker' => '/* testEnumAsFunctionCall */',
'testContent' => 'enum',
],
'not enum - namespace relative function call' => [
'testMarker' => '/* testEnumAsFunctionCallWithNamespace */',
'testContent' => 'enum',
],
'not enum - class constant fetch with enum as class name' => [
'testMarker' => '/* testClassConstantFetchWithEnumAsClassName */',
'testContent' => 'Enum',
],
'not enum - class constant fetch with enum as constant name' => [
'testMarker' => '/* testClassConstantFetchWithEnumAsConstantName */',
'testContent' => 'ENUM',
],
'parse error, not enum - enum declaration without name' => [
'testMarker' => '/* testParseErrorMissingName */',
'testContent' => 'enum',
],
'parse error, not enum - enum declaration with curlies' => [
'testMarker' => '/* testParseErrorLiveCoding */',
'testContent' => 'enum',
],
];
}//end dataNotEnums()
}//end class