feat(ivy): Add AOT handling for bare classes with Input and Output decorators (#25367)

PR Close #25367
This commit is contained in:
Ben Lesh
2018-08-07 12:04:39 -07:00
parent 26066f282e
commit a0a29fdd27
22 changed files with 483 additions and 60 deletions

View File

@ -1837,4 +1837,226 @@ describe('compiler compliance', () => {
});
});
});
describe('inherited bare classes', () => {
it('should add ngBaseDef if one or more @Input is present', () => {
const files = {
app: {
'spec.ts': `
import {Component, NgModule, Input} from '@angular/core';
export class BaseClass {
@Input()
input1 = 'test';
@Input('alias2')
input2 = 'whatever';
}
@Component({
selector: 'my-component',
template: \`<div>{{input1}} {{input2}}</div>\`
})
export class MyComponent extends BaseClass {
}
@NgModule({
declarations: [MyComponent]
})
export class MyModule {}
`
}
};
const expectedOutput = `
// ...
BaseClass.ngBaseDef = i0.ɵdefineBase({
inputs: {
input1: "input1",
input2: ["alias2", "input2"]
}
});
// ...
`;
const result = compile(files, angularFiles);
expectEmit(result.source, expectedOutput, 'Invalid base definition');
});
it('should add ngBaseDef if one or more @Output is present', () => {
const files = {
app: {
'spec.ts': `
import {Component, NgModule, Output, EventEmitter} from '@angular/core';
export class BaseClass {
@Output()
output1 = new EventEmitter<string>();
@Output()
output2 = new EventEmitter<string>();
clicked() {
this.output1.emit('test');
this.output2.emit('test');
}
}
@Component({
selector: 'my-component',
template: \`<button (click)="clicked()">Click Me</button>\`
})
export class MyComponent extends BaseClass {
}
@NgModule({
declarations: [MyComponent]
})
export class MyModule {}
`
}
};
const expectedOutput = `
// ...
BaseClass.ngBaseDef = i0.ɵdefineBase({
outputs: {
output1: "output1",
output2: "output2"
}
});
// ...
`;
const result = compile(files, angularFiles);
expectEmit(result.source, expectedOutput, 'Invalid base definition');
});
it('should add ngBaseDef if a mixture of @Input and @Output props are present', () => {
const files = {
app: {
'spec.ts': `
import {Component, NgModule, Input, Output, EventEmitter} from '@angular/core';
export class BaseClass {
@Output()
output1 = new EventEmitter<string>();
@Output()
output2 = new EventEmitter<string>();
@Input()
input1 = 'test';
@Input('whatever')
input2 = 'blah';
clicked() {
this.output1.emit('test');
this.output2.emit('test');
}
}
@Component({
selector: 'my-component',
template: \`<button (click)="clicked()">Click Me</button>\`
})
export class MyComponent extends BaseClass {
}
@NgModule({
declarations: [MyComponent]
})
export class MyModule {}
`
}
};
const expectedOutput = `
// ...
BaseClass.ngBaseDef = i0.ɵdefineBase({
inputs: {
input1: "input1",
input2: ["whatever", "input2"]
},
outputs: {
output1: "output1",
output2: "output2"
}
});
// ...
`;
const result = compile(files, angularFiles);
expectEmit(result.source, expectedOutput, 'Invalid base definition');
});
it('should NOT add ngBaseDef if @Component is present', () => {
const files = {
app: {
'spec.ts': `
import {Component, NgModule, Output, EventEmitter} from '@angular/core';
@Component({
selector: 'whatever',
template: '<button (click)="clicked()">Click {{input1}}</button>'
})
export class BaseClass {
@Output()
output1 = new EventEmitter<string>();
@Input()
input1 = 'whatever';
clicked() {
this.output1.emit('test');
}
}
@Component({
selector: 'my-component',
template: \`<div>What is this developer doing?</div>\`
})
export class MyComponent extends BaseClass {
}
@NgModule({
declarations: [MyComponent]
})
export class MyModule {}
`
}
};
const result = compile(files, angularFiles);
expect(result.source).not.toContain('ngBaseDef');
});
it('should NOT add ngBaseDef if @Directive is present', () => {
const files = {
app: {
'spec.ts': `
import {Component, Directive, NgModule, Output, EventEmitter} from '@angular/core';
@Directive({
selector: 'whatever',
})
export class BaseClass {
@Output()
output1 = new EventEmitter<string>();
@Input()
input1 = 'whatever';
clicked() {
this.output1.emit('test');
}
}
@Component({
selector: 'my-component',
template: '<button (click)="clicked()">Click {{input1}}</button>'
})
export class MyComponent extends BaseClass {
}
@NgModule({
declarations: [MyComponent]
})
export class MyModule {}
`
}
};
const result = compile(files, angularFiles);
expect(result.source).not.toContain('ngBaseDef');
});
});
});