diff --git a/apps/example-app/src/app/examples/22-signal-inputs.component.spec.ts b/apps/example-app/src/app/examples/22-signal-inputs.component.spec.ts index f2500a2..6a55e61 100644 --- a/apps/example-app/src/app/examples/22-signal-inputs.component.spec.ts +++ b/apps/example-app/src/app/examples/22-signal-inputs.component.spec.ts @@ -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 () => { diff --git a/apps/example-app/src/app/examples/22-signal-inputs.component.ts b/apps/example-app/src/app/examples/22-signal-inputs.component.ts index 2ba1619..ae1e779 100644 --- a/apps/example-app/src/app/examples/22-signal-inputs.component.ts +++ b/apps/example-app/src/app/examples/22-signal-inputs.component.ts @@ -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: ` +