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.
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.
If you're right here, the canStringBeSanitized return type could be changed to bool?
There was a problem hiding this comment.
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.
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