From 1d1338fced610d74af031ca0d5b0ee19e6936006 Mon Sep 17 00:00:00 2001 From: Pawel Kozlowski Date: Mon, 26 Jun 2023 11:36:26 +0200 Subject: [PATCH] test: binding to a mix of zone and signal inputs This commit adds a test for a case of a binding targetting multiple inputs with the same name. Test passes for both signal based components as well as a mix of zone and signal based components. --- .../signal-components/input_bindings.spec.ts | 137 ++++++++++++------ 1 file changed, 94 insertions(+), 43 deletions(-) diff --git a/packages/core/test/acceptance/signal-components/input_bindings.spec.ts b/packages/core/test/acceptance/signal-components/input_bindings.spec.ts index e594d081ae0..f3388ab357d 100644 --- a/packages/core/test/acceptance/signal-components/input_bindings.spec.ts +++ b/packages/core/test/acceptance/signal-components/input_bindings.spec.ts @@ -159,58 +159,59 @@ describe('Signal component inputs', () => { expect(fixture.nativeElement.textContent).toBe('3:3'); }); - it('should reveal dragon no 1: shared expression value for non-primitive literals', () => { - @Directive({ - selector: '[dir1]', - standalone: true, - signals: true, - }) - class Dir1 { - @Input() testInputArr = input({initialValue: []}); - @Input() - testInputObj = - input<{foo: string, bar: string}>({initialValue: {foo: 'before', bar: 'before'}}); - } + it('should evaluate expression only once when binding to multiple inputs with the same name', + () => { + @Directive({ + selector: '[dir1]', + standalone: true, + signals: true, + }) + class Dir1 { + @Input() testInputArr = input({initialValue: []}); + @Input() + testInputObj = + input<{foo: string, bar: string}>({initialValue: {foo: 'before', bar: 'before'}}); + } - @Directive({ - selector: '[dir2]', - standalone: true, - signals: true, - }) - class Dir2 { - @Input() testInputArr = input({initialValue: []}); - @Input() - testInputObj = - input<{foo: string, bar: string}>({initialValue: {foo: 'before', bar: 'before'}}); - } + @Directive({ + selector: '[dir2]', + standalone: true, + signals: true, + }) + class Dir2 { + @Input() testInputArr = input({initialValue: []}); + @Input() + testInputObj = + input<{foo: string, bar: string}>({initialValue: {foo: 'before', bar: 'before'}}); + } - @Component({ - signals: true, - template: ` + @Component({ + signals: true, + template: `
`, - imports: [Dir1, Dir2], - standalone: true, - }) - class App { - } + imports: [Dir1, Dir2], + standalone: true, + }) + class App { + } - const fixture = TestBed.createComponent(App); - fixture.detectChanges(); + const fixture = TestBed.createComponent(App); + fixture.detectChanges(); - const dir1Instance = fixture.debugElement.children[0].injector.get(Dir1); - const dir2Instance = fixture.debugElement.children[0].injector.get(Dir2); + const dir1Instance = fixture.debugElement.children[0].injector.get(Dir1); + const dir2Instance = fixture.debugElement.children[0].injector.get(Dir2); - expect(dir1Instance.testInputArr()).toEqual(['foo', 'bar']); - expect(dir2Instance.testInputArr()).toEqual(['foo', 'bar']); - expect(dir1Instance.testInputArr()).toBe(dir2Instance.testInputArr()); + expect(dir1Instance.testInputArr()).toEqual(['foo', 'bar']); + expect(dir2Instance.testInputArr()).toEqual(['foo', 'bar']); + expect(dir1Instance.testInputArr()).toBe(dir2Instance.testInputArr()); - expect(dir1Instance.testInputObj()).toEqual({foo: 'foo', bar: 'bar'}); - expect(dir2Instance.testInputObj()).toEqual({foo: 'foo', bar: 'bar'}); - expect(dir1Instance.testInputObj()).toBe(dir2Instance.testInputObj()); - }); + expect(dir1Instance.testInputObj()).toEqual({foo: 'foo', bar: 'bar'}); + expect(dir2Instance.testInputObj()).toEqual({foo: 'foo', bar: 'bar'}); + expect(dir1Instance.testInputObj()).toBe(dir2Instance.testInputObj()); + }); it('should be able to bind a variable', () => { @Component({ @@ -301,6 +302,56 @@ describe('Signal component inputs', () => { }); describe('to a mix of zone-based and signal-based targets', () => { - it('works', () => {}); + it('should evaluate expression only once when binding to multiple inputs with the same name', + () => { + @Directive({ + selector: '[dirZone]', + standalone: true, + signals: false, + }) + class DirZone { + @Input() testInputArr: string[] = []; + @Input() testInputObj = {foo: 'before', bar: 'before'}; + } + + @Directive({ + selector: '[dirSignal]', + standalone: true, + signals: true, + }) + class DirSignal { + @Input() testInputArr = input({initialValue: []}); + @Input() + testInputObj = + input<{foo: string, bar: string}>({initialValue: {foo: 'before', bar: 'before'}}); + } + + @Component({ + signals: true, + template: ` +
`, + imports: [DirZone, DirSignal], + standalone: true, + }) + class App { + } + + const fixture = TestBed.createComponent(App); + fixture.detectChanges(); + + const dirZoneInstance = fixture.debugElement.children[0].injector.get(DirZone); + const dirSignalInstance = fixture.debugElement.children[0].injector.get(DirSignal); + + expect(dirZoneInstance.testInputArr).toEqual(['foo', 'bar']); + expect(dirSignalInstance.testInputArr()).toEqual(['foo', 'bar']); + expect(dirZoneInstance.testInputArr).toBe(dirSignalInstance.testInputArr()); + + expect(dirZoneInstance.testInputObj).toEqual({foo: 'foo', bar: 'bar'}); + expect(dirSignalInstance.testInputObj()).toEqual({foo: 'foo', bar: 'bar'}); + expect(dirZoneInstance.testInputObj).toBe(dirSignalInstance.testInputObj()); + }); }); });