refactor(ivy): move exports tests to acceptance (#30157)

PR Close #30157
This commit is contained in:
cexbrayat 2019-04-26 22:29:13 +02:00 committed by Andrew Kushnir
parent 54d4105264
commit 3cf318b498
2 changed files with 88 additions and 231 deletions

View File

@ -135,6 +135,86 @@ describe('exports', () => {
fixture.detectChanges();
expect(fixture.nativeElement.querySelector('span').innerHTML).toBe('First');
});
describe('forward refs', () => {
it('should work with basic text bindings', () => {
const fixture = initWithTemplate(AppComp, '{{ myInput.value}} <input value="one" #myInput>');
fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toEqual('one <input value="one">');
});
it('should work with element properties', () => {
const fixture = initWithTemplate(
AppComp, '<div [title]="myInput.value"></div> <input value="one" #myInput>');
fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toEqual('<div title="one"></div><input value="one">');
});
it('should work with element attrs', () => {
const fixture = initWithTemplate(
AppComp, '<div [attr.aria-label]="myInput.value"></div> <input value="one" #myInput>');
fixture.detectChanges();
expect(fixture.nativeElement.innerHTML)
.toEqual('<div aria-label="one"></div><input value="one">');
});
it('should work with element classes', () => {
const fixture = initWithTemplate(
AppComp,
'<div [class.red]="myInput.checked"></div> <input type="checkbox" checked #myInput>');
fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toContain('<div class="red"></div>');
});
it('should work with component refs', () => {
const fixture = initWithTemplate(
AppComp, '<div [dirWithInput]="myComp"></div><comp-to-ref #myComp></comp-to-ref>');
fixture.detectChanges();
const dirWithInput = fixture.debugElement.children[0].injector.get(DirWithCompInput);
const myComp = fixture.debugElement.children[1].injector.get(ComponentToReference);
expect(dirWithInput.comp).toEqual(myComp);
});
it('should work with multiple forward refs', () => {
const fixture = initWithTemplate(
AppComp,
'{{ myInput.value }} {{ myComp.name }} <comp-to-ref #myComp></comp-to-ref> <input value="one" #myInput>');
fixture.detectChanges();
expect(fixture.nativeElement.innerHTML)
.toEqual('one Nancy <comp-to-ref></comp-to-ref><input value="one">');
});
it('should support local refs in nested dynamic views', () => {
const fixture = initWithTemplate(AppComp, `
<input value="one" #outerInput>
<div *ngIf="outer">
{{ outerInput.value }}
<input value = "two" #innerInput>
<div *ngIf="inner">
{{ outerInput.value }} - {{ innerInput.value}}
</div>
</div>
`);
fixture.detectChanges();
fixture.componentInstance.outer = true;
fixture.componentInstance.inner = true;
fixture.detectChanges();
// result should be <input value="one"><div>one <input value="two"><div>one - two</div></div>
// but contains bindings comments for ngIf
// so we check the outer div
expect(fixture.nativeElement.innerHTML).toContain('one <input value="two">');
// and the inner div
expect(fixture.nativeElement.innerHTML).toContain('one - two');
});
});
});
function initWithTemplate(compType: Type<any>, template: string) {
@ -149,6 +229,8 @@ class ComponentToReference {
@Component({selector: 'app-comp', template: ``})
class AppComp {
outer = false;
inner = false;
}
@Directive({selector: '[dir]', exportAs: 'dir'})

View File

@ -6,176 +6,20 @@
* found in the LICENSE file at https://angular.io/license
*/
import {AttributeMarker, ɵɵdefineComponent, ɵɵdefineDirective} from '../../src/render3/index';
import {ɵɵbind, ɵɵcontainer, ɵɵcontainerRefreshEnd, ɵɵcontainerRefreshStart, ɵɵelement, ɵɵelementAttribute, ɵɵelementClassProp, ɵɵelementEnd, ɵɵelementProperty, ɵɵelementStart, ɵɵelementStyling, ɵɵelementStylingApply, ɵɵembeddedViewEnd, ɵɵembeddedViewStart, ɵɵinterpolation2, ɵɵnextContext, ɵɵreference, ɵɵtemplate, ɵɵtext, ɵɵtextBinding} from '../../src/render3/instructions/all';
import {ɵɵbind, ɵɵcontainer, ɵɵcontainerRefreshEnd, ɵɵcontainerRefreshStart, ɵɵelement, ɵɵelementEnd, ɵɵelementStart, ɵɵembeddedViewEnd, ɵɵembeddedViewStart, ɵɵreference, ɵɵtext, ɵɵtextBinding} from '../../src/render3/instructions/all';
import {RenderFlags} from '../../src/render3/interfaces/definition';
import {NgIf} from './common_with_def';
import {ComponentFixture, createComponent, renderToHtml} from './render_util';
import {ComponentFixture, createComponent} from './render_util';
describe('exports', () => {
// For basic use cases, see core/test/acceptance/exports_spec.ts.
describe('forward refs', () => {
it('should work with basic text bindings', () => {
/** {{ myInput.value}} <input value="one" #myInput> */
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
ɵɵtext(0);
ɵɵelement(1, 'input', ['value', 'one'], ['myInput', '']);
}
if (rf & RenderFlags.Update) {
const tmp = ɵɵreference(2) as any;
ɵɵtextBinding(0, ɵɵbind(tmp.value));
}
}, 3, 1);
const fixture = new ComponentFixture(App);
expect(fixture.html).toEqual('one<input value="one">');
});
it('should work with element properties', () => {
/** <div [title]="myInput.value"</div> <input value="one" #myInput> */
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
ɵɵelement(0, 'div');
ɵɵelement(1, 'input', ['value', 'one'], ['myInput', '']);
}
if (rf & RenderFlags.Update) {
const tmp = ɵɵreference(2) as any;
ɵɵelementProperty(0, 'title', ɵɵbind(tmp.value));
}
}, 3, 1);
const fixture = new ComponentFixture(App);
expect(fixture.html).toEqual('<div title="one"></div><input value="one">');
});
it('should work with element attrs', () => {
/** <div [attr.aria-label]="myInput.value"</div> <input value="one" #myInput> */
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
ɵɵelement(0, 'div');
ɵɵelement(1, 'input', ['value', 'one'], ['myInput', '']);
}
if (rf & RenderFlags.Update) {
const tmp = ɵɵreference(2) as any;
ɵɵelementAttribute(0, 'aria-label', ɵɵbind(tmp.value));
}
}, 3, 1);
const fixture = new ComponentFixture(App);
expect(fixture.html).toEqual('<div aria-label="one"></div><input value="one">');
});
it('should work with element classes', () => {
/** <div [class.red]="myInput.checked"</div> <input type="checkbox" checked #myInput> */
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
ɵɵelementStart(0, 'div', [AttributeMarker.Classes, 'red']);
ɵɵelementStyling(['red']);
ɵɵelementEnd();
ɵɵelement(1, 'input', ['type', 'checkbox', 'checked', 'true'], ['myInput', '']);
}
if (rf & RenderFlags.Update) {
const tmp = ɵɵreference(2) as any;
ɵɵelementClassProp(0, 0, tmp.checked);
ɵɵelementStylingApply(0);
}
}, 3);
const fixture = new ComponentFixture(App);
expect(fixture.html).toEqual('<div class="red"></div><input checked="true" type="checkbox">');
});
it('should work with component refs', () => {
let myComponent: MyComponent;
let myDir: MyDir;
class MyComponent {
constructor() { myComponent = this; }
static ngComponentDef = ɵɵdefineComponent({
type: MyComponent,
selectors: [['comp']],
consts: 0,
vars: 0,
template: function(rf: RenderFlags, ctx: MyComponent) {},
factory: () => new MyComponent
});
}
class MyDir {
// TODO(issue/24571): remove '!'.
myDir !: MyComponent;
constructor() { myDir = this; }
static ngDirectiveDef = ɵɵdefineDirective({
type: MyDir,
selectors: [['', 'myDir', '']],
factory: () => new MyDir,
inputs: {myDir: 'myDir'}
});
}
/** <div [myDir]="myComp"></div><comp #myComp></comp> */
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
ɵɵelement(0, 'div', ['myDir', '']);
ɵɵelement(1, 'comp', null, ['myComp', '']);
}
if (rf & RenderFlags.Update) {
const tmp = ɵɵreference(2) as any;
ɵɵelementProperty(0, 'myDir', ɵɵbind(tmp));
}
}, 3, 1, [MyComponent, MyDir]);
const fixture = new ComponentFixture(App);
expect(myDir !.myDir).toEqual(myComponent !);
});
it('should work with multiple forward refs', () => {
let myComponent: MyComponent;
class MyComponent {
name = 'Nancy';
constructor() { myComponent = this; }
static ngComponentDef = ɵɵdefineComponent({
type: MyComponent,
selectors: [['comp']],
consts: 0,
vars: 0,
template: function() {},
factory: () => new MyComponent
});
}
/** {{ myInput.value }} {{ myComp.name }} <comp #myComp></comp> <input value="one" #myInput>
*/
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
ɵɵtext(0);
ɵɵtext(1);
ɵɵelement(2, 'comp', null, ['myComp', '']);
ɵɵelement(4, 'input', ['value', 'one'], ['myInput', '']);
}
if (rf & RenderFlags.Update) {
const tmp1 = ɵɵreference(3) as any;
const tmp2 = ɵɵreference(5) as any;
ɵɵtextBinding(0, ɵɵbind(tmp2.value));
ɵɵtextBinding(1, ɵɵbind(tmp1.name));
}
}, 6, 2, [MyComponent]);
const fixture = new ComponentFixture(App);
expect(fixture.html).toEqual('oneNancy<comp></comp><input value="one">');
});
/**
* This test needs to be moved to acceptance/exports_spec.ts
* when Ivy compiler supports inline views.
*/
it('should work inside a view container', () => {
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
@ -214,74 +58,5 @@ describe('exports', () => {
fixture.update();
expect(fixture.html).toEqual('<div></div>');
});
it('should support local refs in nested dynamic views', () => {
/**
* <input value="one" #outerInput>
* <div *ngIf="outer">
* {{ outerInput.value }}
*
* <input value = "two" #innerInput>
*
* <div *ngIf="inner">
* {{ outerInput.value }} - {{ innerInput.value}}
* </div>
* </div>
*/
const App = createComponent('app', function(rf: RenderFlags, app: any) {
if (rf & RenderFlags.Create) {
ɵɵelementStart(0, 'input', ['value', 'one'], ['outerInput', '']);
ɵɵelementEnd();
ɵɵtemplate(2, outerTemplate, 5, 2, 'div', [AttributeMarker.Template, 'ngIf']);
}
if (rf & RenderFlags.Update) {
ɵɵelementProperty(2, 'ngIf', ɵɵbind(app.outer));
}
}, 3, 1, [NgIf]);
function outerTemplate(rf: RenderFlags, outer: any) {
if (rf & RenderFlags.Create) {
ɵɵelementStart(0, 'div');
{
ɵɵtext(1);
ɵɵelementStart(2, 'input', ['value', 'two'], ['innerInput', '']);
ɵɵelementEnd();
ɵɵtemplate(4, innerTemplate, 2, 2, 'div', [AttributeMarker.Template, 'ngIf']);
}
ɵɵelementEnd();
}
if (rf & RenderFlags.Update) {
const app = ɵɵnextContext();
const outerInput = ɵɵreference(1) as any;
ɵɵtextBinding(1, ɵɵbind(outerInput.value));
ɵɵelementProperty(4, 'ngIf', ɵɵbind(app.inner));
}
}
function innerTemplate(rf: RenderFlags, inner: any) {
if (rf & RenderFlags.Create) {
ɵɵelementStart(0, 'div');
{ ɵɵtext(1); }
ɵɵelementEnd();
}
if (rf & RenderFlags.Update) {
ɵɵnextContext();
const innerInput = ɵɵreference(3) as any;
ɵɵnextContext();
const outerInput = ɵɵreference(1) as any;
ɵɵtextBinding(1, ɵɵinterpolation2('', outerInput.value, ' - ', innerInput.value, ''));
}
}
const fixture = new ComponentFixture(App);
fixture.component.outer = true;
fixture.component.inner = true;
fixture.update();
expect(fixture.html)
.toEqual(`<input value="one"><div>one<input value="two"><div>one - two</div></div>`);
});
});
});