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

AssertArrayHasKey seems to be not supported #100

Open
VincentLanglet opened this issue Jun 30, 2021 · 7 comments
Open

AssertArrayHasKey seems to be not supported #100

VincentLanglet opened this issue Jun 30, 2021 · 7 comments

Comments

@VincentLanglet
Copy link
Contributor

Hi @ondrejmirtes, I just got an issue with my tests saying that an offset does not exist in an array.
I tried to add a assertArrayHasKey check, without success.

I think this assert is not handle by this plugin, am I wrong ?

I'll try to do a PR in order to add the support, I think I'll be able to copy the way isArray works.
https://github.com/phpstan/phpstan-phpunit/blob/master/src/Type/PHPUnit/Assert/AssertTypeSpecifyingExtensionHelper.php#L158

@ondrejmirtes
Copy link
Member

Yes, this should be easy enough.

@micheh
Copy link

micheh commented Jul 15, 2021

@ondrejmirtes I'm not sure it the implementation in commit 6aaff11 is complete. assertArrayHasKey accepts an ArrayObject as well and PHPUnit will use offsetExists if an object is provided, but in the commit PHPStan will only allow arrays (as it uses array_key_exists).

@ondrejmirtes
Copy link
Member

@micheh Do you have a false-positive that stems from the current implementation?

@micheh
Copy link

micheh commented Jul 15, 2021

I think at least that it stems from the current implementation.

Unit Test:

public function testArrayHasKey(): void
{
    $object = new ArrayObject(['test' => 'hello']);
    self::assertArrayHasKey('test', $object);

    $object2 = new ArrayObject(['test' => 'hello']);
    if ($object2->offsetExists('test') === false) {
        echo 'hello';
    }
}

In version 0.12.21 PHPStan now reports the error for the PHPUnit assertion ($object), but no error for the conditional ($object2):
Call to static method PHPUnit\Framework\Assert::assertArrayHasKey() with 'test' and ArrayObject<string, string> will always evaluate to false.

@VincentLanglet
Copy link
Contributor Author

According to the phpdoc
https://github.com/sebastianbergmann/phpunit/blob/adeede29ca716930efb49ebe0fe1a5cab38af9c4/src/Framework/Assert.php#L95
ArrayAccess has to be supported too indeed.

Can you provide a fix @micheh ?

@villfa
Copy link
Contributor

villfa commented May 2, 2023

To support ArrayAccess properly I think this issue has to be fixed first: phpstan/phpstan#3323

@VincentLanglet
Copy link
Contributor Author

With the current implementation,

'ArrayHasKey' => static function (Scope $scope, Arg $key, Arg $array): Expr {
return new Expr\BinaryOp\BooleanOr(
new Expr\BinaryOp\BooleanAnd(
new Expr\Instanceof_($array->value, new Name('ArrayAccess')),
new Expr\MethodCall($array->value, 'offsetExists', [$key])
),
new FuncCall(new Name('array_key_exists'), [$key, $array])
);
},

AssertArrayHasKey don't work anymore with array because of the issue phpstan/phpstan#11276

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants