-
Notifications
You must be signed in to change notification settings - Fork 551
Fix #13963 with unit tests. #4786
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
base: 2.1.x
Are you sure you want to change the base?
Conversation
|
Hi, I think you're not handling correctly the flag for non-string value I recommend you to add test for You certainly need to do the check you did but after a toString call. |
|
Thanks for your feedback! I added some cases and tried to be as precise as I could on type expectations. I feel like it's starting to get too complex when going deeper on union types. I'm not feeling fluent enough with PHPStan's API but I did my best. Again, tell me if I got something wrong here 😉 |
|
I feel like it could be simpler to look for something like with Some existing tests will fail, but I think it's an improvement. to fix. This is something related to (I think) |
|
I think you could try something like https://github.com/phpstan/phpstan-src/compare/2.1.x...VincentLanglet:phpstan-src:fix/filter_var?expand=1 with all your existing tests @niconoe- |
|
Thank you very much for your feedback! I'm giving it a try right now. I'm just curious about this snippet: In the EDIT: nvm, I got it. Aim is to remove any kind of StringType more specific than just a StringType, like an AccessoryNonEmptyStringType for instance, and replace it by a general StringType. This is due to possible sanitations when using flags that will remove unwanted chars from a non-empty-string that could lead to empty strings, and as we don't know, we infer the general StringType. |
|
I tried your proposal and I got 141 errors because of I think this is due to Forcing the input type as a String only matters when having the flag |
It's certainly because of the Maybe you'll have less failure to fix with https://github.com/phpstan/phpstan-src/compare/2.1.x...VincentLanglet:phpstan-src:fix/filter_var_2?expand=1 |
I figured this out too, but I kept the new method I had to fix the remaining failling unit test about |
|
I really don't understand why the unit tests are not passing on PHP 7.4 only and why the actual results differ from the expectations. The behavior of filter_var remained unchanged AFAIK. For the other errors on the pipeline, there are issues about things I did not impact, and memory limit troubles. For both of them, I don't know if I have something to do. |
tests/PHPStan/Analyser/nsrt/filter-var-returns-non-empty-string.php
Outdated
Show resolved
Hide resolved
tests/PHPStan/Analyser/nsrt/filter-var-returns-non-empty-string.php
Outdated
Show resolved
Hide resolved
|
About Mutation testing, I don't get how could I kill both kind of mutations like this: and when Therefore, I don't think such mutation is relevant IMO. And about other failing tests, this is about memory_limit so, I'm not sure I could do something to be fair. |
|
For Maybe some of the other condition can be checked the same way. |
|
I added unit tests with all combinations of types I got on this unit test file and I added I'm gonna need some time to fix this. |
|
@VincentLanglet I added unit tests with all types and anyOf all types + mixed, which helped into getting even more precise retun types, but some mutants are still alive. I'm not sure how I could kill them by tests. Do you have any ideas about it? Thanks a lot! |
I'm not fully familiar with all those mutation testing errors, I think this is something introduced by @staabm. |
|
Is there a way to run the mutation testing locally so I could give it a try to find how to kill the mutants? I really wish this PR not to be ignored because of this 😅 Any advice you could give @staabm ? Thanks a lot! |
|
#4524 adds a way to run mutation tests locally. sometimes its also useful to apply a mutant manual locally, run the test-suite and make sure it fails with the mutated code. when mutations happen on TrinaryLogic object (most |
…_EMPTY_STRING_NULL.
|
I gave it a try by manually append your modifications from #4524 into my branch but since I rebased the 2.1.x branch this morning, I'm experiancing the following error on almost every unit test I could run:
I can't even run the unit tests only for the class I changed to reduce the scope so I guess I'm blocked for now. |
|
Make sure to run |
|
The You might have more success with Ubuntu or Debian images. Alpine is very minimalX |
|
|
||
| if ($in->isBoolean()->yes() || $in->isFloat()->yes() || $in->isInteger()->yes() || $in->isNull()->yes()) { | ||
| return $in->toString(); | ||
| if ($this->canStringBeSanitized($filterValue, $flagsType)->no()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me, this mutation is a false-positive: the method canStringBeSanitized, in this context, is the exact same value than the TernaryLogic about the FILTER_FLAG_STRIP_* checks. But the problem is that such ternary logic is maybe only when the $flagsType is a non-constant array, and such case is marked as ignored as "Too complicated" (line 150).
Therefore, in this particular context, the canStringBeSanitized returns TernaryLogic::yes or TernaryLogic::no, but can never return TernaryLogic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're right here, the canStringBeSanitized return type could be changed to bool?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was my feeling too, but I only found out how to make it this morning. Changes just have been pushed. Thanks 🙂
| if ( | ||
| $exactType === null | ||
| || $hasOptions->maybe() | ||
| || ($this->isValidationFilter($filterValue) && (!$inputType->equals($type) && $inputType->isSuperTypeOf($type)->yes())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the 2 mutations here, I don't know how to kill them.
I want to find a data-set where only the $inputType->isSuperTypeOf($type)->yes() part toogles, which implies that such data-set must produce the following statements:
$exactTypeis notnull$hasOptions->maybe()isfalse(not a big deal)$this->isValidationFilter($filterValue) istrue`$inputType->equals($type)isfalse.
Also, as the body of this if statement implies a possible change of the $type to return by adding it the $defaultType, it means that $exactType must not be $defaultType too (or the whole condition would have no effect, and mutants are still alive).
Now, regarding how $exactType is set to something different from defaultType and $this->isValidationFilter(…) must be true, the data-set MUST be via filter_var(???, FILTER_VALIDATE_(BOOLEAN|INT|FLOAT), ???)
(Please note that my PR was only about caring of the flag FILTER_FLAG_EMPTY_STRING_NULL which has no effect when used along one of the 3 validators identified, so I'm pretty sure the mutants to kill are not alive due to my changes, but anyway, let's say I'm a mutant killer 😆 )
About FILTER_VALIDATE_BOOLEAN, as we don't want $exactType to be $defaultType, the only data-set possible to search is when $in IS a boolean. Such situation produce that $exactType === $inputType === $type, therefore $inputType->equals($type) is always true. So this filterValue does not allow me to kill the mutant (no data-set possible).
About FILTER_VALIDATE_FLOAT, searched data-set would be $in is true or an integer (float would lead to the same outcome than any boolean with FILTER_VALIDATE_BOOLEAN and null would lead to $defaultType). In such data-set, $exactType (and therefore, $type) would be a Float or a ConstantFloat. But as $inputType as true is never a super-type of ConstantFloat, nor $inputType as int is never a super-type of Float, there is no way to toogle $inputType->isSuperTypeOf($type)->yes() from any possible data-set. This leads to a dead-end.
Finally, about FILTER_VALIDATE_INT, long story short, $exactType is a different type from $inputType or $defaultType only when:
$in === true=> implies$typeto be a ConstantInteger andtrueis never a super-type of a constant integer, therefore no data-set is possible$in is a floatwhich value matches its "integer" value => implies$typeto be an integer and a float is never a super-type of an integer, therefore no sata-set is possible$in is a numerical constant string=> implies$typeto be an integer and a string is never a super-type of an integer, therefore no data-set is possible.
I really do have the feeling that finding a data-set that could kill the mutants is not possible here 😢 .

Fixes phpstan/phpstan#13963