Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions WordPress/Tests/Helpers/ContextHelper/IsInIssetOrEmptyUnitTest.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

/*
* The below should NOT be recognized as being inside an isset/empty check.
*/

/* testBareVariable */ $value;
some_function( /* testOtherFunctionCall */ $value );
array_key_exists( /* testMissingArrayParam */ $key );
key_exists( /* testKeyParamNotArrayParam */ $value, $array );
MyNamespace\key_exists( 'key', /* testPartiallyQualifiedFunction */ $array );
\MyNamespace\array_key_exists( 'key', /* testFullyQualifiedNamespacedFunction */ $array );
namespace\array_key_exists( 'key', /* testNamespaceRelativeFunction */ $array ); // The method should start recognizing this once it can resolve relative namespaces.
namespace\Sub\key_exists( 'key', /* testNamespaceRelativeSubFunction */ $array );
$obj->array_key_exists( 'key', /* testObjectMethod */ $array );
$obj?->key_exists( 'key', /* testNullsafeObjectMethod */ $array );
MyClass::array_key_exists( 'key', /* testStaticMethod */ $array );
key_exists( 'key', my_function( /* testNestedNonTargetFunctionCall */ $array ) );
$obj->isset( /* testIssetObjectMethod */ $value );
Foo::empty( /* testEmptyStaticMethod */ $value );
MyNamespace\isset( /* testIssetNamespacedFunction */ $value );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about the negative test of just bare $value too?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review, @GaryJones. I added the bare $value negative test you suggested. I also added a nested valid function call test similar to the one you suggested in the review of #2721 and renamed testNestedFunctionCall to testNestedNonTargetFunctionCall to better contrast with the new positive case.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about adding these ("no false positives") tests too ?

Foo::isset();
Some\Ns\empty();

And maybe one or two variations, don't need to be silly comprehensive as the tokenizer wouldn't tokenize the above as T_ISSET/T_EMPTY (which is why this isn't specifically tested in PHPCSUtils and all the more reason we should have a few of these tests here).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it, but then opted not to add the tests precisely because PHPCS doesn't tokenize the above as T_ISSET/T_EMPTY. That said, those tests will not hurt, and I added a new commit with them.

/*
* The below should be recognized as being inside an isset/empty check.
*/

isset( /* testIsset */ $value );
empty( /* testEmpty */ $value );
array_key_exists( 'key', /* testUnqualifiedFunction */ $array );
Key_Exists( 'key', /* testMixedCaseFunction */ $array );
\array_key_exists( 'key', /* testFullyQualifiedFunction */ $array );
\KEY_EXISTS( 'key', /* testFullyQualifiedUpperCaseFunction */ $array );
array_key_exists( array: /* testNamedParamReversedOrder */ $array, key: 'foo' );
array_key_exists( 'key', \key_exists( 'key', /* testNestedValidFunctionCall */ $array ) );
147 changes: 147 additions & 0 deletions WordPress/Tests/Helpers/ContextHelper/IsInIssetOrEmptyUnitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<?php
/**
* WordPress Coding Standard.
*
* @package WPCS\WordPressCodingStandards
* @link https://github.com/WordPress/WordPress-Coding-Standards
* @license https://opensource.org/licenses/MIT MIT
*/

namespace WordPressCS\WordPress\Tests\Helpers\ContextHelper;

use PHPCSUtils\TestUtils\UtilityMethodTestCase;
use WordPressCS\WordPress\Helpers\ContextHelper;

/**
* Tests for the `ContextHelper::is_in_isset_or_empty()` utility method.
*
* @since 3.4.0
*
* @covers \WordPressCS\WordPress\Helpers\ContextHelper::is_in_isset_or_empty
*/
final class IsInIssetOrEmptyUnitTest extends UtilityMethodTestCase {

/**
* Test is_in_isset_or_empty().
*
* @dataProvider dataIsInIssetOrEmpty
*
* @param string $testMarker The comment which prefaces the target token in the test file.
* @param bool $expectedResult The expected return value.
*
* @return void
*/
public function testIsInIssetOrEmpty( $testMarker, $expectedResult ) {
$stackPtr = $this->getTargetToken( $testMarker, \T_VARIABLE );
$result = ContextHelper::is_in_isset_or_empty( self::$phpcsFile, $stackPtr );

$this->assertSame( $expectedResult, $result );
}

/**
* Data provider.
*
* @see testIsInIssetOrEmpty()
*
* @return array<string, array<string, bool|string>>
*/
public static function dataIsInIssetOrEmpty() {
return array(
// Cases that should return false.
'bare_variable' => array(
'testMarker' => '/* testBareVariable */',
'expectedResult' => false,
),
'other_function_call' => array(
'testMarker' => '/* testOtherFunctionCall */',
'expectedResult' => false,
),
'missing_array_param' => array(
'testMarker' => '/* testMissingArrayParam */',
'expectedResult' => false,
),
'key_param_not_array_param' => array(
'testMarker' => '/* testKeyParamNotArrayParam */',
'expectedResult' => false,
),
'partially_qualified_function' => array(
'testMarker' => '/* testPartiallyQualifiedFunction */',
'expectedResult' => false,
),
'fully_qualified_namespaced_function' => array(
'testMarker' => '/* testFullyQualifiedNamespacedFunction */',
'expectedResult' => false,
),
'namespace_relative_function' => array(
'testMarker' => '/* testNamespaceRelativeFunction */',
'expectedResult' => false,
),
'namespace_relative_sub_function' => array(
'testMarker' => '/* testNamespaceRelativeSubFunction */',
'expectedResult' => false,
),
'object_method' => array(
'testMarker' => '/* testObjectMethod */',
'expectedResult' => false,
),
'nullsafe_object_method' => array(
'testMarker' => '/* testNullsafeObjectMethod */',
'expectedResult' => false,
),
'static_method' => array(
'testMarker' => '/* testStaticMethod */',
'expectedResult' => false,
),
'nested_non_target_function_call' => array(
'testMarker' => '/* testNestedNonTargetFunctionCall */',
'expectedResult' => false,
),
'isset_object_method' => array(
'testMarker' => '/* testIssetObjectMethod */',
'expectedResult' => false,
),
'empty_static_method' => array(
'testMarker' => '/* testEmptyStaticMethod */',
'expectedResult' => false,
),
'isset_namespaced_function' => array(
'testMarker' => '/* testIssetNamespacedFunction */',
'expectedResult' => false,
),

// Cases that should return true.
'isset' => array(
'testMarker' => '/* testIsset */',
'expectedResult' => true,
),
'empty' => array(
'testMarker' => '/* testEmpty */',
'expectedResult' => true,
),
'unqualified_function' => array(
'testMarker' => '/* testUnqualifiedFunction */',
'expectedResult' => true,
),
'mixed_case_function' => array(
'testMarker' => '/* testMixedCaseFunction */',
'expectedResult' => true,
),
'fully_qualified_function' => array(
'testMarker' => '/* testFullyQualifiedFunction */',
'expectedResult' => true,
),
'fully_qualified_upper_case_function' => array(
'testMarker' => '/* testFullyQualifiedUpperCaseFunction */',
'expectedResult' => true,
),
'named_param_reversed_order' => array(
'testMarker' => '/* testNamedParamReversedOrder */',
'expectedResult' => true,
),
'nested_valid_function_call' => array(
'testMarker' => '/* testNestedValidFunctionCall */',
'expectedResult' => true,
),
);
}
}
1 change: 0 additions & 1 deletion WordPress/Tests/Security/NonceVerificationUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
* @since 1.0.0 This sniff has been moved from the `CSRF` category to the `Security` category.
*
* @covers \WordPressCS\WordPress\Helpers\ContextHelper::is_in_type_test
* @covers \WordPressCS\WordPress\Helpers\ContextHelper::is_in_isset_or_empty
* @covers \WordPressCS\WordPress\Helpers\ContextHelper::is_in_array_comparison
* @covers \WordPressCS\WordPress\Sniffs\Security\NonceVerificationSniff
*/
Expand Down
Loading