From 08c9a21aab8e44a34d706a9a017a267bb4e675a3 Mon Sep 17 00:00:00 2001 From: Lars Neumeier <39283158+lneumeier@users.noreply.github.com> Date: Fri, 7 Feb 2025 14:40:36 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20=F0=9F=90=9B=20type=20check=20on=20compo?= =?UTF-8?q?nent=20outputs=20(#693)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow subjects as component output ✅ Closes: #689 --- .../function-output.component.spec.ts | 39 +++++++++++++++++- .../spectator/src/lib/base/dom-spectator.ts | 4 +- .../function-output.component.spec.ts | 40 ++++++++++++++++++- .../function-output.component.ts | 17 +++++++- 4 files changed, 92 insertions(+), 8 deletions(-) diff --git a/projects/spectator/jest/test/function-output/function-output.component.spec.ts b/projects/spectator/jest/test/function-output/function-output.component.spec.ts index 68dccdc1..0b948057 100644 --- a/projects/spectator/jest/test/function-output/function-output.component.spec.ts +++ b/projects/spectator/jest/test/function-output/function-output.component.spec.ts @@ -14,13 +14,30 @@ describe('FunctionOutputComponent', () => { }); it('should emit the event on button click', () => { - let output; + let output = false; spectator.output('buttonClick').subscribe((result) => (output = result)); spectator.click('button'); expect(output).toEqual(true); }); + + it('should emit the event on button click - EventEmitter', () => { + let output = false; + spectator.output('buttonClickedEvent').subscribe((result) => (output = result)); + + spectator.click('button'); + + expect(output).toEqual(true); + }); + + it('should emit the event on button click - Subject', () => { + let output = false; + spectator.output('buttonClickedSubject').subscribe((result) => (output = result)); + spectator.click('button'); + + expect(output).toEqual(true); + }); }); describe('with SpectatorHost', () => { @@ -36,12 +53,30 @@ describe('FunctionOutputComponent', () => { }); it('should emit the event on button click', () => { - let output; + let output = false; host.output('buttonClick').subscribe((result) => (output = result)); host.click('button'); expect(output).toEqual(true); }); + + it('should emit the event on button click - EventEmitter', () => { + let output = false; + host.output('buttonClickedEvent').subscribe((result) => (output = result)); + + host.click('button'); + + expect(output).toEqual(true); + }); + + it('should emit the event on button click - Subject', () => { + let output = false; + host.output('buttonClickedSubject').subscribe((result) => (output = result)); + + host.click('button'); + + expect(output).toEqual(true); + }); }); }); diff --git a/projects/spectator/src/lib/base/dom-spectator.ts b/projects/spectator/src/lib/base/dom-spectator.ts index 706b1297..dd1fdf51 100644 --- a/projects/spectator/src/lib/base/dom-spectator.ts +++ b/projects/spectator/src/lib/base/dom-spectator.ts @@ -1,7 +1,7 @@ import { DebugElement, ElementRef, EventEmitter, OutputEmitterRef, Type } from '@angular/core'; import { ComponentFixture, tick } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; -import { Observable } from 'rxjs'; +import { Observable, Subject } from 'rxjs'; import { dispatchFakeEvent, dispatchKeyboardEvent, dispatchMouseEvent, dispatchTouchEvent } from '../dispatch-events'; import { DOMSelector } from '../dom-selectors'; @@ -20,7 +20,7 @@ const KEY_UP = 'keyup'; type KeysMatchingReturnType = keyof { [P in keyof T as T[P] extends V ? P : never]: P } & keyof T; type KeysMatchingOutputFunction = KeysMatchingReturnType>; -type KeysMatchingClassicOutput = KeysMatchingReturnType>; +type KeysMatchingClassicOutput = KeysMatchingReturnType | Subject>; type KeysMatchingOutput = KeysMatchingOutputFunction | KeysMatchingClassicOutput; /** diff --git a/projects/spectator/test/function-output/function-output.component.spec.ts b/projects/spectator/test/function-output/function-output.component.spec.ts index ffadbacf..49ac48eb 100644 --- a/projects/spectator/test/function-output/function-output.component.spec.ts +++ b/projects/spectator/test/function-output/function-output.component.spec.ts @@ -1,5 +1,6 @@ import { createComponentFactory, createHostFactory, Spectator, SpectatorHost } from '@ngneat/spectator'; import { FunctionOutputComponent } from './function-output.component'; +import { fakeAsync, tick } from '@angular/core/testing'; describe('FunctionOutputComponent', () => { describe('with Spectator', () => { @@ -14,13 +15,30 @@ describe('FunctionOutputComponent', () => { }); it('should emit the event on button click', () => { - let output; + let output = false; spectator.output('buttonClick').subscribe((result) => (output = result)); spectator.click('button'); expect(output).toEqual(true); }); + + it('should emit the event on button click - EventEmitter', () => { + let output = false; + spectator.output('buttonClickedEvent').subscribe((result) => (output = result)); + + spectator.click('button'); + + expect(output).toEqual(true); + }); + + it('should emit the event on button click - Subject', () => { + let output = false; + spectator.output('buttonClickedSubject').subscribe((result) => (output = result)); + spectator.click('button'); + + expect(output).toEqual(true); + }); }); describe('with SpectatorHost', () => { @@ -36,12 +54,30 @@ describe('FunctionOutputComponent', () => { }); it('should emit the event on button click', () => { - let output; + let output = false; host.output('buttonClick').subscribe((result) => (output = result)); host.click('button'); expect(output).toEqual(true); }); + + it('should emit the event on button click - EventEmitter', () => { + let output = false; + host.output('buttonClickedEvent').subscribe((result) => (output = result)); + + host.click('button'); + + expect(output).toEqual(true); + }); + + it('should emit the event on button click - Subject', () => { + let output = false; + host.output('buttonClickedSubject').subscribe((result) => (output = result)); + + host.click('button'); + + expect(output).toEqual(true); + }); }); }); diff --git a/projects/spectator/test/function-output/function-output.component.ts b/projects/spectator/test/function-output/function-output.component.ts index 27b1a6c6..b8ad8612 100644 --- a/projects/spectator/test/function-output/function-output.component.ts +++ b/projects/spectator/test/function-output/function-output.component.ts @@ -1,10 +1,23 @@ -import { Component, input, output, ɵINPUT_SIGNAL_BRAND_WRITE_TYPE } from '@angular/core'; +import { Component, EventEmitter, input, Output, output, ɵINPUT_SIGNAL_BRAND_WRITE_TYPE } from '@angular/core'; +import { ReplaySubject } from 'rxjs'; @Component({ selector: 'app-function-output', - template: ` `, + template: ` `, standalone: true, }) export class FunctionOutputComponent { public buttonClick = output(); + + @Output() + public buttonClickedEvent = new EventEmitter(); + + @Output() + public buttonClickedSubject = new ReplaySubject(); + + protected buttonClicked(): void { + this.buttonClick.emit(true); + this.buttonClickedEvent.emit(true); + this.buttonClickedSubject.next(true); + } }