From 0bd9deb9f516adfd4e8d0bc9dfec52c250a18b81 Mon Sep 17 00:00:00 2001 From: Marc Laval Date: Thu, 3 Jan 2019 15:55:01 +0100 Subject: [PATCH] fix(ivy): pipes should overwrite pipes with later entry in the pipes array (#27910) PR Close #27910 --- packages/core/src/render3/pipe.ts | 2 +- .../linker/view_injector_integration_spec.ts | 14 +++---- packages/core/test/render3/pipe_spec.ts | 40 ++++++++++++++++++- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/packages/core/src/render3/pipe.ts b/packages/core/src/render3/pipe.ts index 435cd012d6..6808754c09 100644 --- a/packages/core/src/render3/pipe.ts +++ b/packages/core/src/render3/pipe.ts @@ -55,7 +55,7 @@ export function pipe(index: number, pipeName: string): any { */ function getPipeDef(name: string, registry: PipeDefList | null): PipeDef { if (registry) { - for (let i = 0; i < registry.length; i++) { + for (let i = registry.length - 1; i >= 0; i--) { const pipeDef = registry[i]; if (name === pipeDef.name) { return pipeDef; diff --git a/packages/core/test/linker/view_injector_integration_spec.ts b/packages/core/test/linker/view_injector_integration_spec.ts index 32118c32c1..d65a7b508e 100644 --- a/packages/core/test/linker/view_injector_integration_spec.ts +++ b/packages/core/test/linker/view_injector_integration_spec.ts @@ -963,14 +963,12 @@ class TestComp { expect(el.children[0].injector.get(SimpleDirective).value.service).toEqual('pipeService'); }); - fixmeIvy('FW-894: Pipes don\'t overwrite pipes with later entry in the pipes array') - .it('should overwrite pipes with later entry in the pipes array', () => { - TestBed.configureTestingModule( - {declarations: [SimpleDirective, DuplicatePipe1, DuplicatePipe2]}); - const el = createComponent('
'); - expect(el.children[0].injector.get(SimpleDirective).value) - .toBeAnInstanceOf(DuplicatePipe2); - }); + it('should overwrite pipes with later entry in the pipes array', () => { + TestBed.configureTestingModule( + {declarations: [SimpleDirective, DuplicatePipe1, DuplicatePipe2]}); + const el = createComponent('
'); + expect(el.children[0].injector.get(SimpleDirective).value).toBeAnInstanceOf(DuplicatePipe2); + }); it('should inject ChangeDetectorRef into pipes', () => { TestBed.configureTestingModule({ diff --git a/packages/core/test/render3/pipe_spec.ts b/packages/core/test/render3/pipe_spec.ts index c63c473bda..e3d31826d9 100644 --- a/packages/core/test/render3/pipe_spec.ts +++ b/packages/core/test/render3/pipe_spec.ts @@ -39,7 +39,8 @@ describe('pipe', () => { person = new Person(); }); - const pipes = () => [CountingPipe, MultiArgPipe, CountingImpurePipe]; + const pipes = + () => [CountingPipe, MultiArgPipe, CountingImpurePipe, DuplicatePipe1, DuplicatePipe2]; it('should support interpolation', () => { function Template(rf: RenderFlags, person: Person) { @@ -180,6 +181,21 @@ describe('pipe', () => { expect(renderLog.log).toEqual([]); }); + it('should support duplicates by using the later entry', () => { + function Template(rf: RenderFlags, person: Person) { + if (rf & RenderFlags.Create) { + text(0); + pipe(1, 'duplicatePipe'); + } + if (rf & RenderFlags.Update) { + textBinding(0, interpolation1('', pipeBind1(1, 1, person.name), '')); + } + } + + person.init('bob', null); + expect(renderToHtml(Template, person, 2, 3, null, pipes)).toEqual('bob from duplicate 2'); + }); + describe('pure', () => { it('should call pure pipes only if the arguments change', () => { function Template(rf: RenderFlags, person: Person) { @@ -497,6 +513,28 @@ class MultiArgPipe implements PipeTransform { }); } +@Pipe({name: 'duplicatePipe'}) +class DuplicatePipe1 implements PipeTransform { + transform(value: any) { return `${value} from duplicate 1`; } + + static ngPipeDef = definePipe({ + name: 'duplicatePipe', + type: DuplicatePipe1, + factory: function DuplicatePipe1_Factory() { return new DuplicatePipe1(); }, + }); +} + +@Pipe({name: 'duplicatePipe'}) +class DuplicatePipe2 implements PipeTransform { + transform(value: any) { return `${value} from duplicate 2`; } + + static ngPipeDef = definePipe({ + name: 'duplicatePipe', + type: DuplicatePipe2, + factory: function DuplicatePipe2_Factory() { return new DuplicatePipe2(); }, + }); +} + class Person { // TODO(issue/24571): remove '!'. age !: number;