import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
xit,
TestComponentBuilder,
asNativeElements
} from 'angular2/test_lib';
import {Injectable, Optional} from 'angular2/di';
import {QueryList} from 'angular2/core';
import {Query, ViewQuery, Component, Directive, View} from 'angular2/annotations';
import {NgIf, NgFor} from 'angular2/angular2';
import {ListWrapper, iterableToList} from 'angular2/src/facade/collection';
import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
export function main() {
BrowserDomAdapter.makeCurrent();
describe('Query API', () => {
describe("querying by directive type", () => {
it('should contain all direct child directives in the light dom',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '
' +
'' +
'';
tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => {
view.detectChanges();
expect(asNativeElements(view.componentViewChildren)).toHaveText('2|3|');
async.done();
});
}));
it('should contain all directives in the light dom when descendants flag is used',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '' +
'' +
'';
tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => {
view.detectChanges();
expect(asNativeElements(view.componentViewChildren)).toHaveText('2|3|4|');
async.done();
});
}));
it('should contain all directives in the light dom',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '' +
'' +
'';
tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => {
view.detectChanges();
expect(asNativeElements(view.componentViewChildren)).toHaveText('2|3|');
async.done();
});
}));
it('should reflect dynamically inserted directives',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template =
'' +
'' +
'';
tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => {
view.detectChanges();
expect(asNativeElements(view.componentViewChildren)).toHaveText('2|');
view.componentInstance.shouldShow = true;
view.detectChanges();
expect(asNativeElements(view.componentViewChildren)).toHaveText('2|3|');
async.done();
});
}));
it('should reflect moved directives',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template =
'' +
'' +
'';
tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => {
view.detectChanges();
expect(asNativeElements(view.componentViewChildren)).toHaveText('2|1d|2d|3d|');
view.componentInstance.list = ['3d', '2d'];
view.detectChanges();
view.detectChanges();
expect(asNativeElements(view.componentViewChildren)).toHaveText('2|3d|2d|');
async.done();
});
}));
});
describe("onChange", () => {
it('should notify query on change',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '' +
'' +
'' +
'';
tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => {
var q = view.componentViewChildren[0].getLocal("q");
view.detectChanges();
q.query.onChange(() => {
expect(q.query.first.text).toEqual("1");
expect(q.query.last.text).toEqual("2");
async.done();
});
view.componentInstance.shouldShow = true;
view.detectChanges();
});
}));
it("should notify child's query before notifying parent's query",
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '' +
'' +
'' +
'' +
'';
tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => {
var q1 = view.componentViewChildren[0].getLocal("q1");
var q2 = view.componentViewChildren[0].getLocal("q2");
var firedQ2 = false;
q2.query.onChange(() => { firedQ2 = true; });
q1.query.onChange(() => {
expect(firedQ2).toBe(true);
async.done();
});
view.detectChanges();
});
}));
});
describe("querying by var binding", () => {
it('should contain all the child directives in the light dom with the given var binding',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template =
'' +
'' +
'';
tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => {
var q = view.componentViewChildren[0].getLocal("q");
view.componentInstance.list = ['1d', '2d'];
view.detectChanges();
expect(q.query.first.text).toEqual("1d");
expect(q.query.last.text).toEqual("2d");
async.done();
});
}));
it('should support querying by multiple var bindings',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '' +
'' +
'' +
'';
tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => {
var q = view.componentViewChildren[0].getLocal("q");
view.detectChanges();
expect(q.query.first.text).toEqual("one");
expect(q.query.last.text).toEqual("two");
async.done();
});
}));
it('should reflect dynamically inserted directives',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template =
'' +
'' +
'';
tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => {
var q = view.componentViewChildren[0].getLocal("q");
view.componentInstance.list = ['1d', '2d'];
view.detectChanges();
view.componentInstance.list = ['2d', '1d'];
view.detectChanges();
expect(q.query.last.text).toEqual("1d");
async.done();
});
}));
it('should contain all the elements in the light dom with the given var binding',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '' +
'' +
'';
tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => {
var q = view.componentViewChildren[0].getLocal("q");
view.componentInstance.list = ['1d', '2d'];
view.detectChanges();
expect(q.query.first.nativeElement).toHaveText("1d");
expect(q.query.last.nativeElement).toHaveText("2d");
async.done();
});
}));
});
describe("querying in the view", () => {
it('should contain all the elements in the view with that have the given directive',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '';
tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => {
var q: NeedsViewQuery = view.componentViewChildren[0].getLocal("q");
view.detectChanges();
expect(q.query.map((d: TextDirective) => d.text)).toEqual(["1", "2", "3"]);
async.done();
});
}));
it('should query descendants in the view when the flag is used',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '';
tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => {
var q: NeedsViewQueryDesc = view.componentViewChildren[0].getLocal("q");
view.detectChanges();
expect(q.query.map((d: TextDirective) => d.text)).toEqual(["1", "2", "3", "4"]);
async.done();
});
}));
it('should include directive present on the host element',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '';
tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => {
var q: NeedsViewQuery = view.componentViewChildren[0].getLocal("q");
view.detectChanges();
expect(q.query.map((d: TextDirective) => d.text)).toEqual(["self", "1", "2", "3"]);
async.done();
});
}));
it('should reflect changes in the component',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '';
tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => {
var q: NeedsViewQueryIf = view.componentViewChildren[0].getLocal("q");
view.detectChanges();
expect(q.query.length).toBe(0);
q.show = true;
view.detectChanges();
expect(q.query.first.text).toEqual("1");
async.done();
});
}));
/* TODO(rado): fix and reenable.
it('should maintain directives in pre-order depth-first DOM order after dynamic insertion',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb:TestComponentBuilder, async) => {
var template = '';
tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => {
var q:NeedsViewQueryOrder = view.componentViewChildren[0].getLocal("q");
view.detectChanges();
expect(q.query.length).toBe(4);
expect(q.query.first.text).toEqual("1");
expect(q.query.first.text).toEqual("4");
async.done();
});
}));*/
});
});
}
@Directive({selector: '[text]', properties: ['text'], exportAs: 'textDir'})
@Injectable()
class TextDirective {
text: string;
constructor() {}
}
@Component({selector: 'needs-query'})
@View({directives: [NgFor], template: '{{dir.text}}|
'})
@Injectable()
class NeedsQuery {
query: QueryList;
constructor(@Query(TextDirective) query: QueryList) { this.query = query; }
}
@Component({selector: 'needs-query-desc'})
@View({directives: [NgFor], template: '{{dir.text}}|
'})
@Injectable()
class NeedsQueryDesc {
query: QueryList;
constructor(@Query(TextDirective, {descendants: true}) query: QueryList) {
this.query = query;
}
}
@Component({selector: 'needs-query-by-var-binding'})
@View({directives: [], template: ''})
@Injectable()
class NeedsQueryByLabel {
query: QueryList;
constructor(@Query("textLabel", {descendants: true}) query: QueryList) {
this.query = query;
}
}
@Component({selector: 'needs-query-by-var-bindings'})
@View({directives: [], template: ''})
@Injectable()
class NeedsQueryByTwoLabels {
query: QueryList;
constructor(@Query("textLabel1,textLabel2", {descendants: true}) query: QueryList) {
this.query = query;
}
}
@Component({selector: 'needs-view-query'})
@View({
directives: [TextDirective],
template: '' +
''
})
@Injectable()
class NeedsViewQuery {
query: QueryList;
constructor(@ViewQuery(TextDirective) query: QueryList) { this.query = query; }
}
@Component({selector: 'needs-view-query-desc'})
@View({
directives: [TextDirective],
template: '' +
''
})
@Injectable()
class NeedsViewQueryDesc {
query: QueryList;
constructor(@ViewQuery(TextDirective, {descendants: true}) query: QueryList) {
this.query = query;
}
}
@Component({selector: 'needs-view-query-if'})
@View({directives: [NgIf, TextDirective], template: ''})
@Injectable()
class NeedsViewQueryIf {
show: boolean;
query: QueryList;
constructor(@ViewQuery(TextDirective) query: QueryList) {
this.query = query;
this.show = false;
}
}
@Component({selector: 'needs-view-query-order'})
@View({
directives: [NgFor, TextDirective],
template: '' +
'
' +
'
;
constructor(@ViewQuery(TextDirective) query: QueryList) { this.query = query; }
}
@Component({selector: 'my-comp'})
@View({
directives: [
NeedsQuery,
NeedsQueryDesc,
NeedsQueryByLabel,
NeedsQueryByTwoLabels,
NeedsViewQuery,
NeedsViewQueryDesc,
NeedsViewQueryIf,
NeedsViewQueryOrder,
TextDirective,
NgIf,
NgFor
]
})
@Injectable()
class MyComp {
shouldShow: boolean;
list;
constructor() {
this.shouldShow = false;
this.list = ['1d', '2d', '3d'];
}
}