Closed
Description
Context
I think that there is some pains in spying on the output of a component, which is typified by the fact that you have to use type assertions by any
. It is my opinion that the cost to pay for simply subscribing to events emitted by a component and inspecting their values can be lesser.
test('output emits a value', async () => {
const submitFn = jest.fn();
await render(SignalInputComponent, {
componentInputs: {
greeting: 'Hello',
name: 'world',
},
componentOutputs: {
submit: { emit: submitFn } as any, // <==
},
});
await userEvent.click(screen.getByRole('button'));
expect(submitFn).toHaveBeenCalledWith('world');
});
Goals
- No
any
assertions in output testing scenario - Less and intuitive code to subscribe outputs
Idea
This is a pseudo code and has not been strictly validated for feasibility.
test('output emits a value', async () => {
const submitFn = jest.fn();
const { outputs } = await render(SignalInputComponent, {
componentInputs: {
greeting: 'Hello',
name: 'world',
},
});
outputs.get('submit').subscribe(submitFn);
await userEvent.click(screen.getByRole('button'));
expect(submitFn).toHaveBeenCalledWith('world');
});
- Added
outputs
to RenderResult outputs.get(name)
can get a output ref by alias-aware name
outputs.get(eventName)
The eventName
should be same to its name in HTML template, <some-cmp (eventName)="..." />
.
Angular's ComponentMirror
has outputs
getter which returns a record of propName
and tempalteName
of outputs. So I think ALT can map the eventName
to corresponding property.
https://github.com/angular/angular/blob/main/packages/core/src/render3/component.ts#L104-L139
// pseudo code to get OutputRef from eventName
function getOutputRef<C, T>(componentRef: ComponentRef<C>, eventName: string): OutputRef<T> {
const { outputs } = reflectComponentType(componentRef.componentType);
const output = outputs.find(o => o.propName === eventName);
if (output == null) {
throw new Error(`Output ${eventName} doesn't exist.`);
}
return componentRef.instance[output.templateName];
}
Metadata
Metadata
Assignees
Labels
No labels