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

Allow mutating of decorators #5001

Open
sanderblijlevens opened this issue Sep 5, 2024 · 4 comments
Open

Allow mutating of decorators #5001

sanderblijlevens opened this issue Sep 5, 2024 · 4 comments
Labels
🚀 Feature request New feature request

Comments

@sanderblijlevens
Copy link

sanderblijlevens commented Sep 5, 2024

Is your feature request related to a problem? Please describe.
We are using strykerJS in our NestJS backend and have a lot of logic placed in decorators, for instance mapping a property from x to y. With the current version of Stryker this logic is not mutated while it would be nice to have insights in how this logic is tested.

The same problem was also described in #2415

Describe the solution you'd like
We would like the option to enable mutating decorators.

Describe alternatives you've considered
I don't see any alternatives as we are not going to change our code just for Stryker. So without this option Stryker is less valuable to us.

@sanderblijlevens sanderblijlevens added the 🚀 Feature request New feature request label Sep 5, 2024
@nicojs nicojs modified the milestone: 7.1 Sep 6, 2024
@nicojs
Copy link
Member

nicojs commented Sep 29, 2024

Hi @sanderblijlevens . Thanks for reporting this issue.

We can enable this shortly. Decorators are not supported because mutating them is break in Angular projects, where @Component() and friends need static values. When we moved from source code mutation to mutant schemata in v4 of StrykerJS, I had to remove support for mutating decorators to get it released.

Since then, we've implemented the ignore plugin type and have added an Angular specific ignore plugin earlier today (thanks @kal-rein 🙏). We can easily add ignore support for Angular decorators through this plugin.

However, it will be a breaking change, so it will require a major version bump. We can do one in October or November.

Do you want to pick this up @sanderblijlevens ?

@sanderblijlevens
Copy link
Author

sanderblijlevens commented Oct 20, 2024

Hi @nicojs,

Yes I would be happy to help but I may need some pointers. I think I found the condition that ignores all decorators in the babel-transformer.ts. If I remove the isDecorator condition I see a lot of tests failing, as expected. From this point I can probably update the angular-ignore and ignore all the decorators that are used by angular. That means we also need to make a ignore plugin for Vue and all the other frameworks that are using decorators.

My goal with this feature request was to allow mutating of decorators but I now see there are a lot of decorators which you don't want to mutate. The list of decorators you don't want to mutate is probably way longer than the list that you do want to mutate. (for NestJS alone I expect around the 50 decorators) So do we really want to make this a blacklist and have a ignore plugin for all de different frameworks? Maybe a whitelist makes more sense in this case?

@nicojs
Copy link
Member

nicojs commented Oct 22, 2024

That means we also need to make a ignore plugin for Vue and all the other frameworks that are using decorators.

Why? Only Angular uses decorators AFAIK.

My goal with this feature request was to allow mutating of decorators but I now see there are a lot of decorators which you don't want to mutate. The list of decorators you don't want to mutate is probably way longer than the list that you do want to mutate. (for NestJS alone I expect around the 50 decorators)

You can and should test your NestJS decorators, so mutating them should be fine. I would also want to mutate @Component and friends in Angular, but that isn't possible because the Angular Compiler expects them to be static values.

StrykerJS underneath uses Mutant schemata, or mutant switching. This means this:

@Component({ selector: 'my-counter', template: '{{count}}' })
export class CounterComponent {
}

Will be mutated like this:

@Component({ selector: global.__stryker__.activeMutant === '1' ? '':  'my-counter', template: global.__stryker__.activeMutant === '2' ? '' : '{{count}}' })
export class CounterComponent {
}

And this results in the error about static values:

  Unable to evaluate this expression statically.

    src/main.ts:4:91:
      4 │ ...:  'my-app', template: global.__stryker__.activeMutant === '2' ?...
        ╵                           ~~~~~~~~~~~~~~~~~~

Yes I would be happy to help but I may need some pointers

Sure, how can I help? Your intuition is correct, remove the isDecorator check in the babel-transformer.ts and move it to the Angular ignore plugin.

@nicojs
Copy link
Member

nicojs commented Oct 22, 2024

Note that the reason Angular's compiler crashes isn't because dynamic values like this aren't supported in JavaScript or TypeScript. They are. However, Angular uses its own compiler that hooks into the TS compiler and they need the values to be static.

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

No branches or pull requests

2 participants