Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic/UpperCaseConstantName: improve code coverage #665

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -88,36 +88,37 @@ public function process(File $phpcsFile, $stackPtr)
}

// Make sure this is not a method call.
$prev = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
$prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
if ($tokens[$prev]['code'] === T_OBJECT_OPERATOR
|| $tokens[$prev]['code'] === T_DOUBLE_COLON
|| $tokens[$prev]['code'] === T_NULLSAFE_OBJECT_OPERATOR
) {
return;
}

// Make sure this is not an attribute.
if (empty($tokens[$stackPtr]['nested_attributes']) === false) {
return;
}

// If the next non-whitespace token after this token
// is not an opening parenthesis then it is not a function call.
$openBracket = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
if ($openBracket === false) {
if ($openBracket === false || $tokens[$openBracket]['code'] !== T_OPEN_PARENTHESIS) {
return;
}

// The next non-whitespace token must be the constant name.
$constPtr = $phpcsFile->findNext(T_WHITESPACE, ($openBracket + 1), null, true);
if ($tokens[$constPtr]['code'] !== T_CONSTANT_ENCAPSED_STRING) {
// Bow out if next non-empty token after the opening parenthesis is not a string (the
// constant name). This could happen when live coding, if the constant is a variable or an
// expression, or if handling a first-class callable or a function definition outside the
// global scope.
$constPtr = $phpcsFile->findNext(Tokens::$emptyTokens, ($openBracket + 1), null, true);
if ($constPtr === false || $tokens[$constPtr]['code'] !== T_CONSTANT_ENCAPSED_STRING) {
return;
}

$constName = $tokens[$constPtr]['content'];

// Check for constants like self::CONSTANT.
$prefix = '';
$splitPos = strpos($constName, '::');
if ($splitPos !== false) {
$prefix = substr($constName, 0, ($splitPos + 2));
$constName = substr($constName, ($splitPos + 2));
}
$prefix = '';

// Strip namespace from constant like /foo/bar/CONSTANT.
$splitPos = strrpos($constName, '\\');
Expand All @@ -128,19 +129,19 @@ public function process(File $phpcsFile, $stackPtr)

if (strtoupper($constName) !== $constName) {
if (strtolower($constName) === $constName) {
$phpcsFile->recordMetric($stackPtr, 'Constant name case', 'lower');
$phpcsFile->recordMetric($constPtr, 'Constant name case', 'lower');
} else {
$phpcsFile->recordMetric($stackPtr, 'Constant name case', 'mixed');
$phpcsFile->recordMetric($constPtr, 'Constant name case', 'mixed');
}

$error = 'Constants must be uppercase; expected %s but found %s';
$data = [
$prefix.strtoupper($constName),
$prefix.$constName,
];
$phpcsFile->addError($error, $stackPtr, 'ConstantNotUpperCase', $data);
$phpcsFile->addError($error, $constPtr, 'ConstantNotUpperCase', $data);
} else {
$phpcsFile->recordMetric($stackPtr, 'Constant name case', 'upper');
$phpcsFile->recordMetric($constPtr, 'Constant name case', 'upper');
}

}//end process()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace foo\bar;
namespace bar\foo\baz;

define('VALID_NAME', true);
define('invalidName', true);
DEFINE('invalidName', true);
define("VALID_NAME", true);
define("invalidName", true);
define('bar\foo\baz\VALID_NAME_WITH_NAMESPACE', true);
Expand Down Expand Up @@ -37,7 +37,46 @@ class TypedConstants {
const MISSING_VALUE; // Parse error.
const MyClass MYCONST = new MyClass;
const int VALID_NAME = 0;
const INT invalid_name = 0;
final public const INT invalid_name = 0;
const FALSE false = false; // Yes, false can be used as a constant name, don't ask.
const array ARRAY = array(); // Same goes for array.
final protected const array ARRAY = array(); // Same goes for array.
}

define /* comment */ ( /* comment */ 'CommentsInUnconventionalPlaces', 'value' );

define
// comment
(
// phpcs:ignore Stnd.Cat.SniffName -- for reasons.
'CommentsInUnconventionalPlaces',
'value'
);

$foo-> /* comment */ define('bar');
$foo?->
// phpcs:ignore Stnd.Cat.SniffName -- for reasons.
define('bar');

const DEFINE = 'value';

#[Define('some param')]
class MyClass {}

#[
AttributeA,
define('some param')
]
class MyClass {}

const MixedCase = 1;

define('lower_case_name', 'value');
define($var, 'sniff should bow out');
define(constantName(), 'sniff should bow out');
define($obj->constantName(), 'sniff should bow out');
define(MyClass::constantName(), 'sniff should bow out');
define(condition() ? 'name1' : 'name2', 'sniff should bow out');

// Valid if outside the global namespace. Sniff should bow out.
function define($param) {}
$callable = define(...);
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

// Intentional parse error (missing constant name).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.

define(
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

// Intentional parse error (missing opening parenthesis).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.

define
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

// Intentional parse error (missing constant name).
// This should be the only test in this file.
// Testing that the sniff is *not* triggered.

const =
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,32 @@ final class UpperCaseConstantNameUnitTest extends AbstractSniffUnitTest
* 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.
*
* @param string $testFile The name of the test file to process.
*
* @return array<int, int>
*/
public function getErrorList()
public function getErrorList($testFile='')
{
return [
8 => 1,
10 => 1,
12 => 1,
14 => 1,
19 => 1,
28 => 1,
30 => 1,
40 => 1,
41 => 1,
];
switch ($testFile) {
case 'UpperCaseConstantNameUnitTest.1.inc':
return [
8 => 1,
10 => 1,
12 => 1,
14 => 1,
19 => 1,
28 => 1,
30 => 1,
40 => 1,
41 => 1,
45 => 1,
51 => 1,
71 => 1,
73 => 1,
];
default:
return [];
}

}//end getErrorList()

Expand Down