refactor(ivy): move exports tests to acceptance (#30157)
PR Close #30157
This commit is contained in:
parent
54d4105264
commit
3cf318b498
|
@ -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'})
|
||||
|
|
|
@ -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>`);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue