From 2b6fad4177720cfd14857db4fc16df6b6caac5ad Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Wed, 22 May 2024 22:18:02 +0200 Subject: [PATCH 1/5] Commit the sniff. --- WordPress/Sniffs/Commenting/SinceTagSniff.php | 604 ++++++++++++++++++ 1 file changed, 604 insertions(+) create mode 100644 WordPress/Sniffs/Commenting/SinceTagSniff.php diff --git a/WordPress/Sniffs/Commenting/SinceTagSniff.php b/WordPress/Sniffs/Commenting/SinceTagSniff.php new file mode 100644 index 000000000..b4b472e33 --- /dev/null +++ b/WordPress/Sniffs/Commenting/SinceTagSniff.php @@ -0,0 +1,604 @@ + array( + 'name' => 'class', + ), + T_INTERFACE => array( + 'name' => 'interface', + ), + T_TRAIT => array( + 'name' => 'trait', + ), + T_ENUM => array( + 'name' => 'enum', + ), + ); + + /** + * Returns an array of tokens this test wants to listen for. + * + * @return array + */ + public function register() { + return array_merge( + array( + T_FUNCTION, + T_VARIABLE, + T_STRING, + ), + array_keys( static::$oo_tokens ) + ); + } + + /** + * Processes the tokens that this sniff is interested in. + * + * @param File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token in the stack passed in $tokens. + */ + public function process( File $phpcsFile, $stackPtr ) { + $tokens = $phpcsFile->getTokens(); + $token = $tokens[ $stackPtr ]; + + if ( 'T_FUNCTION' === $token['type'] ) { + $this->process_function_token( $phpcsFile, $stackPtr ); + return; + } + + if ( isset( static::$oo_tokens[ $token['code'] ] ) ) { + $this->process_oo_token( $phpcsFile, $stackPtr ); + return; + } + + if ( 'T_STRING' === $token['type'] && static::is_function_call( $phpcsFile, $stackPtr ) ) { + $this->process_hook( $phpcsFile, $stackPtr ); + return; + } + + if ( 'T_VARIABLE' === $token['type'] && Scopes::isOOProperty( $phpcsFile, $stackPtr ) ) { + $this->process_property_token( $phpcsFile, $stackPtr ); + } + } + + /** + * Processes a token representing a function call that invokes a WordPress hook, + * checking for a missing `@since` tag in its docblock. + * + * @param File $phpcs_file The file being scanned. + * @param int $stack_pointer The position of the hook token in the stack. + */ + protected function process_hook( File $phpcs_file, $stack_pointer ) { + $tokens = $phpcs_file->getTokens(); + + // The content of the current token. + $hook_function = $tokens[ $stack_pointer ]['content']; + + $hook_invocation_functions = array( + 'do_action', + 'do_action_ref_array', + 'do_action_deprecated', + 'apply_filters', + 'apply_filters_ref_array', + 'apply_filters_deprecated', + ); + + // Check if the current token content is one of the filter functions. + if ( ! in_array( $hook_function, $hook_invocation_functions, true ) ) { + // Not a hook. + return; + } + + $error_message_data = array( $hook_function ); + + $violation_codes = static::get_violation_codes( 'Hook' ); + + $docblock = static::find_hook_docblock( $phpcs_file, $stack_pointer ); + + $version_tags = static::parse_since_tags( $phpcs_file, $docblock ); + if ( empty( $version_tags ) ) { + if ( false !== $docblock ) { + $docblock_content = GetTokensAsString::compact( $phpcs_file, $docblock['start_token'], $docblock['end_token'], false ); + if ( false !== stripos( $docblock_content, 'This filter is documented in ' ) ) { + $hook_documented_elsewhere = true; + } + } + + if ( empty( $hook_documented_elsewhere ) ) { + $phpcs_file->addError( + 'Missing @since tag for the "%s()" hook function.', + $stack_pointer, + $violation_codes['missing_since_tag'], + $error_message_data + ); + } + + return; + } + + foreach ( $version_tags as $since_tag_token => $version_value_token ) { + if ( null === $version_value_token ) { + $phpcs_file->addError( + 'Missing @since tag version value for the "%s()" hook function.', + $since_tag_token, + $violation_codes['missing_version_value'], + $error_message_data + ); + continue; + } + + $version_value = $tokens[ $version_value_token ]['content']; + + if ( static::validate_version( $version_value ) ) { + continue; + } + + $phpcs_file->addError( + 'Invalid @since version value for the "%s()" hook function: "%s". Version value must be greater than or equal to 0.0.1.', + $version_value_token, + $violation_codes['invalid_version_value'], + array_merge( $error_message_data, array( $version_value ) ) + ); + } + } + + /** + * Processes a token representing an object-oriented programming structure + * like a class, interface, trait, or enum to check for a missing `@since` tag in its docblock. + * + * @param File $phpcs_file The file being scanned. + * @param int $stack_pointer The position of the OO token in the stack. + */ + protected function process_oo_token( File $phpcs_file, $stack_pointer ) { + $tokens = $phpcs_file->getTokens(); + $token_type = static::$oo_tokens[ $tokens[ $stack_pointer ]['code'] ]['name']; + + $token_name = ObjectDeclarations::getName( $phpcs_file, $stack_pointer ); + $error_message_data = array( + $token_name, + $token_type, + ); + + $violation_codes = static::get_violation_codes( ucfirst( $token_type ) ); + + $docblock = static::find_docblock( $phpcs_file, $stack_pointer ); + + $version_tags = static::parse_since_tags( $phpcs_file, $docblock ); + if ( empty( $version_tags ) ) { + $phpcs_file->addError( + 'Missing @since tag for the "%s" %s.', + $stack_pointer, + $violation_codes['missing_since_tag'], + $error_message_data + ); + return; + } + + foreach ( $version_tags as $since_tag_token => $version_value_token ) { + if ( null === $version_value_token ) { + $phpcs_file->addError( + 'Missing @since tag version value for the "%s" %s.', + $since_tag_token, + $violation_codes['missing_version_value'], + $error_message_data + ); + continue; + } + + $version_value = $tokens[ $version_value_token ]['content']; + + if ( static::validate_version( $version_value ) ) { + continue; + } + + $phpcs_file->addError( + 'Invalid @since version value for the "%s" %s: "%s". Version value must be greater than or equal to 0.0.1.', + $version_value_token, + $violation_codes['invalid_version_value'], + array_merge( $error_message_data, array( $version_value ) ) + ); + } + } + + /** + * Processes a token representing an object-oriented property to check for a missing @since tag in its docblock. + * + * @param File $phpcs_file The file being scanned. + * @param int $stack_pointer The position of the object-oriented property token in the stack. + */ + protected function process_property_token( File $phpcs_file, $stack_pointer ) { + $tokens = $phpcs_file->getTokens(); + + $property_name = $tokens[ $stack_pointer ]['content']; + $oo_token = Scopes::validDirectScope( $phpcs_file, $stack_pointer, Collections::ooPropertyScopes() ); + $class_name = ObjectDeclarations::getName( $phpcs_file, $oo_token ); + + $visibility = Variables::getMemberProperties( $phpcs_file, $stack_pointer )['scope']; + if ( $this->check_below_minimum_visibility( $visibility ) ) { + return; + } + + $violation_codes = static::get_violation_codes( 'Property' ); + + $error_message_data = array( + $class_name, + $property_name, + ); + + $docblock = static::find_docblock( $phpcs_file, $stack_pointer ); + + $version_tags = static::parse_since_tags( $phpcs_file, $docblock ); + if ( empty( $version_tags ) ) { + $phpcs_file->addError( + 'Missing @since tag for the "%s::%s" property.', + $stack_pointer, + $violation_codes['missing_since_tag'], + $error_message_data + ); + return; + } + + foreach ( $version_tags as $since_tag_token => $version_value_token ) { + if ( null === $version_value_token ) { + $phpcs_file->addError( + 'Missing @since tag version value for the "%s::%s" property.', + $since_tag_token, + $violation_codes['missing_version_value'], + $error_message_data + ); + continue; + } + + $version_value = $tokens[ $version_value_token ]['content']; + + if ( static::validate_version( $version_value ) ) { + continue; + } + + $phpcs_file->addError( + 'Invalid @since version value for the "%s::%s" property: "%s". Version value must be greater than or equal to 0.0.1.', + $version_value_token, + $violation_codes['invalid_version_value'], + array_merge( $error_message_data, array( $version_value ) ) + ); + } + } + + /** + * Processes a T_FUNCTION token to check for a missing @since tag in its docblock. + * + * @param File $phpcs_file The file being scanned. + * @param int $stack_pointer The position of the T_FUNCTION token in the stack. + */ + protected function process_function_token( File $phpcs_file, $stack_pointer ) { + $tokens = $phpcs_file->getTokens(); + + $oo_token = Scopes::validDirectScope( $phpcs_file, $stack_pointer, Tokens::$ooScopeTokens ); + $function_name = ObjectDeclarations::getName( $phpcs_file, $stack_pointer ); + + $token_type = 'function'; + if ( Scopes::isOOMethod( $phpcs_file, $stack_pointer ) ) { + $visibility = FunctionDeclarations::getProperties( $phpcs_file, $stack_pointer )['scope']; + if ( $this->check_below_minimum_visibility( $visibility ) ) { + return; + } + + $function_name = ObjectDeclarations::getName( $phpcs_file, $oo_token ) . '::' . $function_name; + $token_type = 'method'; + } + + $violation_codes = static::get_violation_codes( ucfirst( $token_type ) ); + + $error_message_data = array( + $function_name, + $token_type, + ); + + $docblock = static::find_docblock( $phpcs_file, $stack_pointer ); + + $version_tags = static::parse_since_tags( $phpcs_file, $docblock ); + if ( empty( $version_tags ) ) { + $phpcs_file->addError( + 'Missing @since tag for the "%s()" %s.', + $stack_pointer, + $violation_codes['missing_since_tag'], + $error_message_data + ); + return; + } + + foreach ( $version_tags as $since_tag_token => $version_value_token ) { + if ( null === $version_value_token ) { + $phpcs_file->addError( + 'Missing @since tag version value for the "%s()" %s.', + $since_tag_token, + $violation_codes['missing_version_value'], + $error_message_data + ); + continue; + } + + $version_value = $tokens[ $version_value_token ]['content']; + + if ( static::validate_version( $version_value ) ) { + continue; + } + + $phpcs_file->addError( + 'Invalid @since version value for the "%s()" %s: "%s". Version value must be greater than or equal to 0.0.1.', + $version_value_token, + $violation_codes['invalid_version_value'], + array_merge( $error_message_data, array( $version_value ) ) + ); + } + } + + /** + * Validates the version value. + * + * @param string $version The version value being checked. + * @return bool True if the version value is valid. + */ + protected static function validate_version( $version ) { + $matches = array(); + if ( 1 === preg_match( '/^MU \((?.+)\)/', $version, $matches ) ) { + $version = $matches['version']; + } + + return version_compare( $version, '0.0.1', '>=' ); + } + + + /** + * Returns violation codes for a specific token type. + * + * @param string $token_type The type of token (e.g., Function, Property) to retrieve violation codes for. + * @return array An array containing violation codes for missing since tag, missing version value, and invalid version value. + */ + protected static function get_violation_codes( $token_type ) { + return array( + 'missing_since_tag' => 'Missing' . $token_type . 'SinceTag', + 'missing_version_value' => 'Missing' . $token_type . 'VersionValue', + 'invalid_version_value' => 'Invalid' . $token_type . 'VersionValue', + ); + } + + /** + * Checks if the provided visibility level is below the set minimum visibility level. + * + * @param string $visibility The visibility level to check. + * @return bool Returns true if the provided visibility level is below the minimum visibility level, false otherwise. + */ + protected function check_below_minimum_visibility( $visibility ) { + if ( 'public' === $this->minimumVisibility && in_array( $visibility, array( 'protected', 'private' ), true ) ) { + return true; + } + + if ( 'protected' === $this->minimumVisibility && 'private' === $visibility ) { + return true; + } + + return false; + } + + /** + * Finds the docblock associated with a hook, starting from a specified position in the token stack. + * Since a line containing a hook can include any type of tokens, this method backtracks through the tokens + * to locate the first token on the current line. This token is then used as the starting point for searching the docblock. + * + * @param File $phpcs_file The file being scanned. + * @param int $stack_pointer The position to start looking for the docblock. + * @return array|false An associative array containing the start and end tokens of the docblock, or false if not found. + */ + protected static function find_hook_docblock( File $phpcs_file, $stack_pointer ) { + $tokens = $phpcs_file->getTokens(); + $current_line = $tokens[ $stack_pointer ]['line']; + + for ( $i = $stack_pointer; $i >= 0; $i-- ) { + if ( $tokens[ $i ]['line'] < $current_line ) { + // The previous token is on the previous line, so the current token is the first on the line. + return static::find_docblock( $phpcs_file, $i + 1 ); + } + } + + return static::find_docblock( $phpcs_file, 0 ); + } + + /** + * Determines if a T_STRING token represents a function call. + * The implementation was copied from PHPCompatibility\Sniffs\Extensions\RemovedExtensionsSniff::process(). + * + * @param File $phpcs_file The file being scanned. + * @param int $stack_pointer The position of the T_STRING token in question. + * @return bool True if the token represents a function call, false otherwise. + */ + protected static function is_function_call( File $phpcs_file, $stack_pointer ) { + $tokens = $phpcs_file->getTokens(); + + // Find the next non-empty token. + $open_bracket = $phpcs_file->findNext( Tokens::$emptyTokens, ( $stack_pointer + 1 ), null, true ); + + if ( T_OPEN_PARENTHESIS !== $tokens[ $open_bracket ]['code'] ) { + // Not a function call. + return false; + } + + if ( false === isset( $tokens[ $open_bracket ]['parenthesis_closer'] ) ) { + // Not a function call. + return false; + } + + // Find the previous non-empty token. + $search = Tokens::$emptyTokens; + $search[] = T_BITWISE_AND; + $previous = $phpcs_file->findPrevious( $search, ( $stack_pointer - 1 ), null, true ); + + $previous_tokens_to_ignore = array( + T_FUNCTION, // Function declaration. + T_NEW, // Creating an object. + T_OBJECT_OPERATOR, // Calling an object. + ); + + return ! in_array( $tokens[ $previous ]['code'], $previous_tokens_to_ignore, true ); + } + + /** + * Finds the docblock preceding a specified position (stack pointer) in a given PHP file. + * The implementation was copied from PHP_CodeSniffer\Standards\PEAR\Sniffs\Commenting\FunctionCommentSniff::process(). + * + * @param File $phpcs_file The file being scanned. + * @param int $stack_pointer The position (stack pointer) in the token stack from which to start searching backwards. + * @return array|false An associative array containing the start and end tokens of the docblock, or false if not found. + */ + protected static function find_docblock( File $phpcs_file, $stack_pointer ) { + $tokens = $phpcs_file->getTokens(); + $ignore = Tokens::$methodPrefixes; + $ignore[ T_WHITESPACE ] = T_WHITESPACE; + + for ( $comment_end = ( $stack_pointer - 1 ); $comment_end >= 0; $comment_end-- ) { + if ( isset( $ignore[ $tokens[ $comment_end ]['code'] ] ) ) { + continue; + } + + if ( T_ATTRIBUTE_END === $tokens[ $comment_end ]['code'] + && isset( $tokens[ $comment_end ]['attribute_opener'] ) + ) { + $comment_end = $tokens[ $comment_end ]['attribute_opener']; + continue; + } + + break; + } + + if ( $tokens[ $comment_end ]['code'] === T_COMMENT ) { + // Inline comments might just be closing comments for + // control structures or functions instead of function comments + // using the wrong comment type. If there is other code on the line, + // assume they relate to that code. + $previous = $phpcs_file->findPrevious( $ignore, ( $comment_end - 1 ), null, true ); + if ( false !== $previous && $tokens[ $previous ]['line'] === $tokens[ $comment_end ]['line'] ) { + $comment_end = $previous; + } + } + + if ( T_DOC_COMMENT_CLOSE_TAG !== $tokens[ $comment_end ]['code'] ) { + // Only "/**" style comments are supported. + return false; + } + + return array( + 'start_token' => $tokens[ $comment_end ]['comment_opener'], + 'end_token' => $comment_end, + ); + } + + /** + * Searches for @since values within a docblock. + * + * @param File $phpcs_file The file being scanned. + * @param array|false $docblock An associative array containing the start and end tokens of the docblock, or false if not exists. + * @return array Returns an array of "@since" tokens and their corresponding value tokens. + */ + protected static function parse_since_tags( File $phpcs_file, $docblock ) { + $version_tags = array(); + + if ( false === $docblock ) { + return $version_tags; + } + + $tokens = $phpcs_file->getTokens(); + + for ( $i = $docblock['start_token'] + 1; $i < $docblock['end_token']; $i++ ) { + if ( ! ( T_DOC_COMMENT_TAG === $tokens[ $i ]['code'] && '@since' === $tokens[ $i ]['content'] ) ) { + continue; + } + + $version_token = $phpcs_file->findNext( T_DOC_COMMENT_WHITESPACE, $i + 1, $docblock['end_token'], true, null, true ); + if ( ( false === $version_token ) || ( T_DOC_COMMENT_STRING !== $tokens[ $version_token ]['code'] ) ) { + $version_tags[ $i ] = null; + continue; + } + + $version_tags[ $i ] = $version_token; + } + + return $version_tags; + } + + /** + * Checks if the current block is experimental. + * + * @param File $phpcs_file The file being scanned. + * @return bool Returns true if the current block is experimental. + */ + protected static function is_experimental_block( File $phpcs_file ) { + $block_json_filepath = dirname( $phpcs_file->getFilename() ) . DIRECTORY_SEPARATOR . 'block.json'; + + if ( isset( static::$cache[ $block_json_filepath ] ) ) { + return static::$cache[ $block_json_filepath ]; + } + + if ( ! is_file( $block_json_filepath ) || ! is_readable( $block_json_filepath ) ) { + static::$cache[ $block_json_filepath ] = false; + return static::$cache[ $block_json_filepath ]; + } + + // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- this Composer package doesn't depend on WordPress. + $block_metadata = file_get_contents( $block_json_filepath ); + if ( false === $block_metadata ) { + static::$cache[ $block_json_filepath ] = false; + return static::$cache[ $block_json_filepath ]; + } + + $block_metadata = json_decode( $block_metadata, true ); + if ( ! is_array( $block_metadata ) ) { + static::$cache[ $block_json_filepath ] = false; + return static::$cache[ $block_json_filepath ]; + } + + $experimental_flag = '__experimental'; + static::$cache[ $block_json_filepath ] = array_key_exists( $experimental_flag, $block_metadata ) && ( false !== $block_metadata[ $experimental_flag ] ); + return static::$cache[ $block_json_filepath ]; + } +} From f6894801954532f55987842209c191da8bbd84ee Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Wed, 22 May 2024 22:30:57 +0200 Subject: [PATCH 2/5] Remove non-related stuff. --- WordPress/Sniffs/Commenting/SinceTagSniff.php | 37 ------------------- 1 file changed, 37 deletions(-) diff --git a/WordPress/Sniffs/Commenting/SinceTagSniff.php b/WordPress/Sniffs/Commenting/SinceTagSniff.php index b4b472e33..55b637004 100644 --- a/WordPress/Sniffs/Commenting/SinceTagSniff.php +++ b/WordPress/Sniffs/Commenting/SinceTagSniff.php @@ -22,7 +22,6 @@ /** * This sniff verifies the presence of valid `@since` tags in the docblocks of various PHP structures * and WordPress hooks. Supported structures include classes, interfaces, traits, enums, functions, methods and properties. - * Files located within the __experimental block of the block-library are excluded from checks. */ class SinceTagSniff implements Sniff { @@ -565,40 +564,4 @@ protected static function parse_since_tags( File $phpcs_file, $docblock ) { return $version_tags; } - - /** - * Checks if the current block is experimental. - * - * @param File $phpcs_file The file being scanned. - * @return bool Returns true if the current block is experimental. - */ - protected static function is_experimental_block( File $phpcs_file ) { - $block_json_filepath = dirname( $phpcs_file->getFilename() ) . DIRECTORY_SEPARATOR . 'block.json'; - - if ( isset( static::$cache[ $block_json_filepath ] ) ) { - return static::$cache[ $block_json_filepath ]; - } - - if ( ! is_file( $block_json_filepath ) || ! is_readable( $block_json_filepath ) ) { - static::$cache[ $block_json_filepath ] = false; - return static::$cache[ $block_json_filepath ]; - } - - // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- this Composer package doesn't depend on WordPress. - $block_metadata = file_get_contents( $block_json_filepath ); - if ( false === $block_metadata ) { - static::$cache[ $block_json_filepath ] = false; - return static::$cache[ $block_json_filepath ]; - } - - $block_metadata = json_decode( $block_metadata, true ); - if ( ! is_array( $block_metadata ) ) { - static::$cache[ $block_json_filepath ] = false; - return static::$cache[ $block_json_filepath ]; - } - - $experimental_flag = '__experimental'; - static::$cache[ $block_json_filepath ] = array_key_exists( $experimental_flag, $block_metadata ) && ( false !== $block_metadata[ $experimental_flag ] ); - return static::$cache[ $block_json_filepath ]; - } } From 46ccec79577813eff0614fdb930c70db24410870 Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Wed, 22 May 2024 22:37:36 +0200 Subject: [PATCH 3/5] Add tests. --- .../Tests/Commenting/SinceTagUnitTest.inc | 629 ++++++++++++++++++ .../Tests/Commenting/SinceTagUnitTest.php | 171 +++++ 2 files changed, 800 insertions(+) create mode 100644 WordPress/Tests/Commenting/SinceTagUnitTest.inc create mode 100644 WordPress/Tests/Commenting/SinceTagUnitTest.php diff --git a/WordPress/Tests/Commenting/SinceTagUnitTest.inc b/WordPress/Tests/Commenting/SinceTagUnitTest.inc new file mode 100644 index 000000000..aa8593b2e --- /dev/null +++ b/WordPress/Tests/Commenting/SinceTagUnitTest.inc @@ -0,0 +1,629 @@ +do_action(); +$foo = new do_action_ref_array(); +$foo->do_action_ref_array(); +$foo = new do_action_deprecated(); +$foo->do_action_deprecated(); +$foo = new apply_filters(); +$foo->apply_filters(); +$foo = new apply_filters_ref_array(); +$foo->apply_filters_ref_array(); +$foo = new apply_filters_deprecated(); +$foo->apply_filters_deprecated(); +$foo = new non_hook_action(); +$foo->non_hook_action(); diff --git a/WordPress/Tests/Commenting/SinceTagUnitTest.php b/WordPress/Tests/Commenting/SinceTagUnitTest.php new file mode 100644 index 000000000..c485438cf --- /dev/null +++ b/WordPress/Tests/Commenting/SinceTagUnitTest.php @@ -0,0 +1,171 @@ + => + */ + public function getErrorList() { + return array( + 2 => 1, + 3 => 1, + 4 => 1, + 5 => 1, + 6 => 1, + 9 => 1, + 15 => 1, + 26 => 1, + 33 => 1, + 35 => 1, + 36 => 1, + 42 => 1, + 49 => 1, + 62 => 1, + 67 => 1, + 69 => 1, + 70 => 1, + 79 => 1, + 82 => 1, + 88 => 1, + 97 => 1, + 99 => 1, + 105 => 1, + 107 => 1, + 108 => 1, + 112 => 1, + 113 => 1, + 114 => 1, + 115 => 1, + 116 => 1, + 119 => 1, + 125 => 1, + 136 => 1, + 142 => 1, + 145 => 1, + 152 => 1, + 165 => 1, + 174 => 1, + 178 => 1, + 180 => 1, + 181 => 1, + 188 => 1, + 195 => 1, + 208 => 1, + 213 => 1, + 215 => 1, + 216 => 1, + 221 => 1, + 223 => 1, + 229 => 1, + 238 => 1, + 240 => 1, + 246 => 1, + 248 => 1, + 249 => 1, + 253 => 1, + 254 => 1, + 255 => 1, + 256 => 1, + 257 => 1, + 260 => 1, + 266 => 1, + 277 => 1, + 283 => 1, + 286 => 1, + 293 => 1, + 306 => 1, + 315 => 1, + 319 => 1, + 321 => 1, + 322 => 1, + 329 => 1, + 336 => 1, + 349 => 1, + 354 => 1, + 356 => 1, + 357 => 1, + 362 => 1, + 365 => 1, + 371 => 1, + 380 => 1, + 382 => 1, + 388 => 1, + 390 => 1, + 391 => 1, + 395 => 1, + 396 => 1, + 397 => 1, + 398 => 1, + 399 => 1, + 402 => 1, + 408 => 1, + 419 => 1, + 426 => 1, + 433 => 1, + 446 => 1, + 455 => 1, + 459 => 1, + 461 => 1, + 462 => 1, + 469 => 1, + 476 => 1, + 489 => 1, + 492 => 1, + 493 => 1, + 496 => 1, + 502 => 1, + 513 => 1, + 517 => 1, + 519 => 1, + 520 => 1, + 526 => 1, + 533 => 1, + 546 => 1, + 549 => 1, + 550 => 1, + 551 => 1, + 552 => 1, + 555 => 1, + 561 => 1, + 572 => 1, + 579 => 1, + 581 => 1, + 582 => 1, + 587 => 1, + 592 => 1, + 597 => 1, + 602 => 1, + 607 => 1, + 612 => 1, + ); + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array(); + } +} \ No newline at end of file From 65baf9090de9ff475501f820a91fe2a7d531f1b3 Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Wed, 22 May 2024 22:47:47 +0200 Subject: [PATCH 4/5] Remove mentions of "Gutenberg". --- WordPress/Tests/Commenting/SinceTagUnitTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/WordPress/Tests/Commenting/SinceTagUnitTest.php b/WordPress/Tests/Commenting/SinceTagUnitTest.php index c485438cf..63c7b11b6 100644 --- a/WordPress/Tests/Commenting/SinceTagUnitTest.php +++ b/WordPress/Tests/Commenting/SinceTagUnitTest.php @@ -7,7 +7,7 @@ * @license https://opensource.org/licenses/MIT MIT */ -namespace WordPressCS\WordPress\Tests\DateTime; +namespace WordPressCS\WordPress\Tests\Commenting; use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest; @@ -23,7 +23,7 @@ final class SinceTagUnitTest extends AbstractSniffUnitTest { /** * Returns the lines where errors should occur. * - * @return array => + * @return array Key is the line number, value is the number of expected errors. */ public function getErrorList() { return array( @@ -163,9 +163,9 @@ public function getErrorList() { /** * Returns the lines where warnings should occur. * - * @return array => + * @return array Key is the line number, value is the number of expected warnings. */ public function getWarningList() { return array(); } -} \ No newline at end of file +} From 8bf3a4b4a63cb0f6f39150cc12b09ff8648963b4 Mon Sep 17 00:00:00 2001 From: Anton Vlasenko Date: Wed, 22 May 2024 22:50:37 +0200 Subject: [PATCH 5/5] Fix the test. --- WordPress/Tests/Commenting/SinceTagUnitTest.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/WordPress/Tests/Commenting/SinceTagUnitTest.php b/WordPress/Tests/Commenting/SinceTagUnitTest.php index 63c7b11b6..6d12aabf6 100644 --- a/WordPress/Tests/Commenting/SinceTagUnitTest.php +++ b/WordPress/Tests/Commenting/SinceTagUnitTest.php @@ -49,6 +49,7 @@ public function getErrorList() { 88 => 1, 97 => 1, 99 => 1, + 101 => 1, 105 => 1, 107 => 1, 108 => 1, @@ -64,6 +65,7 @@ public function getErrorList() { 145 => 1, 152 => 1, 165 => 1, + 171 => 1, 174 => 1, 178 => 1, 180 => 1, @@ -79,6 +81,7 @@ public function getErrorList() { 229 => 1, 238 => 1, 240 => 1, + 242 => 1, 246 => 1, 248 => 1, 249 => 1, @@ -94,6 +97,7 @@ public function getErrorList() { 286 => 1, 293 => 1, 306 => 1, + 312 => 1, 315 => 1, 319 => 1, 321 => 1, @@ -109,6 +113,7 @@ public function getErrorList() { 371 => 1, 380 => 1, 382 => 1, + 384 => 1, 388 => 1, 390 => 1, 391 => 1, @@ -123,6 +128,7 @@ public function getErrorList() { 426 => 1, 433 => 1, 446 => 1, + 452 => 1, 455 => 1, 459 => 1, 461 => 1,