Skip to content

Commit

Permalink
fix: πŸ› component re-render when updating fields in lifecycle hook (#646)
Browse files Browse the repository at this point in the history
* fix: πŸ› component re-render when updating fields in lifecycle hook

* test: βœ… fix incorrect assertion after prettier bump
  • Loading branch information
kfrancois committed Mar 20, 2024
1 parent 32938c3 commit e522c99
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 5 deletions.
@@ -0,0 +1,25 @@
import { createComponentFactory, Spectator } from '@ngneat/spectator/jest';
import { NgOnChangesInputComponent } from '../../../test/ngonchanges-input/ngonchanges-input.component';

describe('NgOnChangesInputComponent', () => {
describe('with Spectator', () => {
let spectator: Spectator<NgOnChangesInputComponent>;

const createComponent = createComponentFactory({
component: NgOnChangesInputComponent,
});

beforeEach(() => {
spectator = createComponent();
});

it('should re-render when updating fields in ngOnChanges', () => {
expect(spectator.query('button')).toBeDisabled();
expect(spectator.query('button')).toHaveText('Button disabled');

spectator.setInput({ btnDisabled: false });
expect(spectator.query('button')).not.toBeDisabled();
expect(spectator.query('button')).toHaveText('Button enabled');
});
});
});
6 changes: 3 additions & 3 deletions projects/spectator/src/lib/spectator/spectator.ts
Expand Up @@ -44,11 +44,11 @@ export class Spectator<C> extends DomSpectator<C> {
public setInput<K extends keyof C>(input: K, inputValue: InferInputSignal<C[K]>): void;
public setInput(input: any, value?: any): void {
setProps(this.fixture.componentRef, input, value);
// Force cd on the tested component
this.debugElement.injector.get(ChangeDetectorRef).detectChanges();

// Force cd on the host component for cases such as: https://github.com/ngneat/spectator/issues/539
this.detectChanges();

// Force cd on the tested component
this.debugElement.injector.get(ChangeDetectorRef).detectChanges();
}

public deferBlock(deferBlockIndex = 0): DeferBlocks {
Expand Down
Expand Up @@ -15,7 +15,7 @@ describe('Matcher enhancements', () => {
const el = spectator.queryAll('.text-check');
expect(el).toHaveText(['It should', 'different text', 'another']);
expect(el).toContainText(['It should', 'different text', 'another']);
expect(el).toHaveExactText(['It should have', 'Some different text', ' And another one ']);
expect(el).toHaveExactText(['It should have', 'Some different text', 'And another one']);
expect(el).toHaveExactText(['It should have', 'Some different text', 'And another one'], { trim: true });
expect(el).toHaveExactTrimmedText(['It should have', 'Some different text', 'And another one']);
});
Expand Down
@@ -0,0 +1,25 @@
import { createComponentFactory, Spectator } from '@ngneat/spectator';
import { NgOnChangesInputComponent } from './ngonchanges-input.component';

describe('NgOnChangesInputComponent', () => {
describe('with Spectator', () => {
let spectator: Spectator<NgOnChangesInputComponent>;

const createComponent = createComponentFactory({
component: NgOnChangesInputComponent,
});

beforeEach(() => {
spectator = createComponent();
});

it('should re-render when updating fields in ngOnChanges', () => {
expect(spectator.query('button')).toBeDisabled();
expect(spectator.query('button')).toHaveText('Button disabled');

spectator.setInput({ btnDisabled: false });
expect(spectator.query('button')).not.toBeDisabled();
expect(spectator.query('button')).toHaveText('Button enabled');
});
});
});
@@ -0,0 +1,22 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';

@Component({
selector: 'app-root',
standalone: true,
template: `
<button [disabled]="btnDisabled">
{{ btnText }}
</button>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NgOnChangesInputComponent {
@Input()
btnDisabled = true;

btnText = 'Button disabled';

ngOnChanges() {
this.btnText = this.btnDisabled ? 'Button disabled' : 'Button enabled';
}
}
Expand Up @@ -30,7 +30,7 @@ describe('StandalonePipe', () => {
spectator = createPipe(`<div id="standalone">{{ thisField | standalone }}</div>`, { hostProps: { thisField: 'This' } });
});

fit('should render and execute the StandalonePipe', () => {
it('should render and execute the StandalonePipe', () => {
expect(spectator.element.querySelector('#standalone')).toContainText('This stands alone!');
});
});
Expand Down

0 comments on commit e522c99

Please sign in to comment.