-
Notifications
You must be signed in to change notification settings - Fork 250
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
Function chain #1907
Comments
Welcome @wolf-off to the community, I was thinking something similar before. I definitely like your idea and the way you were able to make a separate working mutator as a demo. As an outside contributor, I wonder if we could somehow make it easier or smoother to make individual mutator plugins like yours and the ideas I had proposed in PR #1891 work together. Just food for thought. Another thing is that we have separate mutator implementations for JavaScript and TypeScript, I raised discussion in #1893 to hopefully bring them together somehow. |
If you remove 1 function from chain, you will get n - 1 mutants, where n is the original chain length. If you do it for all of them, you will get (n - 1)!. I dunno if it is the best mutator, it surely would work in some cases, but in general it won't be commonly used. Instead of hard-coding it in Stryker I would rather opt for making it an optional plugin. Also consider other cases. Like: test.sort((e) => { a lot of stuff here }) test.myOwnFunction().myAnotherFunction(); |
But line like this are not popular too and we will not create too much mutants (3 here)
This chains currently are not mutated at all, just can be deleted now. |
Yea. My mistake, I used equation for all possible combinations. This mutator still will behave differently / strange in some cases. We could make list of "mutable chains", like [map, filter, sort, for each, etc.], Or check via some prototype or sth... But it's still is tricky, I dunno if it is the best idea. You might want to try and make a plugin but I really don't know if it's enough consistent for core mutator |
Previously there was request, but have not implemented |
@wolf-off thanks for opening this issue! I've discussed it with @simondel and we agree that we need these kinds of mutations. In fact, they are already implemented in some way in our Stryker.NET and Stryker4s sister projects. We should align with them on the name and call it the Method expressions mutator
Let's make the first implementation with a hardcoded list and see what the reaction is. We can always make it configurable in the future. I suggest focussing on strings and arrays first. There is some overlap between them and rxjs function names, so that's a bonus.
There are a couple more we can think of, however, they will give a lot of false positives in the form of equivalent mutants.
We will have to implement it twice for now. They do share the same tests, so its not that big of a deal. |
Agree to that ^ creating fake mutants is not good. That's also why I am a bit against this type of mutation - we have to think of lots of cases not to do silly mistake like that one ^ Creating more equivalent mutants and fake mutant for another complexity of Stryker isn't the best scenario IMHO. For each string method. What will happen if I use empty string or string only with special characters? StartsWith and endsWith - "anna". Array: |
@kmdrGroch I get the point, and I agree that creating fake mutants is probably not a good idea. However it might create for a lot of cases useful mutants. Can't we do both? Create mutants that remove the method from the chain aswel as changing it to their opposite method? I have some time for implementing these kind of functionality, so if we can agree upon a solution, I might be able to implement this. No pressure though. |
Yea, you could try. And I was thinking, that you can check, if original output is equal to mutated one, e.x [].filter() === [], and if that's a case, don't mutate, or mark it somehow that it doesn't produce a valid mutant... @nicojs your ideas about it? @wolf-off do you think it would reduce amount of equivalent mutants enough? @MrFix93 any other ideas? Do you agree? |
I undestand that Same story for [].sort/reverse/filter
["1","2","1"].reverse()
[1,1,1].filter()
["1"].some() @kmdrGroch I don't know exactly what "fake" mutants are, but if you're referring to "equivalent" mutants, I think we're safe. Removing a I do agree that it's not productive to mutate // An easy way to clear an array.
while(arr.pop()) {}
// Equivalent to:
while(arr.shift()){ }
arr.reduce((a, b) => a < b? a: b));
// Equivalent to:
arr.reduceRight((a, b) => a < b? a: b)); |
@nicojs you are right, it is totally my misunderstanding. Thanks for clarifing it. So basically we should avoid changing operations which work left - right like pop and shift, reduce, reduce right, trim left, trim right, trim. Instead, we should just remove it instead of changing i guess. Or make some double check - remove it AND replace. |
I'm preparing a PR for this feature. |
@MrFix93 Hi 👋 Do you have an update on this? |
Offcourse. The javascript mutator is implemented and tested. However, I'm struggling with the integration tests. These test do not pass as the mutation score is different (offcourse). Any thoughts on how to handle this? |
Awesome <3 You could validate if the outcome of the run is what you'd expect. If that's the case, there's no harm in updating the mutation score to the new value. |
Awesome. Will do! I'm planning to create separate pull requests for the js and ts mutators, that's not a problem right? |
That's fine by me! For adding tests, you could use the mutator-specification package. That way you will end up having the same test cases for javascript and typescript code :) |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Thanks stale, but we still want this feature. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Thanks stale, but we still want this feature. Trust me, it will be awesome! |
Yearly bump? 😅 |
It actually isn't even a lot of work. Let's make it a stretch goal for v6 😍 |
Looks like a perfect issue for me to tackle 😁 |
pipe/chain functions.
It is popular and very widespred to use pipe functions or some chains.
And very usefull to remove one call from chain to verify tests
May be it's not good for some projects and can generate some lifeless mutants,
but my experience show, that this is one of usefull mutator,
when you use array pipes or work with RxJs
I'm using this implementation
https://github.com/wolf-off/stryker-rxjs/blob/master/src/mutator/FunctionChainMutator.ts
The text was updated successfully, but these errors were encountered: