From 576c1bd6be4a08610531517fef0dc9f5c5499f81 Mon Sep 17 00:00:00 2001 From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> Date: Fri, 14 Jun 2024 19:31:10 +0200 Subject: [PATCH] docs: add computed example --- .../22-signal-inputs.component.spec.ts | 50 +++++++++++++++---- .../examples/22-signal-inputs.component.ts | 7 ++- 2 files changed, 45 insertions(+), 12 deletions(-) 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 6a55e61..113d330 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,4 +1,4 @@ -import { render, screen } from '@testing-library/angular'; +import { render, screen, within } from '@testing-library/angular'; import { SignalInputComponent } from './22-signal-inputs.component'; import userEvent from '@testing-library/user-event'; @@ -10,7 +10,20 @@ test('works with signal inputs', async () => { }, }); - expect(screen.getByText(/hello world/i)).toBeInTheDocument(); + const inputValue = within(screen.getByTestId('input-value')); + expect(inputValue.getByText(/hello world/i)).toBeInTheDocument(); +}); + +test('works with computed', async () => { + await render(SignalInputComponent, { + componentInputs: { + greeting: 'Hello', + name: 'world', + }, + }); + + const computedValue = within(screen.getByTestId('computed-value')); + expect(computedValue.getByText(/hello world/i)).toBeInTheDocument(); }); test('can update signal inputs', async () => { @@ -21,11 +34,16 @@ test('can update signal inputs', async () => { }, }); - expect(screen.getByText(/hello world/i)).toBeInTheDocument(); + const inputValue = within(screen.getByTestId('input-value')); + const computedValue = within(screen.getByTestId('computed-value')); + + expect(inputValue.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(); + expect(await inputValue.findByText(/hello updated/i)).toBeInTheDocument(); + expect(await computedValue.findByText(/hello updated/i)).toBeInTheDocument(); + // it's not recommended to access the model directly, but it's possible expect(fixture.componentInstance.name()).toBe('updated'); }); @@ -55,22 +73,29 @@ test('model update also updates the template', async () => { }, }); - expect(screen.getByText(/hello initial/i)).toBeInTheDocument(); + const inputValue = within(screen.getByTestId('input-value')); + const computedValue = within(screen.getByTestId('computed-value')); + + expect(inputValue.getByText(/hello initial/i)).toBeInTheDocument(); + expect(computedValue.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(inputValue.getByText(/hello updated/i)).toBeInTheDocument(); + expect(computedValue.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(); + expect(await inputValue.findByText(/hello new value/i)).toBeInTheDocument(); + expect(await computedValue.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 () => { +test('works with signal inputs, computed values, and rerenders', async () => { const view = await render(SignalInputComponent, { componentInputs: { greeting: 'Hello', @@ -78,7 +103,11 @@ test('works with signal inputs and rerenders', async () => { }, }); - expect(screen.getByText(/hello world/i)).toBeInTheDocument(); + const inputValue = within(screen.getByTestId('input-value')); + const computedValue = within(screen.getByTestId('computed-value')); + + expect(inputValue.getByText(/hello world/i)).toBeInTheDocument(); + expect(computedValue.getByText(/hello world/i)).toBeInTheDocument(); await view.rerender({ componentInputs: { @@ -87,5 +116,6 @@ test('works with signal inputs and rerenders', async () => { }, }); - expect(screen.getByText(/bye test/i)).toBeInTheDocument(); + expect(inputValue.getByText(/bye test/i)).toBeInTheDocument(); + expect(computedValue.getByText(/bye test/i)).toBeInTheDocument(); }); 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 ae1e779..ddc0c90 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,10 +1,11 @@ -import { Component, input, model, output } from '@angular/core'; +import { Component, computed, input, model, output } from '@angular/core'; import { FormsModule } from '@angular/forms'; @Component({ selector: 'app-signal-input', template: ` -
{{ greetings() }} {{ name() }}
+
{{ greetings() }} {{ name() }}
+
{{ greetingMessage() }}
`, @@ -18,6 +19,8 @@ export class SignalInputComponent { name = model.required(); submit = output(); + greetingMessage = computed(() => `${this.greetings()} ${this.name()}`); + submitName() { this.submit.emit(this.name()); }