Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
rename option to
  • Loading branch information
Simon Mumenthaler committed Jul 16, 2024
commit 46bc4a0f7d0f8bcabb2bb58d134de0c9829c3724
10 changes: 5 additions & 5 deletions projects/testing-library/src/lib/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ComponentFixture, DeferBlockBehavior, DeferBlockState, TestBed } from '
import { Routes } from '@angular/router';
import { BoundFunction, Queries, queries, Config as dtlConfig, PrettyDOMOptions } from '@testing-library/dom';

export type SubscribeToOutputsKeysWithCallback<T> = {
export type OutputRefKeysWithCallback<T> = {
[key in keyof T as T[key] extends OutputRef<any> ? key : never]?: T[key] extends OutputRef<infer U>
? (val: U) => void
: never;
Expand Down Expand Up @@ -66,7 +66,7 @@ export interface RenderResult<ComponentType, WrapperType = ComponentType> extend
rerender: (
properties?: Pick<
RenderTemplateOptions<ComponentType>,
'componentProperties' | 'componentInputs' | 'componentOutputs' | 'subscribeToOutputs' | 'detectChangesOnRender'
'componentProperties' | 'componentInputs' | 'componentOutputs' | 'on' | 'detectChangesOnRender'
> & { partialUpdate?: boolean },
) => Promise<void>;
/**
Expand Down Expand Up @@ -211,7 +211,7 @@ export interface RenderComponentOptions<ComponentType, Q extends Queries = typeo
/**
* @description
* An object to set `@Output` properties of the component
* @deprecated use the `subscribeToOutputs` option instead. When actually wanting to override properties, use the `componentProperties` option.
* @deprecated use the `on` option instead. When it is necessary to override properties, use the `componentProperties` option.
* @default
* {}
*
Expand All @@ -237,12 +237,12 @@ export interface RenderComponentOptions<ComponentType, Q extends Queries = typeo
* @example
* const sendValue = (value) => { ... }
* await render(AppComponent, {
* subscribeToOutputs: {
* on: {
* send: (_v:any) => void
* }
* })
*/
subscribeToOutputs?: SubscribeToOutputsKeysWithCallback<ComponentType>;
on?: OutputRefKeysWithCallback<ComponentType>;

/**
* @description
Expand Down
18 changes: 9 additions & 9 deletions projects/testing-library/src/lib/testing-library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {
RenderComponentOptions,
RenderResult,
RenderTemplateOptions,
SubscribeToOutputsKeysWithCallback,
OutputRefKeysWithCallback,
} from './models';
import { getConfig } from './config';

Expand Down Expand Up @@ -67,7 +67,7 @@ export async function render<SutType, WrapperType = SutType>(
componentProperties = {},
componentInputs = {},
componentOutputs = {},
subscribeToOutputs = {},
on = {},
componentProviders = [],
childComponentOverrides = [],
componentImports: componentImports,
Expand Down Expand Up @@ -185,7 +185,7 @@ export async function render<SutType, WrapperType = SutType>(
properties: Partial<SutType>,
inputs: Partial<SutType>,
outputs: Partial<SutType>,
subscribeTo: SubscribeToOutputsKeysWithCallback<SutType>,
subscribeTo: OutputRefKeysWithCallback<SutType>,
): Promise<ComponentFixture<SutType>> => {
const createdFixture: ComponentFixture<SutType> = await createComponent(componentContainer);
setComponentProperties(createdFixture, properties);
Expand Down Expand Up @@ -224,7 +224,7 @@ export async function render<SutType, WrapperType = SutType>(
return createdFixture;
};

const fixture = await renderFixture(componentProperties, componentInputs, componentOutputs, subscribeToOutputs);
const fixture = await renderFixture(componentProperties, componentInputs, componentOutputs, on);

if (deferBlockStates) {
if (Array.isArray(deferBlockStates)) {
Expand All @@ -239,7 +239,7 @@ export async function render<SutType, WrapperType = SutType>(
const rerender = async (
properties?: Pick<
RenderTemplateOptions<SutType>,
'componentProperties' | 'componentInputs' | 'componentOutputs' | 'subscribeToOutputs' | 'detectChangesOnRender'
'componentProperties' | 'componentInputs' | 'componentOutputs' | 'on' | 'detectChangesOnRender'
> & { partialUpdate?: boolean },
) => {
const newComponentInputs = properties?.componentInputs ?? {};
Expand All @@ -262,15 +262,15 @@ export async function render<SutType, WrapperType = SutType>(
renderedOutputKeys = Object.keys(newComponentOutputs);

// first unsubscribe the no longer available or changed callback-fns
const newSubscribeToOutputs: SubscribeToOutputsKeysWithCallback<SutType> = properties?.subscribeToOutputs ?? {};
const newObservableSubscriptions: OutputRefKeysWithCallback<SutType> = properties?.on ?? {};
for (const [key, cb, subscription] of subscribedOutputs) {
// when no longer provided or when the callback has changed
if (!(key in newSubscribeToOutputs) || cb !== (newSubscribeToOutputs as any)[key]) {
if (!(key in newObservableSubscriptions) || cb !== (newObservableSubscriptions as any)[key]) {
subscription.unsubscribe();
}
}
// then subscribe the new callback-fns
subscribedOutputs = Object.entries(newSubscribeToOutputs).map(([key, cb]) => {
subscribedOutputs = Object.entries(newObservableSubscriptions).map(([key, cb]) => {
const existing = subscribedOutputs.find(([k]) => k === key);
return existing && existing[1] === cb
? existing // nothing to do
Expand Down Expand Up @@ -388,7 +388,7 @@ function setComponentInputs<SutType>(

function subscribeToComponentOutputs<SutType>(
fixture: ComponentFixture<SutType>,
listeners: SubscribeToOutputsKeysWithCallback<SutType>,
listeners: OutputRefKeysWithCallback<SutType>,
): SubscribedOutput<SutType>[] {
// with Object.entries we lose the type information of the key and callback, therefore we need to cast them
return Object.entries(listeners).map(([key, cb]) =>
Expand Down
20 changes: 10 additions & 10 deletions projects/testing-library/tests/render.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ describe('componentOutputs', () => {
});
});

describe('subscribeToOutputs', () => {
describe('on', () => {
@Component({ template: ``, standalone: true })
class TestFixtureWithEventEmitterComponent {
@Output() readonly event = new EventEmitter<void>();
Expand All @@ -205,15 +205,15 @@ describe('subscribeToOutputs', () => {

it('should subscribe passed listener to the component EventEmitter', async () => {
const spy = jest.fn();
const { fixture } = await render(TestFixtureWithEventEmitterComponent, { subscribeToOutputs: { event: spy } });
const { fixture } = await render(TestFixtureWithEventEmitterComponent, { on: { event: spy } });
fixture.componentInstance.event.emit();
expect(spy).toHaveBeenCalled();
});

it('should unsubscribe on rerender without listener', async () => {
const spy = jest.fn();
const { fixture, rerender } = await render(TestFixtureWithEventEmitterComponent, {
subscribeToOutputs: { event: spy },
on: { event: spy },
});

await rerender({});
Expand All @@ -225,10 +225,10 @@ describe('subscribeToOutputs', () => {
it('should not unsubscribe when same listener function is used on rerender', async () => {
const spy = jest.fn();
const { fixture, rerender } = await render(TestFixtureWithEventEmitterComponent, {
subscribeToOutputs: { event: spy },
on: { event: spy },
});

await rerender({ subscribeToOutputs: { event: spy } });
await rerender({ on: { event: spy } });

fixture.componentInstance.event.emit();
expect(spy).toHaveBeenCalled();
Expand All @@ -237,11 +237,11 @@ describe('subscribeToOutputs', () => {
it('should unsubscribe old and subscribe new listener function on rerender', async () => {
const firstSpy = jest.fn();
const { fixture, rerender } = await render(TestFixtureWithEventEmitterComponent, {
subscribeToOutputs: { event: firstSpy },
on: { event: firstSpy },
});

const newSpy = jest.fn();
await rerender({ subscribeToOutputs: { event: newSpy } });
await rerender({ on: { event: newSpy } });

fixture.componentInstance.event.emit();

Expand All @@ -252,7 +252,7 @@ describe('subscribeToOutputs', () => {
it('should subscribe passed listener to a derived component output', async () => {
const spy = jest.fn();
const { fixture } = await render(TestFixtureWithDerivedEventComponent, {
subscribeToOutputs: { event: spy },
on: { event: spy },
});
fireEvent.click(fixture.nativeElement);
expect(spy).toHaveBeenCalled();
Expand All @@ -261,7 +261,7 @@ describe('subscribeToOutputs', () => {
it('should subscribe passed listener to a functional component output', async () => {
const spy = jest.fn();
const { fixture } = await render(TestFixtureWithFunctionalOutputComponent, {
subscribeToOutputs: { event: spy },
on: { event: spy },
});
fixture.componentInstance.event.emit('test');
expect(spy).toHaveBeenCalledWith('test');
Expand All @@ -274,7 +274,7 @@ describe('subscribeToOutputs', () => {
}
const spy = jest.fn();
const { fixture } = await render(TestFixtureWithFunctionalDerivedEventComponent, {
subscribeToOutputs: { event: spy },
on: { event: spy },
});
fireEvent.click(fixture.nativeElement);
expect(spy).toHaveBeenCalled();
Expand Down