Skip to content

Commit

Permalink
docs: add example for output and model (#443)
Browse files Browse the repository at this point in the history
  • Loading branch information
timdeschryver committed Apr 8, 2024
1 parent c079865 commit 8897b49
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,73 @@
import { render, screen } from '@testing-library/angular';
import { SignalInputComponent } from './22-signal-inputs.component';
import userEvent from '@testing-library/user-event';

test('works with signal inputs', async () => {
await render(SignalInputComponent, {
componentInputs: {
greeting: 'Hello',
name: 'world',
},
});

expect(screen.getByText(/hello world/i)).toBeInTheDocument();
});

test('can update signal inputs', async () => {
const { fixture } = await render(SignalInputComponent, {
componentInputs: {
greeting: 'Hello',
name: 'world',
},
});

expect(screen.getByText(/hello world/i)).toBeInTheDocument();

fixture.componentInstance.name.set('updated');
// set doesn't trigger change detection within the test, findBy is needed to update the template
expect(await screen.findByText(/hello updated/i)).toBeInTheDocument();
// it's not recommended to access the model directly, but it's possible
expect(fixture.componentInstance.name()).toBe('updated');
});

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');
});

test('model update also updates the template', async () => {
const { fixture } = await render(SignalInputComponent, {
componentInputs: {
greeting: 'Hello',
name: 'initial',
},
});

expect(screen.getByText(/hello initial/i)).toBeInTheDocument();

await userEvent.clear(screen.getByRole('textbox'));
await userEvent.type(screen.getByRole('textbox'), 'updated');

expect(screen.getByText(/hello updated/i)).toBeInTheDocument();
expect(fixture.componentInstance.name()).toBe('updated');

fixture.componentInstance.name.set('new value');
// set doesn't trigger change detection within the test, findBy is needed to update the template
expect(await screen.findByText(/hello new value/i)).toBeInTheDocument();
// it's not recommended to access the model directly, but it's possible
expect(fixture.componentInstance.name()).toBe('new value');
});

test('works with signal inputs and rerenders', async () => {
Expand Down
17 changes: 14 additions & 3 deletions apps/example-app/src/app/examples/22-signal-inputs.component.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
import { Component, input } from '@angular/core';
import { Component, input, model, output } from '@angular/core';
import { FormsModule } from '@angular/forms';

@Component({
selector: 'app-signal-input',
template: ` {{ greetings() }} {{ name() }} `,
template: `
<div>{{ greetings() }} {{ name() }}</div>
<button (click)="submitName()">Submit</button>
<input type="text" [(ngModel)]="name" />
`,
standalone: true,
imports: [FormsModule],
})
export class SignalInputComponent {
greetings = input<string>('', {
alias: 'greeting',
});
name = input.required<string>();
name = model.required<string>();
submit = output<string>();

submitName() {
this.submit.emit(this.name());
}
}

0 comments on commit 8897b49

Please sign in to comment.