-
-
Notifications
You must be signed in to change notification settings - Fork 89
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
feat: standalone pipes and legacy external modules support in angular 19 #10826
base: master
Are you sure you want to change the base?
Conversation
Tests seem to fail, any idea on that? |
This 100% fixed all the relevant issues in my project. It's an enterprise class frontend app with probably 500k LOC of frontend code, legacy AJS + A19 hybrid. We should merge your PR ASAP. |
any updates on this ? |
Hello, do you find a way to correct the failing tests @KernelFolla ? Thanks for your contribution anyway, hoping it will be merged ASAP regarding of issues linked. |
can I say I don't know how to do it? :) anyway I'll try this weekend, any suggestions and help are welcome. |
Any plans to merge this change ? |
Yes you can! 🤣 I'm not used to work with NgMocks source code and I think @satanTime or maybe an usual contributor could help on it. As I read in your changed code and in the original code, I think there is a missing concept in isStandalone function. There is no way currently for this function to know the using context of an entity (component, directive, pipe). Without this information, how NgMocks could know if an entity is standalone or not? If this function could know if the dependency tree entity to mock is declared by a Module, we could deduce that is not a standalone component. It could be summed up as : if (isEntityDeclaredInModule) { // <--- treatment for component/directive/pipe declared into module, concept currently absent
return false;
} else {
// do your current modified isStandalone treatment
} Maybe i'm wrong but as NgMocks knows the full entity dependency tree, I think you could find this information and add it to the isStandalone function (or call the isStandalone function just in "else" case). Good luck @KernelFolla 😉 |
@kheos31 To be honest I don't fully understand what you're referring to here? Could you explain it a bit more? I'm currently looking at the tests and I found something that is probably not correct in this PR. I'm trying to understand how everything works together in order to fix the code and with that the code :) |
Pipe(coreReflectPipeResolve(pipe))(mock); | ||
const meta = coreReflectPipeResolve(pipe); | ||
|
||
Pipe(decorateDeclaration(pipe, mock, meta, {}) as Pipe)(mock); |
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.
Because of the decorateDeclaration call here, the decorateMock
function will be called twice. Once inside the method and once on the line below (43). Therefore the contents of the mock object are overwritten the second time it's called and breaking the tests.
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 noticed that line 42 (the line starting with 'Pipe') appears to be redundant and could potentially be removed without consequences. I plan to verify this hypothesis tomorrow when I'll have access to the code to test this change.
anyway changes on this file are all made in order to support standalone pipes
@@ -18,4 +18,9 @@ export default (mock: AnyType<any>, source: AnyType<any>, configInput: ngMocksMo | |||
} | |||
: configInput; | |||
coreDefineProperty(mock.prototype, '__ngMocksConfig', config); | |||
if ((mock as any)?.ɵmod?.declarations) { |
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.
Hi @KernelFolla, could you maybe elaborate a bit on this piece of code? I don't fully understand the purpose of it?
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.
when mocking angular modules, this code ensures that declarations which don't explicitly specify standalone: true are marked as standalone: false
@@ -30,7 +30,7 @@ const registerTemplateMiddleware = (template: AnyType<any>, meta: Directive): vo | |||
// nothing to do | |||
} | |||
|
|||
const standalone = (meta as any).__ngMocksStandalone === true; | |||
const standalone = (meta as any).standalone === true; |
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.
Why is this part needed? It breaks the test for #4032. Locally I've reverted this line and I don't see any 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.
Honestly I don't remember, tomorrow I'll try this too, reverting on my codebase
Hello, I just said that NgMocks have to treat with the same maneer standalone components with "standalone: true" (old way) and without (Angular 19 way). NgMocks also have to treat the non standalone components differently.
It's just impossible to use a NotStandaloneComponent in another SComponent without this SComponent imports MyModule containing the NotStandaloneComponent. Dependency tree:
Thus, using NgMocks, you'll necessarily call MockModule(MyModule) in the unit test of SComponent. Doing that giving us our entry point to the tree dependency which have to be mocked, and we therefore have the information we need to deduct our "isStandalone" check. |
What if there was a parameter to make sure ngmocks knows something will not be a standalone component? We all probably know the component it is failing on and having |
In the ng-mocks-universe.ts there is a boolean value that checks if you're in the world of |
Unfortunately no, because external libraries could be "Angular 19" compatible but not migrated as "default standalone". It's the problem here, and why I suggested previous idea to manage this check. |
@KernelFolla I've pushed some of my changes here to this branch, maybe something you can take a look at as well: https://github.com/FrankMerema/ng-mocks/tree/feature/fix-pr-10826 |
this PR solves two things:
I've tested the following code in my project without issues but I'm not confident on how to run and fix tests with karma and e2e
I hope this PR somehow contributes towards the definitive solution for supporting Angular 19🙏