diff --git a/apps/example-app-karma/src/app/issues/issue-222.spec.ts b/apps/example-app-karma/src/app/issues/issue-222.spec.ts
index 17e9a02..5da35d4 100644
--- a/apps/example-app-karma/src/app/issues/issue-222.spec.ts
+++ b/apps/example-app-karma/src/app/issues/issue-222.spec.ts
@@ -13,16 +13,3 @@ it('https://github.com/testing-library/angular-testing-library/issues/222 with r
expect(screen.getByText('Hello Mark')).toBeTruthy();
});
-
-it('https://github.com/testing-library/angular-testing-library/issues/222 with change', async () => {
- const { change } = await render(`
Hello {{ name}}
`, {
- componentProperties: {
- name: 'Sarah',
- },
- });
-
- expect(screen.getByText('Hello Sarah')).toBeTruthy();
- await change({ name: 'Mark' });
-
- expect(screen.getByText('Hello Mark')).toBeTruthy();
-});
diff --git a/apps/example-app/src/app/examples/16-input-getter-setter.spec.ts b/apps/example-app/src/app/examples/16-input-getter-setter.spec.ts
index 53dee01..4382d85 100644
--- a/apps/example-app/src/app/examples/16-input-getter-setter.spec.ts
+++ b/apps/example-app/src/app/examples/16-input-getter-setter.spec.ts
@@ -10,20 +10,6 @@ test('should run logic in the input setter and getter', async () => {
expect(getterValueControl).toHaveTextContent('I am value from getter Angular');
});
-test('should run logic in the input setter and getter while changing', async () => {
- const { change } = await render(InputGetterSetter, { componentProperties: { value: 'Angular' } });
- const valueControl = screen.getByTestId('value');
- const getterValueControl = screen.getByTestId('value-getter');
-
- expect(valueControl).toHaveTextContent('I am value from setter Angular');
- expect(getterValueControl).toHaveTextContent('I am value from getter Angular');
-
- await change({ value: 'React' });
-
- expect(valueControl).toHaveTextContent('I am value from setter React');
- expect(getterValueControl).toHaveTextContent('I am value from getter React');
-});
-
test('should run logic in the input setter and getter while re-rendering', async () => {
const { rerender } = await render(InputGetterSetter, { componentProperties: { value: 'Angular' } });
diff --git a/projects/testing-library/src/lib/models.ts b/projects/testing-library/src/lib/models.ts
index b4babe7..0a9b78a 100644
--- a/projects/testing-library/src/lib/models.ts
+++ b/projects/testing-library/src/lib/models.ts
@@ -63,22 +63,6 @@ export interface RenderResult extend
'componentProperties' | 'componentInputs' | 'componentOutputs' | 'detectChangesOnRender'
>,
) => Promise;
- /**
- * @deprecated
- * Use rerender instead. For more info see {@link https://github.com/testing-library/angular-testing-library/issues/365 GitHub Issue}
- *
- * @description
- * Keeps the current fixture intact and invokes ngOnChanges with the updated properties.
- */
- change: (changedProperties: Partial) => void;
- /**
- * @deprecated
- * Use rerender instead. For more info see {@link https://github.com/testing-library/angular-testing-library/issues/365 GitHub Issue}
- *
- * @description
- * Keeps the current fixture intact, update the @Input properties and invoke ngOnChanges with the updated properties.
- */
- changeInput: (changedInputProperties: Partial) => void;
}
export interface RenderComponentOptions {
diff --git a/projects/testing-library/src/lib/testing-library.ts b/projects/testing-library/src/lib/testing-library.ts
index 2d492d6..5c6b0f2 100644
--- a/projects/testing-library/src/lib/testing-library.ts
+++ b/projects/testing-library/src/lib/testing-library.ts
@@ -162,32 +162,6 @@ export async function render(
}
};
- const changeInput = (changedInputProperties: Partial) => {
- if (Object.keys(changedInputProperties).length === 0) {
- return;
- }
-
- setComponentInputs(fixture, changedInputProperties);
-
- fixture.detectChanges();
- };
-
- const change = (changedProperties: Partial) => {
- if (Object.keys(changedProperties).length === 0) {
- return;
- }
-
- const changes = getChangesObj(fixture.componentInstance as Record, changedProperties);
-
- setComponentProperties(fixture, changedProperties);
-
- if (hasOnChangesHook(fixture.componentInstance)) {
- fixture.componentInstance.ngOnChanges(changes);
- }
-
- fixture.componentRef.injector.get(ChangeDetectorRef).detectChanges();
- };
-
const navigate = async (elementOrPath: Element | string, basePath = ''): Promise => {
const href = typeof elementOrPath === 'string' ? elementOrPath : elementOrPath.getAttribute('href');
const [path, params] = (basePath + href).split('?');
@@ -234,8 +208,6 @@ export async function render(
detectChanges: () => detectChanges(),
navigate,
rerender,
- change,
- changeInput,
// @ts-ignore: fixture assigned
debugElement: fixture.debugElement,
// @ts-ignore: fixture assigned
diff --git a/projects/testing-library/tests/change.spec.ts b/projects/testing-library/tests/change.spec.ts
deleted file mode 100644
index d6d30f4..0000000
--- a/projects/testing-library/tests/change.spec.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core';
-import { render, screen } from '../src/public_api';
-
-@Component({
- selector: 'atl-fixture',
- template: ` {{ firstName }} {{ lastName }} `,
-})
-class FixtureComponent {
- @Input() firstName = 'Sarah';
- @Input() lastName?: string;
-}
-
-test('changes the component with updated props', async () => {
- const { change } = await render(FixtureComponent);
- expect(screen.getByText('Sarah')).toBeInTheDocument();
-
- const firstName = 'Mark';
- change({ firstName });
-
- expect(screen.getByText(firstName)).toBeInTheDocument();
-});
-
-test('changes the component with updated props while keeping other props untouched', async () => {
- const firstName = 'Mark';
- const lastName = 'Peeters';
- const { change } = await render(FixtureComponent, {
- componentProperties: {
- firstName,
- lastName,
- },
- });
-
- expect(screen.getByText(`${firstName} ${lastName}`)).toBeInTheDocument();
-
- const firstName2 = 'Chris';
- change({ firstName: firstName2 });
-
- expect(screen.getByText(`${firstName2} ${lastName}`)).toBeInTheDocument();
-});
-
-@Component({
- selector: 'atl-fixture',
- template: ` {{ propOne }} {{ propTwo }}`,
-})
-class FixtureWithNgOnChangesComponent implements OnChanges {
- @Input() propOne = 'Init';
- @Input() propTwo = '';
-
- // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method, @typescript-eslint/no-empty-function
- ngOnChanges() {}
-}
-
-test('calls ngOnChanges on change', async () => {
- const componentInputs = { propOne: 'One', propTwo: 'Two' };
- const { change, fixture } = await render(FixtureWithNgOnChangesComponent, { componentInputs });
- const spy = jest.spyOn(fixture.componentInstance, 'ngOnChanges');
-
- expect(screen.getByText(`${componentInputs.propOne} ${componentInputs.propTwo}`)).toBeInTheDocument();
-
- const propOne = 'UpdatedOne';
- const propTwo = 'UpdatedTwo';
- change({ propOne, propTwo });
-
- expect(spy).toHaveBeenCalledTimes(1);
- expect(screen.getByText(`${propOne} ${propTwo}`)).toBeInTheDocument();
-});
-
-test('does not invoke ngOnChanges on change without props', async () => {
- const componentInputs = { propOne: 'One', propTwo: 'Two' };
- const { change, fixture } = await render(FixtureWithNgOnChangesComponent, { componentInputs });
- const spy = jest.spyOn(fixture.componentInstance, 'ngOnChanges');
-
- expect(screen.getByText(`${componentInputs.propOne} ${componentInputs.propTwo}`)).toBeInTheDocument();
-
- change({});
- expect(spy).not.toHaveBeenCalled();
-
- expect(screen.getByText(`${componentInputs.propOne} ${componentInputs.propTwo}`)).toBeInTheDocument();
-});
-@Component({
- changeDetection: ChangeDetectionStrategy.OnPush,
- selector: 'atl-fixture',
- template: ` Number
`,
-})
-class FixtureWithOnPushComponent {
- @Input() activeField = '';
-}
-
-test('update properties on change', async () => {
- const { change } = await render(FixtureWithOnPushComponent);
- const numberHtmlElementRef = screen.queryByTestId('number');
-
- expect(numberHtmlElementRef).not.toHaveClass('active');
- change({ activeField: 'number' });
- expect(numberHtmlElementRef).toHaveClass('active');
-});
diff --git a/projects/testing-library/tests/changeInputs.spec.ts b/projects/testing-library/tests/changeInputs.spec.ts
deleted file mode 100644
index 8a97082..0000000
--- a/projects/testing-library/tests/changeInputs.spec.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core';
-import { render, screen } from '../src/public_api';
-
-@Component({
- selector: 'atl-fixture',
- template: ` {{ firstName }} {{ lastName }} `,
-})
-class FixtureComponent {
- @Input() firstName = 'Sarah';
- @Input() lastName?: string;
-}
-
-test('changes the component with updated props', async () => {
- const { changeInput } = await render(FixtureComponent);
- expect(screen.getByText('Sarah')).toBeInTheDocument();
-
- const firstName = 'Mark';
- changeInput({ firstName });
-
- expect(screen.getByText(firstName)).toBeInTheDocument();
-});
-
-test('changes the component with updated props while keeping other props untouched', async () => {
- const firstName = 'Mark';
- const lastName = 'Peeters';
- const { changeInput } = await render(FixtureComponent, {
- componentInputs: {
- firstName,
- lastName,
- },
- });
-
- expect(screen.getByText(`${firstName} ${lastName}`)).toBeInTheDocument();
-
- const firstName2 = 'Chris';
- changeInput({ firstName: firstName2 });
-
- expect(screen.getByText(`${firstName2} ${lastName}`)).toBeInTheDocument();
-});
-
-@Component({
- selector: 'atl-fixture',
- template: ` {{ propOne }} {{ propTwo }}`,
-})
-class FixtureWithNgOnChangesComponent implements OnChanges {
- @Input() propOne = 'Init';
- @Input() propTwo = '';
-
- // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method, @typescript-eslint/no-empty-function
- ngOnChanges() {}
-}
-
-test('calls ngOnChanges on change', async () => {
- const componentInputs = { propOne: 'One', propTwo: 'Two' };
- const { changeInput, fixture } = await render(FixtureWithNgOnChangesComponent, { componentInputs });
- const spy = jest.spyOn(fixture.componentInstance, 'ngOnChanges');
-
- expect(screen.getByText(`${componentInputs.propOne} ${componentInputs.propTwo}`)).toBeInTheDocument();
-
- const propOne = 'UpdatedOne';
- const propTwo = 'UpdatedTwo';
- changeInput({ propOne, propTwo });
-
- expect(spy).toHaveBeenCalledTimes(1);
- expect(screen.getByText(`${propOne} ${propTwo}`)).toBeInTheDocument();
-});
-
-test('does not invoke ngOnChanges on change without props', async () => {
- const componentInputs = { propOne: 'One', propTwo: 'Two' };
- const { changeInput, fixture } = await render(FixtureWithNgOnChangesComponent, { componentInputs });
- const spy = jest.spyOn(fixture.componentInstance, 'ngOnChanges');
-
- expect(screen.getByText(`${componentInputs.propOne} ${componentInputs.propTwo}`)).toBeInTheDocument();
-
- changeInput({});
- expect(spy).not.toHaveBeenCalled();
-
- expect(screen.getByText(`${componentInputs.propOne} ${componentInputs.propTwo}`)).toBeInTheDocument();
-});
-
-@Component({
- changeDetection: ChangeDetectionStrategy.OnPush,
- selector: 'atl-fixture',
- template: ` Number
`,
-})
-class FixtureWithOnPushComponent {
- @Input() activeField = '';
-}
-
-test('update properties on change', async () => {
- const { changeInput } = await render(FixtureWithOnPushComponent);
- const numberHtmlElementRef = screen.queryByTestId('number');
-
- expect(numberHtmlElementRef).not.toHaveClass('active');
- changeInput({ activeField: 'number' });
- expect(numberHtmlElementRef).toHaveClass('active');
-});
diff --git a/projects/testing-library/tests/rerender.spec.ts b/projects/testing-library/tests/rerender.spec.ts
index a06beaf..2e5ee4c 100644
--- a/projects/testing-library/tests/rerender.spec.ts
+++ b/projects/testing-library/tests/rerender.spec.ts
@@ -35,6 +35,7 @@ test('rerenders without props', async () => {
await rerender();
expect(screen.getByText('Sarah')).toBeInTheDocument();
+ expect(ngOnChangesSpy).toHaveBeenCalledTimes(1); // one time initially and one time for rerender
});
test('rerenders the component with updated inputs', async () => {
@@ -48,6 +49,41 @@ test('rerenders the component with updated inputs', async () => {
});
test('rerenders the component with updated props and resets other props', async () => {
+ const firstName = 'Mark';
+ const lastName = 'Peeters';
+ const { rerender } = await render(FixtureComponent, {
+ componentInputs: {
+ firstName,
+ lastName,
+ },
+ });
+
+ expect(screen.getByText(`${firstName} ${lastName}`)).toBeInTheDocument();
+
+ const firstName2 = 'Chris';
+ await rerender({ componentInputs: { firstName: firstName2 } });
+
+ expect(screen.getByText(firstName2)).toBeInTheDocument();
+ expect(screen.queryByText(firstName)).not.toBeInTheDocument();
+ expect(screen.queryByText(lastName)).not.toBeInTheDocument();
+
+ expect(ngOnChangesSpy).toHaveBeenCalledTimes(2); // one time initially and one time for rerender
+ const rerenderedChanges = ngOnChangesSpy.mock.calls[1][0] as SimpleChanges;
+ expect(rerenderedChanges).toEqual({
+ lastName: {
+ previousValue: 'Peeters',
+ currentValue: undefined,
+ firstChange: false,
+ },
+ firstName: {
+ previousValue: 'Mark',
+ currentValue: 'Chris',
+ firstChange: false,
+ },
+ });
+});
+
+test('rerenders the component with updated props and resets other props with componentProperties', async () => {
const firstName = 'Mark';
const lastName = 'Peeters';
const { rerender } = await render(FixtureComponent, {