From 5ab0d03dbc0eff576f946e565d6c815312997da0 Mon Sep 17 00:00:00 2001 From: Mahdi Lazraq Date: Tue, 13 Aug 2024 19:05:51 +0200 Subject: [PATCH] fix: add support for InputSignalWithTransform in inputs property --- .../22-signal-inputs.component.spec.ts | 25 ++++++++++++------- .../examples/22-signal-inputs.component.ts | 7 +++--- projects/testing-library/src/lib/models.ts | 8 ++++-- 3 files changed, 26 insertions(+), 14 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 cb22ba6..470e639 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 @@ -7,11 +7,12 @@ test('works with signal inputs', async () => { inputs: { ...aliasedInput('greeting', 'Hello'), name: 'world', + age: '45', }, }); const inputValue = within(screen.getByTestId('input-value')); - expect(inputValue.getByText(/hello world/i)).toBeInTheDocument(); + expect(inputValue.getByText(/hello world of 45 years old/i)).toBeInTheDocument(); }); test('works with computed', async () => { @@ -19,11 +20,12 @@ test('works with computed', async () => { inputs: { ...aliasedInput('greeting', 'Hello'), name: 'world', + age: '45', }, }); const computedValue = within(screen.getByTestId('computed-value')); - expect(computedValue.getByText(/hello world/i)).toBeInTheDocument(); + expect(computedValue.getByText(/hello world of 45 years old/i)).toBeInTheDocument(); }); test('can update signal inputs', async () => { @@ -31,18 +33,19 @@ test('can update signal inputs', async () => { inputs: { ...aliasedInput('greeting', 'Hello'), name: 'world', + age: '45', }, }); const inputValue = within(screen.getByTestId('input-value')); const computedValue = within(screen.getByTestId('computed-value')); - expect(inputValue.getByText(/hello world/i)).toBeInTheDocument(); + expect(inputValue.getByText(/hello world of 45 years old/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 inputValue.findByText(/hello updated/i)).toBeInTheDocument(); - expect(await computedValue.findByText(/hello updated/i)).toBeInTheDocument(); + expect(await inputValue.findByText(/hello updated of 45 years old/i)).toBeInTheDocument(); + expect(await computedValue.findByText(/hello updated of 45 years old/i)).toBeInTheDocument(); // it's not recommended to access the model directly, but it's possible expect(fixture.componentInstance.name()).toBe('updated'); @@ -54,6 +57,7 @@ test('output emits a value', async () => { inputs: { ...aliasedInput('greeting', 'Hello'), name: 'world', + age: '45', }, on: { submit: submitFn, @@ -70,6 +74,7 @@ test('model update also updates the template', async () => { inputs: { ...aliasedInput('greeting', 'Hello'), name: 'initial', + age: '45', }, }); @@ -100,22 +105,24 @@ test('works with signal inputs, computed values, and rerenders', async () => { inputs: { ...aliasedInput('greeting', 'Hello'), name: 'world', + age: '45', }, }); 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(); + expect(inputValue.getByText(/hello world of 45 years old/i)).toBeInTheDocument(); + expect(computedValue.getByText(/hello world of 45 years old/i)).toBeInTheDocument(); await view.rerender({ inputs: { ...aliasedInput('greeting', 'bye'), name: 'test', + age: '0', }, }); - expect(inputValue.getByText(/bye test/i)).toBeInTheDocument(); - expect(computedValue.getByText(/bye test/i)).toBeInTheDocument(); + expect(inputValue.getByText(/bye test of 0 years old/i)).toBeInTheDocument(); + expect(computedValue.getByText(/bye test of 0 years old/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 ddc0c90..dfe6bd0 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,10 @@ -import { Component, computed, input, model, output } from '@angular/core'; +import { Component, computed, input, model, numberAttribute, output } from '@angular/core'; import { FormsModule } from '@angular/forms'; @Component({ selector: 'app-signal-input', template: ` -
{{ greetings() }} {{ name() }}
+
{{ greetings() }} {{ name() }} of {{ age() }} years old
{{ greetingMessage() }}
@@ -16,10 +16,11 @@ export class SignalInputComponent { greetings = input('', { alias: 'greeting', }); + age = input.required({ transform: numberAttribute }); name = model.required(); submit = output(); - greetingMessage = computed(() => `${this.greetings()} ${this.name()}`); + greetingMessage = computed(() => `${this.greetings()} ${this.name()} of ${this.age()} years old`); submitName() { this.submit.emit(this.name()); diff --git a/projects/testing-library/src/lib/models.ts b/projects/testing-library/src/lib/models.ts index f7697c5..1956728 100644 --- a/projects/testing-library/src/lib/models.ts +++ b/projects/testing-library/src/lib/models.ts @@ -1,4 +1,4 @@ -import { Type, DebugElement, EventEmitter, Signal } from '@angular/core'; +import { Type, DebugElement, EventEmitter, Signal, InputSignalWithTransform } from '@angular/core'; import { ComponentFixture, DeferBlockBehavior, DeferBlockState, TestBed } from '@angular/core/testing'; import { Routes } from '@angular/router'; import { BoundFunction, Queries, queries, Config as dtlConfig, PrettyDOMOptions } from '@testing-library/dom'; @@ -94,7 +94,11 @@ export type AliasedInputs = Record>; export type ComponentInput = | { - [P in keyof T]?: T[P] extends Signal ? U : T[P]; + [P in keyof T]?: T[P] extends InputSignalWithTransform + ? U + : T[P] extends Signal + ? U + : T[P]; } | AliasedInputs;