fix(ivy): host bindings and listeners not being inherited from undecorated classes (#30158)

Fixes `HostBinding` and `HostListener` declarations not being inherited from base classes that don't have an Angular decorator.

This PR resolves FW-1275.

PR Close #30158
This commit is contained in:
Kristiyan Kostadinov
2019-04-27 09:33:10 +02:00
committed by Andrew Kushnir
parent 164d160b22
commit 68ff2cc323
15 changed files with 365 additions and 117 deletions

View File

@ -3220,6 +3220,89 @@ describe('compiler compliance', () => {
expectEmit(result.source, expectedOutput, 'Invalid base definition');
});
it('should add ngBaseDef if a host binding is present', () => {
const files = {
app: {
'spec.ts': `
import {Component, NgModule, HostBinding} from '@angular/core';
export class BaseClass {
@HostBinding('attr.tabindex')
tabindex = -1;
}
@Component({
selector: 'my-component',
template: ''
})
export class MyComponent extends BaseClass {
}
@NgModule({
declarations: [MyComponent]
})
export class MyModule {}
`
}
};
const expectedOutput = `
// ...
BaseClass.ngBaseDef = $r3$.ɵɵdefineBase({
hostBindings: function (rf, ctx, elIndex) {
if (rf & 1) {
$r3$.ɵɵallocHostVars(1);
}
if (rf & 2) {
$r3$.ɵɵelementAttribute(elIndex, "tabindex", $r3$.ɵɵbind(ctx.tabindex));
}
}
});
// ...
`;
const result = compile(files, angularFiles);
expectEmit(result.source, expectedOutput, 'Invalid base definition');
});
it('should add ngBaseDef if a host listener is present', () => {
const files = {
app: {
'spec.ts': `
import {Component, NgModule, HostListener} from '@angular/core';
export class BaseClass {
@HostListener('mousedown', ['$event'])
handleMousedown(event: any) {}
}
@Component({
selector: 'my-component',
template: ''
})
export class MyComponent extends BaseClass {
}
@NgModule({
declarations: [MyComponent]
})
export class MyModule {}
`
}
};
const expectedOutput = `
// ...
BaseClass.ngBaseDef = $r3$.ɵɵdefineBase({
hostBindings: function (rf, ctx, elIndex) {
if (rf & 1) {
$r3$.ɵɵlistener("mousedown", function ($event) {
return ctx.handleMousedown($event);
});
}
}
});
// ...
`;
const result = compile(files, angularFiles);
expectEmit(result.source, expectedOutput, 'Invalid base definition');
});
it('should NOT add ngBaseDef if @Component is present', () => {
const files = {
app: {

View File

@ -1723,7 +1723,7 @@ describe('ngtsc behavioral tests', () => {
.toContain('Cannot have a pipe in an action expression');
});
it('should throw in case pipes are used in host listeners', () => {
it('should throw in case pipes are used in host bindings', () => {
env.tsconfig();
env.write(`test.ts`, `
import {Component} from '@angular/core';