chore(test): migrate remaining core tests to testcomponentbuilder

Also add a small utility function to debug element to get an
array of native elements, which works smoothly with the
toHaveText matcher.
This commit is contained in:
Julie Ralph 2015-06-23 17:02:00 -07:00
parent 1c8a58963c
commit d3dda614dd
5 changed files with 103 additions and 90 deletions

View File

@ -145,6 +145,10 @@ export function inspectElement(elementRef: ElementRef): DebugElement {
return DebugElement.create(elementRef); return DebugElement.create(elementRef);
} }
export function asNativeElements(arr: List<DebugElement>): List<any> {
return arr.map((debugEl) => debugEl.nativeElement);
}
/** /**
* @exportedAs angular2/test * @exportedAs angular2/test
*/ */

View File

@ -3,7 +3,6 @@ library angular2.test.di.integration_dart_spec;
import 'package:angular2/angular2.dart'; import 'package:angular2/angular2.dart';
import 'package:angular2/di.dart'; import 'package:angular2/di.dart';
import 'package:angular2/src/test_lib/test_bed.dart';
import 'package:angular2/test_lib.dart'; import 'package:angular2/test_lib.dart';
class MockException implements Error { class MockException implements Error {
@ -40,16 +39,16 @@ void functionThatThrowsNonError() {
main() { main() {
describe('TypeLiteral', () { describe('TypeLiteral', () {
it('should publish via appInjector', inject([ it('should publish via appInjector', inject([
TestBed, TestComponentBuilder,
AsyncTestCompleter AsyncTestCompleter
], (tb, async) { ], (tb, async) {
tb.overrideView(Dummy, new View( tb.overrideView(Dummy, new View(
template: '<type-literal-component></type-literal-component>', template: '<type-literal-component></type-literal-component>',
directives: [TypeLiteralComponent])); directives: [TypeLiteralComponent]))
tb.createView(Dummy).then((view) { .createAsync(Dummy).then((tc) {
view.detectChanges(); tc.detectChanges();
expect(view.rootNodes).toHaveText('[Hello, World]'); expect(asNativeElements(tc.componentViewChildren)).toHaveText('[Hello, World]');
async.done(); async.done();
}); });
})); }));
@ -57,28 +56,28 @@ main() {
describe('Error handling', () { describe('Error handling', () {
it('should preserve Error stack traces thrown from components', inject([ it('should preserve Error stack traces thrown from components', inject([
TestBed, TestComponentBuilder,
AsyncTestCompleter AsyncTestCompleter
], (tb, async) { ], (tb, async) {
tb.overrideView(Dummy, new View( tb.overrideView(Dummy, new View(
template: '<throwing-component></throwing-component>', template: '<throwing-component></throwing-component>',
directives: [ThrowingComponent])); directives: [ThrowingComponent]))
tb.createView(Dummy).catchError((e, stack) { .createAsync(Dummy).catchError((e, stack) {
expect(stack.toString().split('\n')[0]).toEqual(e.message); expect(stack.toString().split('\n')[0]).toEqual(e.message);
async.done(); async.done();
}); });
})); }));
it('should preserve non-Error stack traces thrown from components', inject([ it('should preserve non-Error stack traces thrown from components', inject([
TestBed, TestComponentBuilder,
AsyncTestCompleter AsyncTestCompleter
], (tb, async) { ], (tb, async) {
tb.overrideView(Dummy, new View( tb.overrideView(Dummy, new View(
template: '<throwing-component2></throwing-component2>', template: '<throwing-component2></throwing-component2>',
directives: [ThrowingComponent2])); directives: [ThrowingComponent2]))
tb.createView(Dummy).catchError((e, stack) { .createAsync(Dummy).catchError((e, stack) {
expect(stack.toString().split('\n')[0]).toEqual(e.message); expect(stack.toString().split('\n')[0]).toEqual(e.message);
async.done(); async.done();
}); });
@ -87,30 +86,30 @@ main() {
describe('Property access', () { describe('Property access', () {
it('should distinguish between map and property access', inject([ it('should distinguish between map and property access', inject([
TestBed, TestComponentBuilder,
AsyncTestCompleter AsyncTestCompleter
], (tb, async) { ], (tb, async) {
tb.overrideView(Dummy, new View( tb.overrideView(Dummy, new View(
template: '<property-access></property-access>', template: '<property-access></property-access>',
directives: [PropertyAccess])); directives: [PropertyAccess]))
tb.createView(Dummy).then((view) { .createAsync(Dummy).then((tc) {
view.detectChanges(); tc.detectChanges();
expect(view.rootNodes).toHaveText('prop:foo-prop;map:foo-map'); expect(asNativeElements(tc.componentViewChildren)).toHaveText('prop:foo-prop;map:foo-map');
async.done(); async.done();
}); });
})); }));
it('should not fallback on map access if property missing', inject([ it('should not fallback on map access if property missing', inject([
TestBed, TestComponentBuilder,
AsyncTestCompleter AsyncTestCompleter
], (tb, async) { ], (tb, async) {
tb.overrideView(Dummy, new View( tb.overrideView(Dummy, new View(
template: '<no-property-access></no-property-access>', template: '<no-property-access></no-property-access>',
directives: [NoPropertyAccess])); directives: [NoPropertyAccess]))
tb.createView(Dummy).then((view) { .createAsync(Dummy).then((tc) {
expect(() => view.detectChanges()) expect(() => tc.detectChanges())
.toThrowError(new RegExp('property not found')); .toThrowError(new RegExp('property not found'));
async.done(); async.done();
}); });
@ -119,16 +118,16 @@ main() {
describe('OnChange', () { describe('OnChange', () {
it('should be notified of changes', inject([ it('should be notified of changes', inject([
TestBed, TestComponentBuilder,
AsyncTestCompleter AsyncTestCompleter
], (tb, async) { ], (tb, async) {
tb.overrideView(Dummy, new View( tb.overrideView(Dummy, new View(
template: '''<on-change [prop]="'hello'"></on-change>''', template: '''<on-change [prop]="'hello'"></on-change>''',
directives: [OnChangeComponent])); directives: [OnChangeComponent]))
tb.createView(Dummy).then((view) { .createAsync(Dummy).then((tc) {
view.detectChanges(); tc.detectChanges();
var cmp = view.rawView.elementInjectors[0].get(OnChangeComponent); var cmp = tc.componentViewChildren[0].inject(OnChangeComponent);
expect(cmp.prop).toEqual('hello'); expect(cmp.prop).toEqual('hello');
expect(cmp.changes.containsKey('prop')).toEqual(true); expect(cmp.changes.containsKey('prop')).toEqual(true);
async.done(); async.done();

View File

@ -9,9 +9,10 @@ import {
inject, inject,
it, it,
xit, xit,
TestComponentBuilder,
asNativeElements
} from 'angular2/test_lib'; } from 'angular2/test_lib';
import {TestBed} from 'angular2/src/test_lib/test_bed';
import {Injectable, Optional} from 'angular2/di'; import {Injectable, Optional} from 'angular2/di';
import {QueryList} from 'angular2/core'; import {QueryList} from 'angular2/core';
@ -28,92 +29,98 @@ export function main() {
describe("querying by directive type", () => { describe("querying by directive type", () => {
it('should contain all direct child directives in the light dom', it('should contain all direct child directives in the light dom',
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => { inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '<div text="1"></div>' + var template = '<div text="1"></div>' +
'<needs-query text="2"><div text="3">' + '<needs-query text="2"><div text="3">' +
'<div text="too-deep"></div>' + '<div text="too-deep"></div>' +
'</div></needs-query>' + '</div></needs-query>' +
'<div text="4"></div>'; '<div text="4"></div>';
tb.createView(MyComp, {html: template}) tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => { .then((view) => {
view.detectChanges(); view.detectChanges();
expect(view.rootNodes).toHaveText('2|3|');
expect(asNativeElements(view.componentViewChildren)).toHaveText('2|3|');
async.done(); async.done();
}); });
})); }));
it('should contain all directives in the light dom when descendants flag is used', it('should contain all directives in the light dom when descendants flag is used',
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => { inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '<div text="1"></div>' + var template = '<div text="1"></div>' +
'<needs-query-desc text="2"><div text="3">' + '<needs-query-desc text="2"><div text="3">' +
'<div text="4"></div>' + '<div text="4"></div>' +
'</div></needs-query-desc>' + '</div></needs-query-desc>' +
'<div text="5"></div>'; '<div text="5"></div>';
tb.createView(MyComp, {html: template}) tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => { .then((view) => {
view.detectChanges(); view.detectChanges();
expect(view.rootNodes).toHaveText('2|3|4|'); expect(asNativeElements(view.componentViewChildren)).toHaveText('2|3|4|');
async.done(); async.done();
}); });
})); }));
it('should contain all directives in the light dom', it('should contain all directives in the light dom',
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => { inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '<div text="1"></div>' + var template = '<div text="1"></div>' +
'<needs-query text="2"><div text="3"></div></needs-query>' + '<needs-query text="2"><div text="3"></div></needs-query>' +
'<div text="4"></div>'; '<div text="4"></div>';
tb.createView(MyComp, {html: template}) tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => { .then((view) => {
view.detectChanges(); view.detectChanges();
expect(view.rootNodes).toHaveText('2|3|'); expect(asNativeElements(view.componentViewChildren)).toHaveText('2|3|');
async.done(); async.done();
}); });
})); }));
it('should reflect dynamically inserted directives', it('should reflect dynamically inserted directives',
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => { inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = var template =
'<div text="1"></div>' + '<div text="1"></div>' +
'<needs-query text="2"><div *ng-if="shouldShow" [text]="\'3\'"></div></needs-query>' + '<needs-query text="2"><div *ng-if="shouldShow" [text]="\'3\'"></div></needs-query>' +
'<div text="4"></div>'; '<div text="4"></div>';
tb.createView(MyComp, {html: template}) tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => { .then((view) => {
view.detectChanges(); view.detectChanges();
expect(view.rootNodes).toHaveText('2|'); expect(asNativeElements(view.componentViewChildren)).toHaveText('2|');
view.context.shouldShow = true; view.componentInstance.shouldShow = true;
view.detectChanges(); view.detectChanges();
expect(view.rootNodes).toHaveText('2|3|'); expect(asNativeElements(view.componentViewChildren)).toHaveText('2|3|');
async.done(); async.done();
}); });
})); }));
it('should reflect moved directives', it('should reflect moved directives',
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => { inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = var template =
'<div text="1"></div>' + '<div text="1"></div>' +
'<needs-query text="2"><div *ng-for="var i of list" [text]="i"></div></needs-query>' + '<needs-query text="2"><div *ng-for="var i of list" [text]="i"></div></needs-query>' +
'<div text="4"></div>'; '<div text="4"></div>';
tb.createView(MyComp, {html: template}) tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => { .then((view) => {
view.detectChanges(); view.detectChanges();
expect(view.rootNodes).toHaveText('2|1d|2d|3d|'); expect(asNativeElements(view.componentViewChildren)).toHaveText('2|1d|2d|3d|');
view.context.list = ['3d', '2d']; view.componentInstance.list = ['3d', '2d'];
view.detectChanges(); view.detectChanges();
view.detectChanges(); view.detectChanges();
expect(view.rootNodes).toHaveText('2|3d|2d|'); expect(asNativeElements(view.componentViewChildren)).toHaveText('2|3d|2d|');
async.done(); async.done();
}); });
@ -122,15 +129,16 @@ export function main() {
describe("onChange", () => { describe("onChange", () => {
it('should notify query on change', it('should notify query on change',
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => { inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '<needs-query #q>' + var template = '<needs-query #q>' +
'<div text="1"></div>' + '<div text="1"></div>' +
'<div *ng-if="shouldShow" text="2"></div>' + '<div *ng-if="shouldShow" text="2"></div>' +
'</needs-query>'; '</needs-query>';
tb.createView(MyComp, {html: template}) tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => { .then((view) => {
var q = view.rawView.locals.get("q"); var q = view.componentViewChildren[0].getLocal("q");
view.detectChanges(); view.detectChanges();
q.query.onChange(() => { q.query.onChange(() => {
@ -139,23 +147,24 @@ export function main() {
async.done(); async.done();
}); });
view.context.shouldShow = true; view.componentInstance.shouldShow = true;
view.detectChanges(); view.detectChanges();
}); });
})); }));
it("should notify child's query before notifying parent's query", it("should notify child's query before notifying parent's query",
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => { inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '<needs-query-desc #q1>' + var template = '<needs-query-desc #q1>' +
'<needs-query-desc #q2>' + '<needs-query-desc #q2>' +
'<div text="1"></div>' + '<div text="1"></div>' +
'</needs-query-desc>' + '</needs-query-desc>' +
'</needs-query-desc>'; '</needs-query-desc>';
tb.createView(MyComp, {html: template}) tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => { .then((view) => {
var q1 = view.rawView.locals.get("q1"); var q1 = view.componentViewChildren[0].getLocal("q1");
var q2 = view.rawView.locals.get("q2"); var q2 = view.componentViewChildren[0].getLocal("q2");
var firedQ2 = false; var firedQ2 = false;
@ -172,17 +181,18 @@ export function main() {
describe("querying by var binding", () => { describe("querying by var binding", () => {
it('should contain all the child directives in the light dom with the given var binding', it('should contain all the child directives in the light dom with the given var binding',
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => { inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = var template =
'<needs-query-by-var-binding #q>' + '<needs-query-by-var-binding #q>' +
'<div *ng-for="#item of list" [text]="item" #text-label="textDir"></div>' + '<div *ng-for="#item of list" [text]="item" #text-label="textDir"></div>' +
'</needs-query-by-var-binding>'; '</needs-query-by-var-binding>';
tb.createView(MyComp, {html: template}) tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => { .then((view) => {
var q = view.rawView.locals.get("q"); var q = view.componentViewChildren[0].getLocal("q");
view.context.list = ['1d', '2d']; view.componentInstance.list = ['1d', '2d'];
view.detectChanges(); view.detectChanges();
@ -194,15 +204,16 @@ export function main() {
})); }));
it('should support querying by multiple var bindings', it('should support querying by multiple var bindings',
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => { inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '<needs-query-by-var-bindings #q>' + var template = '<needs-query-by-var-bindings #q>' +
'<div text="one" #text-label1="textDir"></div>' + '<div text="one" #text-label1="textDir"></div>' +
'<div text="two" #text-label2="textDir"></div>' + '<div text="two" #text-label2="textDir"></div>' +
'</needs-query-by-var-bindings>'; '</needs-query-by-var-bindings>';
tb.createView(MyComp, {html: template}) tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => { .then((view) => {
var q = view.rawView.locals.get("q"); var q = view.componentViewChildren[0].getLocal("q");
view.detectChanges(); view.detectChanges();
expect(q.query.first.text).toEqual("one"); expect(q.query.first.text).toEqual("one");
@ -213,21 +224,22 @@ export function main() {
})); }));
it('should reflect dynamically inserted directives', it('should reflect dynamically inserted directives',
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => { inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = var template =
'<needs-query-by-var-binding #q>' + '<needs-query-by-var-binding #q>' +
'<div *ng-for="#item of list" [text]="item" #text-label="textDir"></div>' + '<div *ng-for="#item of list" [text]="item" #text-label="textDir"></div>' +
'</needs-query-by-var-binding>'; '</needs-query-by-var-binding>';
tb.createView(MyComp, {html: template}) tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => { .then((view) => {
var q = view.rawView.locals.get("q"); var q = view.componentViewChildren[0].getLocal("q");
view.context.list = ['1d', '2d']; view.componentInstance.list = ['1d', '2d'];
view.detectChanges(); view.detectChanges();
view.context.list = ['2d', '1d']; view.componentInstance.list = ['2d', '1d'];
view.detectChanges(); view.detectChanges();
@ -238,18 +250,19 @@ export function main() {
})); }));
it('should contain all the elements in the light dom with the given var binding', it('should contain all the elements in the light dom with the given var binding',
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => { inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template = '<needs-query-by-var-binding #q>' + var template = '<needs-query-by-var-binding #q>' +
'<div template="ng-for: #item of list">' + '<div template="ng-for: #item of list">' +
'<div #text-label>{{item}}</div>' + '<div #text-label>{{item}}</div>' +
'</div>' + '</div>' +
'</needs-query-by-var-binding>'; '</needs-query-by-var-binding>';
tb.createView(MyComp, {html: template}) tcb.overrideTemplate(MyComp, template)
.createAsync(MyComp)
.then((view) => { .then((view) => {
var q = view.rawView.locals.get("q"); var q = view.componentViewChildren[0].getLocal("q");
view.context.list = ['1d', '2d']; view.componentInstance.list = ['1d', '2d'];
view.detectChanges(); view.detectChanges();

View File

@ -9,11 +9,11 @@ import {
it, it,
xdescribe, xdescribe,
xit, xit,
TestComponentBuilder,
IS_DARTIUM IS_DARTIUM
} from 'angular2/test_lib'; } from 'angular2/test_lib';
import {ListWrapper} from 'angular2/src/facade/collection'; import {ListWrapper} from 'angular2/src/facade/collection';
import {TestBed} from 'angular2/src/test_lib/test_bed';
import { import {
Directive, Directive,
Component, Component,
@ -27,25 +27,21 @@ import * as viewAnn from 'angular2/src/core/annotations_impl/view';
export function main() { export function main() {
describe('directive lifecycle integration spec', () => { describe('directive lifecycle integration spec', () => {
var ctx;
beforeEach(() => { ctx = new MyComp(); });
it('should invoke lifecycle methods onChange > onInit > onCheck > onAllChangesDone', it('should invoke lifecycle methods onChange > onInit > onCheck > onAllChangesDone',
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => { inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tb.overrideView( tcb.overrideView(
MyComp, MyComp,
new viewAnn.View( new viewAnn.View(
{template: '<div [field]="123" lifecycle></div>', directives: [LifecycleDir]})); {template: '<div [field]="123" lifecycle></div>', directives: [LifecycleDir]}))
.createAsync(MyComp)
tb.createView(MyComp, {context: ctx}) .then((tc) => {
.then((view) => { var dir = tc.componentViewChildren[0].inject(LifecycleDir);
var dir = view.rawView.elementInjectors[0].get(LifecycleDir); tc.detectChanges();
view.detectChanges();
expect(dir.log).toEqual(["onChange", "onInit", "onCheck", "onAllChangesDone"]); expect(dir.log).toEqual(["onChange", "onInit", "onCheck", "onAllChangesDone"]);
view.detectChanges(); tc.detectChanges();
expect(dir.log).toEqual([ expect(dir.log).toEqual([
"onChange", "onChange",

View File

@ -1,5 +1,7 @@
import { import {
AsyncTestCompleter, AsyncTestCompleter,
TestComponentBuilder,
asNativeElements,
beforeEach, beforeEach,
ddescribe, ddescribe,
describe, describe,
@ -9,7 +11,6 @@ import {
it, it,
xit xit
} from 'angular2/test_lib'; } from 'angular2/test_lib';
import {TestBed} from 'angular2/src/test_lib/test_bed';
import {Directive, Component, Query, View} from 'angular2/annotations'; import {Directive, Component, Query, View} from 'angular2/annotations';
import {QueryList, NgFor} from 'angular2/angular2'; import {QueryList, NgFor} from 'angular2/angular2';
import {forwardRef, resolveForwardRef, bind, Inject} from 'angular2/di'; import {forwardRef, resolveForwardRef, bind, Inject} from 'angular2/di';
@ -18,10 +19,10 @@ import {Type} from 'angular2/src/facade/lang';
export function main() { export function main() {
describe("forwardRef integration", function() { describe("forwardRef integration", function() {
it('should instantiate components which are declared using forwardRef', it('should instantiate components which are declared using forwardRef',
inject([TestBed, AsyncTestCompleter], (tb: TestBed, async) => { inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tb.createView(App).then((view) => { tcb.createAsync(App).then((tc) => {
view.detectChanges(); tc.detectChanges();
expect(view.rootNodes).toHaveText('frame(lock)'); expect(asNativeElements(tc.componentViewChildren)).toHaveText('frame(lock)');
async.done(); async.done();
}); });
})); }));