fix(ivy): pipes should overwrite pipes with later entry in the pipes array (#27910)

PR Close #27910
This commit is contained in:
Marc Laval 2019-01-03 15:55:01 +01:00 committed by Kara Erickson
parent 13d23f315b
commit 0bd9deb9f5
3 changed files with 46 additions and 10 deletions

View File

@ -55,7 +55,7 @@ export function pipe(index: number, pipeName: string): any {
*/ */
function getPipeDef(name: string, registry: PipeDefList | null): PipeDef<any> { function getPipeDef(name: string, registry: PipeDefList | null): PipeDef<any> {
if (registry) { if (registry) {
for (let i = 0; i < registry.length; i++) { for (let i = registry.length - 1; i >= 0; i--) {
const pipeDef = registry[i]; const pipeDef = registry[i];
if (name === pipeDef.name) { if (name === pipeDef.name) {
return pipeDef; return pipeDef;

View File

@ -963,13 +963,11 @@ class TestComp {
expect(el.children[0].injector.get(SimpleDirective).value.service).toEqual('pipeService'); 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', () => {
.it('should overwrite pipes with later entry in the pipes array', () => {
TestBed.configureTestingModule( TestBed.configureTestingModule(
{declarations: [SimpleDirective, DuplicatePipe1, DuplicatePipe2]}); {declarations: [SimpleDirective, DuplicatePipe1, DuplicatePipe2]});
const el = createComponent('<div [simpleDirective]="true | duplicatePipe"></div>'); const el = createComponent('<div [simpleDirective]="true | duplicatePipe"></div>');
expect(el.children[0].injector.get(SimpleDirective).value) expect(el.children[0].injector.get(SimpleDirective).value).toBeAnInstanceOf(DuplicatePipe2);
.toBeAnInstanceOf(DuplicatePipe2);
}); });
it('should inject ChangeDetectorRef into pipes', () => { it('should inject ChangeDetectorRef into pipes', () => {

View File

@ -39,7 +39,8 @@ describe('pipe', () => {
person = new Person(); person = new Person();
}); });
const pipes = () => [CountingPipe, MultiArgPipe, CountingImpurePipe]; const pipes =
() => [CountingPipe, MultiArgPipe, CountingImpurePipe, DuplicatePipe1, DuplicatePipe2];
it('should support interpolation', () => { it('should support interpolation', () => {
function Template(rf: RenderFlags, person: Person) { function Template(rf: RenderFlags, person: Person) {
@ -180,6 +181,21 @@ describe('pipe', () => {
expect(renderLog.log).toEqual([]); 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', () => { describe('pure', () => {
it('should call pure pipes only if the arguments change', () => { it('should call pure pipes only if the arguments change', () => {
function Template(rf: RenderFlags, person: Person) { 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 { class Person {
// TODO(issue/24571): remove '!'. // TODO(issue/24571): remove '!'.
age !: number; age !: number;