fixup! fix(ivy): incorrectly remapping certain properties that refer to inputs (#28765)

PR Close #28765
This commit is contained in:
Kristiyan Kostadinov 2019-02-21 00:00:02 +01:00 committed by Igor Minar
parent 93a7836f7a
commit 32ae84da28
4 changed files with 109 additions and 160 deletions

View File

@ -137,6 +137,48 @@ describe('compiler compliance: bindings', () => {
const result = compile(files, angularFiles);
expect(result.source).not.toContain('i0.ɵelementProperty');
});
it('should not remap property names whose names do not correspond to their attribute names',
() => {
const files = {
app: {
'spec.ts': `
import {Component, NgModule} from '@angular/core';
@Component({
selector: 'my-component',
template: \`
<label [for]="forValue"></label>\`
})
export class MyComponent {
forValue = 'some-input';
}
@NgModule({declarations: [MyComponent]})
export class MyModule {}
`
}
};
const template = `
const $c0$ = [${AttributeMarker.SelectOnly}, "for"];
// ...
function MyComponent_Template(rf, ctx) {
if (rf & 1) {
$i0$.ɵelement(0, "label", _c0);
}
if (rf & 2) {
$i0$.ɵelementProperty(0, "for", $i0$.ɵbind(ctx.forValue));
}
}`;
const result = compile(files, angularFiles);
expectEmit(result.source, template, 'Incorrect template');
});
});
describe('host bindings', () => {

View File

@ -0,0 +1,63 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {Component, Input} from '@angular/core';
import {TestBed} from '@angular/core/testing';
import {By} from '@angular/platform-browser';
import {expect} from '@angular/platform-browser/testing/src/matchers';
describe('elementProperty', () => {
it('should bind to properties whose names do not correspond to their attribute names', () => {
@Component({template: '<label [for]="forValue"></label>'})
class MyComp {
forValue?: string;
}
TestBed.configureTestingModule({declarations: [MyComp]});
const fixture = TestBed.createComponent(MyComp);
const labelNode = fixture.debugElement.query(By.css('label'));
fixture.componentInstance.forValue = 'some-input';
fixture.detectChanges();
expect(labelNode.nativeElement.getAttribute('for')).toBe('some-input');
fixture.componentInstance.forValue = 'some-textarea';
fixture.detectChanges();
expect(labelNode.nativeElement.getAttribute('for')).toBe('some-textarea');
});
it('should not map properties whose names do not correspond to their attribute names, ' +
'if they correspond to inputs',
() => {
@Component({template: '', selector: 'my-comp'})
class MyComp {
@Input() for !:string;
}
@Component({template: '<my-comp [for]="forValue"></my-comp>'})
class App {
forValue?: string;
}
TestBed.configureTestingModule({declarations: [App, MyComp]});
const fixture = TestBed.createComponent(App);
const myCompNode = fixture.debugElement.query(By.directive(MyComp));
fixture.componentInstance.forValue = 'hello';
fixture.detectChanges();
expect(myCompNode.nativeElement.getAttribute('for')).toBeFalsy();
expect(myCompNode.componentInstance.for).toBe('hello');
fixture.componentInstance.forValue = 'hej';
fixture.detectChanges();
expect(myCompNode.nativeElement.getAttribute('for')).toBeFalsy();
expect(myCompNode.componentInstance.for).toBe('hej');
});
});

View File

@ -76,26 +76,6 @@ describe('elementProperty', () => {
expect(fixture.html).toEqual('<span id="_otherId_"></span>');
});
it('should map properties whose names do not correspond to their attribute names', () => {
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(0, 'label');
}
if (rf & RenderFlags.Update) {
elementProperty(0, 'for', bind(ctx.forValue));
}
}, 1, 1);
const fixture = new ComponentFixture(App);
fixture.component.forValue = 'some-input';
fixture.update();
expect(fixture.html).toEqual('<label for="some-input"></label>');
fixture.component.forValue = 'some-textarea';
fixture.update();
expect(fixture.html).toEqual('<label for="some-textarea"></label>');
});
describe('input properties', () => {
let button: MyButton;
let otherDir: OtherDir;
@ -384,50 +364,6 @@ describe('elementProperty', () => {
expect(otherDir !.id).toEqual(3);
});
it('should not map properties whose names do not correspond to their attribute names, ' +
'if they correspond to inputs',
() => {
let comp: Comp;
class Comp {
// TODO(issue/24571): remove '!'.
// clang-format off
for !: string;
// clang-format on
static ngComponentDef = defineComponent({
type: Comp,
selectors: [['comp']],
consts: 0,
vars: 0,
template: function(rf: RenderFlags, ctx: any) {},
factory: () => comp = new Comp(),
inputs: {for: 'for'}
});
}
/** <comp [for]="forValue"></comp> */
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(0, 'comp');
}
if (rf & RenderFlags.Update) {
elementProperty(0, 'for', bind(ctx.forValue));
}
}, 1, 1, [Comp]);
const fixture = new ComponentFixture(App);
fixture.component.forValue = 'hello';
fixture.update();
expect(fixture.html).toEqual(`<comp></comp>`);
expect(comp !.for).toEqual('hello');
fixture.component.forValue = 'hej';
fixture.update();
expect(fixture.html).toEqual(`<comp></comp>`);
expect(comp !.for).toEqual('hej');
});
});
describe('attributes and input properties', () => {

View File

@ -733,73 +733,9 @@ window.testBlocklist = {
"error": "Error: Expected null not to be null.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with formControl should update datepicker when formControl changes": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with formControl should update formControl when date is selected": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with formControl should disable input when form control disabled": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with formControl should disable toggle when form control disabled": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should set `aria-haspopup` on the toggle button": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should open calendar when toggle clicked": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should not open calendar when toggle clicked if datepicker is disabled": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should not open calendar when toggle clicked if input is disabled": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should set the `button` type on the trigger to prevent form submissions": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should remove the underlying SVG icon from the tab order": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should restore focus to the toggle after the calendar is closed": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should re-render when the i18n labels change": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with mat-datepicker-toggle should toggle the active state of the datepicker toggle": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with custom mat-datepicker-toggle icon should be able to override the mat-datepicker-toggle icon": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with tabindex on mat-datepicker-toggle should forward the tabindex to the underlying button": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with tabindex on mat-datepicker-toggle should clear the tabindex from the mat-datepicker-toggle host": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with tabindex on mat-datepicker-toggle should forward focus to the underlying button when the host is focused": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
"error": "Error: this._portalOutlet is undefined.",
"notes": "FW-1019: Design new API to replace static queries"
},
"MatDatepicker with MatNativeDateModule datepicker inside mat-form-field should pass the form field theme color to the overlay": {
"error": "TypeError: Cannot read property 'classList' of null",
@ -809,37 +745,9 @@ window.testBlocklist = {
"error": "TypeError: Cannot read property 'classList' of null",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with min and max dates and validation should use min and max dates specified by the input": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with min and max dates and validation should mark invalid when value is before min": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with min and max dates and validation should mark invalid when value is after max": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with min and max dates and validation should not mark invalid when value equals min": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with min and max dates and validation should not mark invalid when value equals max": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with min and max dates and validation should not mark invalid when value is between min and max": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with filter and validation should mark input invalid": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
},
"MatDatepicker with MatNativeDateModule datepicker with filter and validation should disable filtered calendar cells": {
"error": "Error: Template error: Can't bind to 'htmlFor' since it isn't a known property of 'mat-datepicker-toggle'.",
"notes": "Unknown"
"error": "Error: this._portalOutlet is undefined.",
"notes": "FW-1019: Design new API to replace static queries"
},
"MatDialog should set the proper animation states": {
"error": "TypeError: Cannot read property 'componentInstance' of null",