-
-
Notifications
You must be signed in to change notification settings - Fork 154
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
Leave only one element in the non empty returned array #735
Conversation
d617c5b
to
6d1cb40
Compare
I was thinking maybe we could use |
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.
👍
Thank you @sanmai & @BackEndTea |
public function getCollection() : array | ||
{ | ||
$collection = [1, 2, 3]; | ||
return count($collection) > 1 ? array_slice($collection, 0, 1, true) : $collection; |
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.
The fact that the mutation produces a conditional statement opens up the possibility of false positives. At the code execution time, depending on the size of the collection, the mutation may or may not effectively happen but it will also be counted as such.
Some collections have one element by design. For instance, all sorts of JSON-based API responses that have one top-level element:
{
"response": { /* ... */}
}
The code that consumes this API and the corresponding tests don't expect any other elements in the collection, therefore the mutation (that effectively doesn't change anything) passes.
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.
Agree. And this is where the user can disable mutator for particular line, method or completely for the project.
Do you have any suggestions here?
This mutator is useful for the opposite scenario, where we are working with e.g. Doctrine repositories and expect > 1 elements in the returned array.
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.
This mutator is useful for the opposite scenario, where we are working with e.g. Doctrine repositories and expect > 1 elements in the returned array.
Do you mean that they expect more than one item but only check the first one? Shouldn't the ArrayItemRemoval
mutation flag such tests?
Do you have any suggestions here?
Judging by the documentation, this is the only mutation that generates a conditional, one branch of which is the same as the original code. I suggest to avoid that and make sure the code is mutated unconditionally (however it's still not clear how it's different from ArrayItemRemoval
).
Alternatively, the mutated code, instead of returning the one-element collection as is could throw an exception indicating that the mutation didn't happen and shouldn't be counted.
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.
Shouldn't the
ArrayItemRemoval
mutation flag such tests?
ArrayItemRemoval
mutates the raw arrays, not variables. When you literally have ['a' => 1, 2, 3, 'd' => 4]
for example.
This mutator, ArrayOneItem
, mutates returned array
variables. That's the difference.
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.
Indeed, even item removal cannot be done unconditionally. You cannot remove it from an empty array. Still, throwing an exception on an unsuccessful mutation should help avoid false positives.
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.
even item removal cannot be done unconditionally. You cannot remove it from an empty array
we don't mutate empty array with ArrayItermRemoval
mutator :) So there are no conditions.
Still, throwing an exception on an unsuccessful mutation should help avoid false positives.
Do you have false-positives with ArrayOneItem
mutator because of conditions? What is the real source code?
I'm open to change it to throw an exception, just need more information about real cases and then we can create issue and discuss farther / implement.
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.
we don't mutate empty array with
ArrayItermRemoval
mutator :) So there are no conditions.
That's the thing. You can see if the array literal is empty at mutation time and avoid false positives but you cannot do the same with a variable.
Do you have false-positives with
ArrayOneItem
mutator because of conditions? What is the real source code?
Yes. See morozov/kih#13.
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.
I have put this into an issue so we can track this a bit better: #803
This PR:
Closes #690