Skip to content

fix(compiler): properly compile DI factories when coverage reporting is enabled#37811

Closed
JoostK wants to merge 2 commits intoangular:masterfrom
JoostK:istanbul-instrumentation-ctor
Closed

fix(compiler): properly compile DI factories when coverage reporting is enabled#37811
JoostK wants to merge 2 commits intoangular:masterfrom
JoostK:istanbul-instrumentation-ctor

Conversation

@JoostK
Copy link
Member

@JoostK JoostK commented Jun 28, 2020

When running tests with code coverage using Istanbul, the code is
instrumented with coverage reporting statements. These statements are
also inserted into synthesized constructors, preventing Angular from
properly recognizing them as synthesized constructor.

This commit extends the logic to detect synthesized constructors by
first canonicalizing the constructor's code, which strips out Istanbul's
instrumentation logic.

The tests have been extended with an input file that is being
instrumented using the babel-plugin-istanbul for both ES2015 and ES5
targets, in order to verify that the approach works for real-world
usages.

Fixes #31337

@JoostK JoostK added type: bug/fix state: WIP freq1: low severity3: broken area: core Issues related to the framework runtime workaround2: non-obvious target: patch This PR is targeted for the next patch release area: compiler Issues related to `ngc`, Angular's template compiler core: di labels Jun 28, 2020
@ngbot ngbot bot modified the milestone: needsTriage Jun 28, 2020
@sviat9440
Copy link

Any news?

@JoostK JoostK force-pushed the istanbul-instrumentation-ctor branch 3 times, most recently from 6070724 to 20c4d98 Compare October 25, 2020 13:25
@JoostK JoostK added action: review The PR is still awaiting reviews from at least one requested reviewer and removed state: WIP labels Oct 25, 2020
@JoostK JoostK marked this pull request as ready for review October 25, 2020 13:50
@pullapprove pullapprove bot requested review from IgorMinar and atscott October 25, 2020 13:50
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: this avoids pulling in the Istanbul related canonicalization logic into production logic, with the downside that testing environments need to configure it correctly. This PR does that for TestBed, but other situations are not covered. Should we just pull in the canonicalization logic here instead? That seems a bit simpler, but I'd love some feedback here.

@JoostK JoostK removed the action: review The PR is still awaiting reviews from at least one requested reviewer label May 4, 2021
@ngbot ngbot bot removed this from the needsTriage milestone May 4, 2021
@ngbot ngbot bot added this to the Backlog milestone May 4, 2021
@klemenoslaj
Copy link
Contributor

Any news on this?

@JoostK
Copy link
Member Author

JoostK commented May 12, 2021

@klemenoslaj I haven't had cycles to work on this due to v12 priorities, but I was planning to pick up on this sometime soon.

@klemenoslaj
Copy link
Contributor

@klemenoslaj I haven't had cycles to work on this due to v12 priorities, but I was planning to pick up on this sometime soon.

Thanks for a super fast reply @JoostK.
I am now setting target to ES5, but just in the tsconfig.spec.json. Is that a valid workaround?

@JoostK
Copy link
Member Author

JoostK commented May 12, 2021

@klemenoslaj I haven't had cycles to work on this due to v12 priorities, but I was planning to pick up on this sometime soon.

Thanks for a super fast reply @JoostK.
I am now setting target to ES5, but just in the tsconfig.spec.json. Is that a valid workaround?

AFAIK the problem would also occur in ES5, as the code coverage statements cause Angular to consider a constructor as manually written instead of being just a delegated constructor to the base type.

A workaround may be to always write the constructor, including all parameters and a super call in any of your own classes. This doesn't help for libraries but that shouldn't be a problem if they are AOT compiled by ngcc (and not recompiled by TestBed using override* API). This does have some bundle size impact thought.

@klemenoslaj
Copy link
Contributor

@klemenoslaj I haven't had cycles to work on this due to v12 priorities, but I was planning to pick up on this sometime soon.

Thanks for a super fast reply @JoostK.
I am now setting target to ES5, but just in the tsconfig.spec.json. Is that a valid workaround?

AFAIK the problem would also occur in ES5, as the code coverage statements cause Angular to consider a constructor as manually written instead of being just a delegated constructor to the base type.

A workaround may be to always write the constructor, including all parameters and a super call in any of your own classes. This doesn't help for libraries but that shouldn't be a problem if they are AOT compiled by ngcc (and not recompiled by TestBed using override* API). This does have some bundle size impact thought.

Interestingly, I just tested with and without es5 setup. Without it fails, with it works fine. 🤔

@JoostK JoostK force-pushed the istanbul-instrumentation-ctor branch 2 times, most recently from 4bfc814 to c0db81c Compare October 31, 2021 11:13
…is enabled

When running tests with code coverage using Istanbul, the code is
instrumented with coverage reporting statements. These statements are
also inserted into synthesized constructors, preventing Angular from
properly recognizing them as synthesized constructor.

This commit extends the logic to detect synthesized constructors by
first canonicalizing the constructor's code, which strips out Istanbul's
instrumentation logic.

The tests have been extended with an input file that is being
instrumented using the `babel-plugin-istanbul` for both ES2015 and ES5
targets, in order to verify that the approach works for real-world
usages.

Fixes angular#31337
@JoostK JoostK force-pushed the istanbul-instrumentation-ctor branch from c0db81c to 9cc5fca Compare October 31, 2021 15:12
@JoostK JoostK added the action: review The PR is still awaiting reviews from at least one requested reviewer label Oct 31, 2021
@JoostK
Copy link
Member Author

JoostK commented Oct 31, 2021

@klemenoslaj I haven't had cycles to work on this due to v12 priorities, but I was planning to pick up on this sometime soon.

Thanks for a super fast reply @JoostK.
I am now setting target to ES5, but just in the tsconfig.spec.json. Is that a valid workaround?

AFAIK the problem would also occur in ES5, as the code coverage statements cause Angular to consider a constructor as manually written instead of being just a delegated constructor to the base type.
A workaround may be to always write the constructor, including all parameters and a super call in any of your own classes. This doesn't help for libraries but that shouldn't be a problem if they are AOT compiled by ngcc (and not recompiled by TestBed using override* API). This does have some bundle size impact thought.

Interestingly, I just tested with and without es5 setup. Without it fails, with it works fine. 🤔

I have revised the PR a bit and replaced the integration test using the CLI with manually instrumenting code using babel-plugin-istanbul, which made it far easier to exercise the logic for both ES2015 and ES5. Surprisingly to me, the ES5 test passes even without the changes in this PR; so that confirms your findings for ES5. The ES5's regex is probably more lenient, allowing it to work as desired even with instrumentation instructions.

Copy link
Contributor

@petebacondarwin petebacondarwin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - a couple of suggestions.

@petebacondarwin
Copy link
Contributor

BTW - I assume that core/reflections code does not normally appear in AOT built production ivy code?

@JoostK
Copy link
Member Author

JoostK commented Oct 31, 2021

BTW - I assume that core/reflections code does not normally appear in AOT built production ivy code?

Indeed, it shouldn't. The ReflectionCapabilities should only be pulled in when using the JIT compiler.

@devversion devversion self-requested a review November 5, 2021 07:12
@JoostK JoostK added action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Nov 5, 2021
@JoostK JoostK marked this pull request as draft November 5, 2021 08:24
@JoostK
Copy link
Member Author

JoostK commented Nov 5, 2021

Converting back to draft as there may be an alternative fix that would be superior, if it works.

@JoostK
Copy link
Member Author

JoostK commented Jan 21, 2022

Closing as superseded by #44732.

@JoostK JoostK closed this Jan 21, 2022
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Feb 21, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews area: compiler Issues related to `ngc`, Angular's template compiler area: core Issues related to the framework runtime cla: yes core: di freq1: low target: patch This PR is targeted for the next patch release type: bug/fix workaround2: non-obvious

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dependency injection and class inheritance doesn't work in Angular 8 library test

6 participants