refactor(core): ts’ify tests
This commit is contained in:
@@ -114,5 +114,5 @@ export class DomAdapter {
|
||||
getHistory() { throw _abstract(); }
|
||||
getLocation() { throw _abstract(); }
|
||||
getBaseHref() { throw _abstract(); }
|
||||
getUserAgent() { throw _abstract(); }
|
||||
getUserAgent(): string { throw _abstract(); }
|
||||
}
|
||||
|
||||
@@ -45,6 +45,6 @@ export function el(html: string) {
|
||||
var _RE_SPECIAL_CHARS = ['-', '[', ']', '/', '{', '}', '\\', '(', ')', '*', '+', '?', '.', '^', '$', '|'];
|
||||
var _ESCAPE_RE = RegExpWrapper.create(`[\\${_RE_SPECIAL_CHARS.join('\\')}]`);
|
||||
export function containsRegexp(input: string): RegExp {
|
||||
return RegExpWrapper.create(StringWrapper.replaceAllMapped(input, _ESCAPE_RE, (match) => `\\${match[0]}`));
|
||||
return RegExpWrapper.create(
|
||||
StringWrapper.replaceAllMapped(input, _ESCAPE_RE, (match) => `\\${match[0]}`));
|
||||
}
|
||||
|
||||
|
||||
+3
-7
@@ -1,25 +1,21 @@
|
||||
import {ddescribe, describe, it, iit, expect, beforeEach} from 'angular2/test_lib';
|
||||
import {Directive, onChange} from 'angular2/src/core/annotations_impl/annotations';
|
||||
|
||||
class DummyDirective extends Directive {
|
||||
constructor({lifecycle} = {}) { super({lifecycle: lifecycle}); }
|
||||
}
|
||||
|
||||
export function main() {
|
||||
describe("Directive", () => {
|
||||
describe("lifecycle", () => {
|
||||
it("should be false when no lifecycle specified", () => {
|
||||
var d = new DummyDirective();
|
||||
var d = new Directive();
|
||||
expect(d.hasLifecycleHook(onChange)).toBe(false);
|
||||
});
|
||||
|
||||
it("should be false when the lifecycle does not contain the hook", () => {
|
||||
var d = new DummyDirective({lifecycle:[]});
|
||||
var d = new Directive({lifecycle: []});
|
||||
expect(d.hasLifecycleHook(onChange)).toBe(false);
|
||||
});
|
||||
|
||||
it("should be true otherwise", () => {
|
||||
var d = new DummyDirective({lifecycle:[onChange]});
|
||||
var d = new Directive({lifecycle: [onChange]});
|
||||
expect(d.hasLifecycleHook(onChange)).toBe(true);
|
||||
});
|
||||
});
|
||||
-192
@@ -1,192 +0,0 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
beforeEach,
|
||||
ddescribe,
|
||||
describe,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
it,
|
||||
xdescribe,
|
||||
xit,
|
||||
} from 'angular2/test_lib';
|
||||
import {bootstrap} from 'angular2/src/core/application';
|
||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {bind} from 'angular2/di';
|
||||
import {Inject} from 'angular2/src/di/annotations_impl';
|
||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
||||
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
||||
import {Testability, TestabilityRegistry} from 'angular2/src/core/testability/testability';
|
||||
import {DOCUMENT_TOKEN} from 'angular2/src/render/dom/dom_renderer';
|
||||
|
||||
@Component({selector: 'hello-app'})
|
||||
@View({template: '{{greeting}} world!'})
|
||||
class HelloRootCmp {
|
||||
greeting:string;
|
||||
constructor() {
|
||||
this.greeting = 'hello';
|
||||
}
|
||||
}
|
||||
|
||||
@Component({selector: 'hello-app'})
|
||||
@View({template: 'before: <content></content> after: done'})
|
||||
class HelloRootCmpContent {
|
||||
constructor() { }
|
||||
}
|
||||
|
||||
@Component({selector: 'hello-app-2'})
|
||||
@View({template: '{{greeting}} world, again!'})
|
||||
class HelloRootCmp2 {
|
||||
greeting:string;
|
||||
constructor() {
|
||||
this.greeting = 'hello';
|
||||
}
|
||||
}
|
||||
|
||||
@Component({selector: 'hello-app'})
|
||||
@View({template: ''})
|
||||
class HelloRootCmp3 {
|
||||
appBinding;
|
||||
|
||||
constructor(@Inject("appBinding") appBinding) {
|
||||
this.appBinding = appBinding;
|
||||
}
|
||||
}
|
||||
|
||||
@Component({selector: 'hello-app'})
|
||||
@View({template: ''})
|
||||
class HelloRootCmp4 {
|
||||
lc;
|
||||
|
||||
constructor(@Inject(LifeCycle) lc) {
|
||||
this.lc = lc;
|
||||
}
|
||||
}
|
||||
|
||||
@Component({selector: 'hello-app'})
|
||||
class HelloRootMissingTemplate { }
|
||||
|
||||
@Directive({selector: 'hello-app'})
|
||||
class HelloRootDirectiveIsNotCmp { }
|
||||
|
||||
export function main() {
|
||||
var fakeDoc, el, el2, testBindings, lightDom;
|
||||
|
||||
beforeEach(() => {
|
||||
fakeDoc = DOM.createHtmlDocument();
|
||||
el = DOM.createElement('hello-app', fakeDoc);
|
||||
el2 = DOM.createElement('hello-app-2', fakeDoc);
|
||||
lightDom = DOM.createElement('light-dom-el', fakeDoc);
|
||||
DOM.appendChild(fakeDoc.body, el);
|
||||
DOM.appendChild(fakeDoc.body, el2);
|
||||
DOM.appendChild(el, lightDom);
|
||||
DOM.setText(lightDom, 'loading');
|
||||
testBindings = [bind(DOCUMENT_TOKEN).toValue(fakeDoc)];
|
||||
});
|
||||
|
||||
describe('bootstrap factory method', () => {
|
||||
it('should throw if bootstrapped Directive is not a Component', inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise = bootstrap(HelloRootDirectiveIsNotCmp, testBindings, (e,t) => {throw e;});
|
||||
PromiseWrapper.then(refPromise, null, (reason) => {
|
||||
expect(reason.message).toContain(`Could not load 'HelloRootDirectiveIsNotCmp' because it is not a component.`);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should throw if no element is found', inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise = bootstrap(HelloRootCmp, [], (e,t) => {throw e;});
|
||||
PromiseWrapper.then(refPromise, null, (reason) => {
|
||||
expect(reason.message).toContain(
|
||||
'The selector "hello-app" did not match any elements');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should create an injector promise', () => {
|
||||
var refPromise = bootstrap(HelloRootCmp, testBindings);
|
||||
expect(refPromise).not.toBe(null);
|
||||
});
|
||||
|
||||
it('should resolve an injector promise and contain bindings', inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise = bootstrap(HelloRootCmp, testBindings);
|
||||
refPromise.then((ref) => {
|
||||
expect(ref.injector.get(HelloRootCmp)).toBeAnInstanceOf(HelloRootCmp);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should provide the application component in the injector', inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise = bootstrap(HelloRootCmp, testBindings);
|
||||
refPromise.then((ref) => {
|
||||
expect(ref.injector.get(HelloRootCmp)).toBeAnInstanceOf(HelloRootCmp);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should display hello world', inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise = bootstrap(HelloRootCmp, testBindings);
|
||||
refPromise.then((ref) => {
|
||||
expect(el).toHaveText('hello world!');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should support multiple calls to bootstrap', inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise1 = bootstrap(HelloRootCmp, testBindings);
|
||||
var refPromise2 = bootstrap(HelloRootCmp2, testBindings);
|
||||
PromiseWrapper.all([refPromise1, refPromise2]).then((refs) => {
|
||||
expect(el).toHaveText('hello world!');
|
||||
expect(el2).toHaveText('hello world, again!');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it("should make the provided bindings available to the application component", inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise = bootstrap(HelloRootCmp3, [
|
||||
testBindings,
|
||||
bind("appBinding").toValue("BoundValue")
|
||||
]);
|
||||
|
||||
refPromise.then((ref) => {
|
||||
expect(ref.injector.get(HelloRootCmp3).appBinding).toEqual("BoundValue");
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it("should avoid cyclic dependencies when root component requires Lifecycle through DI", inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise = bootstrap(HelloRootCmp4, testBindings);
|
||||
|
||||
refPromise.then((ref) => {
|
||||
expect(ref.injector.get(HelloRootCmp4).lc).toBe(ref.injector.get(LifeCycle));
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it("should support shadow dom content tag", inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise = bootstrap(HelloRootCmpContent, testBindings);
|
||||
refPromise.then((ref) => {
|
||||
expect(el).toHaveText('before: loading after: done');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should register each application with the testability registry', inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise1 = bootstrap(HelloRootCmp, testBindings);
|
||||
var refPromise2 = bootstrap(HelloRootCmp2, testBindings);
|
||||
|
||||
PromiseWrapper.all([refPromise1, refPromise2]).then((refs) => {
|
||||
var registry = refs[0].injector.get(TestabilityRegistry);
|
||||
PromiseWrapper.all([
|
||||
refs[0].injector.asyncGet(Testability),
|
||||
refs[1].injector.asyncGet(Testability)]).then((testabilities) => {
|
||||
expect(registry.findTestabilityInTree(el)).toEqual(testabilities[0]);
|
||||
expect(registry.findTestabilityInTree(el2)).toEqual(testabilities[1]);
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
beforeEach,
|
||||
ddescribe,
|
||||
describe,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
it,
|
||||
xdescribe,
|
||||
xit,
|
||||
IS_DARTIUM
|
||||
} from 'angular2/test_lib';
|
||||
import {isPresent, stringify} from 'angular2/src/facade/lang';
|
||||
import {bootstrap} from 'angular2/src/core/application';
|
||||
import {Component, Directive, View} from 'angular2/annotations';
|
||||
import {DOM} from 'angular2/src/dom/dom_adapter';
|
||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||
import {bind, Inject} from 'angular2/di';
|
||||
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
||||
import {Testability, TestabilityRegistry} from 'angular2/src/core/testability/testability';
|
||||
import {DOCUMENT_TOKEN} from 'angular2/src/render/dom/dom_renderer';
|
||||
|
||||
@Component({selector: 'hello-app'})
|
||||
@View({template: '{{greeting}} world!'})
|
||||
class HelloRootCmp {
|
||||
greeting: string;
|
||||
constructor() { this.greeting = 'hello'; }
|
||||
}
|
||||
|
||||
@Component({selector: 'hello-app'})
|
||||
@View({template: 'before: <content></content> after: done'})
|
||||
class HelloRootCmpContent {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
@Component({selector: 'hello-app-2'})
|
||||
@View({template: '{{greeting}} world, again!'})
|
||||
class HelloRootCmp2 {
|
||||
greeting: string;
|
||||
constructor() { this.greeting = 'hello'; }
|
||||
}
|
||||
|
||||
@Component({selector: 'hello-app'})
|
||||
@View({template: ''})
|
||||
class HelloRootCmp3 {
|
||||
appBinding;
|
||||
|
||||
constructor(@Inject("appBinding") appBinding) { this.appBinding = appBinding; }
|
||||
}
|
||||
|
||||
@Component({selector: 'hello-app'})
|
||||
@View({template: ''})
|
||||
class HelloRootCmp4 {
|
||||
lc;
|
||||
|
||||
constructor(@Inject(LifeCycle) lc) { this.lc = lc; }
|
||||
}
|
||||
|
||||
@Component({selector: 'hello-app'})
|
||||
class HelloRootMissingTemplate {
|
||||
}
|
||||
|
||||
@Directive({selector: 'hello-app'})
|
||||
class HelloRootDirectiveIsNotCmp {
|
||||
}
|
||||
|
||||
export function main() {
|
||||
var fakeDoc, el, el2, testBindings, lightDom;
|
||||
|
||||
beforeEach(() => {
|
||||
fakeDoc = DOM.createHtmlDocument();
|
||||
el = DOM.createElement('hello-app', fakeDoc);
|
||||
el2 = DOM.createElement('hello-app-2', fakeDoc);
|
||||
lightDom = DOM.createElement('light-dom-el', fakeDoc);
|
||||
DOM.appendChild(fakeDoc.body, el);
|
||||
DOM.appendChild(fakeDoc.body, el2);
|
||||
DOM.appendChild(el, lightDom);
|
||||
DOM.setText(lightDom, 'loading');
|
||||
testBindings = [bind(DOCUMENT_TOKEN).toValue(fakeDoc)];
|
||||
});
|
||||
|
||||
describe('bootstrap factory method', () => {
|
||||
it('should throw if bootstrapped Directive is not a Component',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise =
|
||||
bootstrap(HelloRootDirectiveIsNotCmp, testBindings, (e, t) => { throw e; });
|
||||
PromiseWrapper.then(refPromise, null, (reason) => {
|
||||
expect(reason.message)
|
||||
.toContain(
|
||||
`Could not load '${stringify(HelloRootDirectiveIsNotCmp)}' because it is not a component.`);
|
||||
async.done();
|
||||
return null;
|
||||
});
|
||||
}));
|
||||
|
||||
it('should throw if no element is found', inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise = bootstrap(HelloRootCmp, [], (e, t) => { throw e; });
|
||||
PromiseWrapper.then(refPromise, null, (reason) => {
|
||||
expect(reason.message).toContain('The selector "hello-app" did not match any elements');
|
||||
async.done();
|
||||
return null;
|
||||
});
|
||||
}));
|
||||
|
||||
it('should create an injector promise', () => {
|
||||
var refPromise = bootstrap(HelloRootCmp, testBindings);
|
||||
expect(refPromise).not.toBe(null);
|
||||
});
|
||||
|
||||
it('should resolve an injector promise and contain bindings',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise = bootstrap(HelloRootCmp, testBindings);
|
||||
refPromise.then((ref) => {
|
||||
expect(ref.injector.get(HelloRootCmp)).toBeAnInstanceOf(HelloRootCmp);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should provide the application component in the injector',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise = bootstrap(HelloRootCmp, testBindings);
|
||||
refPromise.then((ref) => {
|
||||
expect(ref.injector.get(HelloRootCmp)).toBeAnInstanceOf(HelloRootCmp);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should display hello world', inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise = bootstrap(HelloRootCmp, testBindings);
|
||||
refPromise.then((ref) => {
|
||||
expect(el).toHaveText('hello world!');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should support multiple calls to bootstrap', inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise1 = bootstrap(HelloRootCmp, testBindings);
|
||||
var refPromise2 = bootstrap(HelloRootCmp2, testBindings);
|
||||
PromiseWrapper.all([refPromise1, refPromise2])
|
||||
.then((refs) => {
|
||||
expect(el).toHaveText('hello world!');
|
||||
expect(el2).toHaveText('hello world, again!');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it("should make the provided bindings available to the application component",
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise =
|
||||
bootstrap(HelloRootCmp3, [testBindings, bind("appBinding").toValue("BoundValue")]);
|
||||
|
||||
refPromise.then((ref) => {
|
||||
expect(ref.injector.get(HelloRootCmp3).appBinding).toEqual("BoundValue");
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it("should avoid cyclic dependencies when root component requires Lifecycle through DI",
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise = bootstrap(HelloRootCmp4, testBindings);
|
||||
|
||||
refPromise.then((ref) => {
|
||||
expect(ref.injector.get(HelloRootCmp4).lc).toBe(ref.injector.get(LifeCycle));
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it("should support shadow dom content tag", inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise = bootstrap(HelloRootCmpContent, testBindings);
|
||||
refPromise.then((ref) => {
|
||||
expect(el).toHaveText('before: loading after: done');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should register each application with the testability registry',
|
||||
inject([AsyncTestCompleter], (async) => {
|
||||
var refPromise1 = bootstrap(HelloRootCmp, testBindings);
|
||||
var refPromise2 = bootstrap(HelloRootCmp2, testBindings);
|
||||
|
||||
PromiseWrapper.all([refPromise1, refPromise2])
|
||||
.then((refs) => {
|
||||
var registry = refs[0].injector.get(TestabilityRegistry);
|
||||
PromiseWrapper.all([
|
||||
refs[0]
|
||||
.injector.asyncGet(Testability),
|
||||
refs[1].injector.asyncGet(Testability)
|
||||
])
|
||||
.then((testabilities) => {
|
||||
expect(registry.findTestabilityInTree(el)).toEqual(testabilities[0]);
|
||||
expect(registry.findTestabilityInTree(el2)).toEqual(testabilities[1]);
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+9
-11
@@ -1,30 +1,28 @@
|
||||
import {ddescribe, describe, it, iit, expect, beforeEach} from 'angular2/test_lib';
|
||||
import {DirectiveResolver} from 'angular2/src/core/compiler/directive_resolver';
|
||||
import {Directive} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {Directive} from 'angular2/annotations';
|
||||
import * as dirAnn from 'angular2/src/core/annotations_impl/annotations';
|
||||
|
||||
@Directive({selector: 'someDirective'})
|
||||
class SomeDirective {}
|
||||
|
||||
class SomeDirectiveWithoutAnnotation {
|
||||
class SomeDirective {
|
||||
}
|
||||
|
||||
class SomeDirectiveWithoutAnnotation {}
|
||||
|
||||
export function main() {
|
||||
describe("DirectiveResolver", () => {
|
||||
var reader;
|
||||
|
||||
beforeEach(() => {
|
||||
reader = new DirectiveResolver();
|
||||
});
|
||||
beforeEach(() => { reader = new DirectiveResolver(); });
|
||||
|
||||
it('should read out the Directive annotation', () => {
|
||||
var directiveMetadata = reader.resolve(SomeDirective);
|
||||
expect(directiveMetadata).toEqual(new Directive({selector: 'someDirective'}));
|
||||
expect(directiveMetadata).toEqual(new dirAnn.Directive({selector: 'someDirective'}));
|
||||
});
|
||||
|
||||
it('should throw if not matching annotation is found', () => {
|
||||
expect(() => {
|
||||
reader.resolve(SomeDirectiveWithoutAnnotation);
|
||||
}).toThrowError('No Directive annotation found on SomeDirectiveWithoutAnnotation');
|
||||
expect(() => { reader.resolve(SomeDirectiveWithoutAnnotation); })
|
||||
.toThrowError('No Directive annotation found on SomeDirectiveWithoutAnnotation');
|
||||
});
|
||||
});
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+333
-352
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,8 @@ import {
|
||||
IS_DARTIUM,
|
||||
beforeEachBindings,
|
||||
it,
|
||||
xit
|
||||
xit,
|
||||
containsRegexp
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
|
||||
@@ -25,7 +26,8 @@ import {
|
||||
BaseException,
|
||||
assertionsEnabled,
|
||||
isJsObject,
|
||||
global
|
||||
global,
|
||||
stringify
|
||||
} from 'angular2/src/facade/lang';
|
||||
import {PromiseWrapper, EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
||||
|
||||
@@ -989,94 +991,88 @@ export function main() {
|
||||
}));
|
||||
});
|
||||
|
||||
// TODO(tbosch): enable this again
|
||||
// Deactivated until we are fully on traceur as Typescript does not
|
||||
// emit class names when transpiling to ES6 and using decorators.
|
||||
// See https://github.com/Microsoft/TypeScript/pull/3063
|
||||
var supportsClassNames =
|
||||
IS_DARTIUM || (isPresent((<any>MyService).name) && (<any>MyService).name.length > 0);
|
||||
|
||||
describe("error handling", () => {
|
||||
if (supportsClassNames) {
|
||||
it('should report a meaningful error when a directive is missing annotation',
|
||||
it('should report a meaningful error when a directive is missing annotation',
|
||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
tb.overrideView(MyComp,
|
||||
new viewAnn.View({directives: [SomeDirectiveMissingAnnotation]}));
|
||||
|
||||
PromiseWrapper.catchError(tb.createView(MyComp, {context: ctx}), (e) => {
|
||||
expect(e.message).toEqual(
|
||||
`No Directive annotation found on ${stringify(SomeDirectiveMissingAnnotation)}`);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should report a meaningful error when a directive is null',
|
||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
|
||||
tb.overrideView(MyComp, new viewAnn.View({directives: [[null]]}));
|
||||
|
||||
PromiseWrapper.catchError(tb.createView(MyComp, {context: ctx}), (e) => {
|
||||
expect(e.message).toEqual(
|
||||
`Unexpected directive value 'null' on the View of component '${stringify(MyComp)}'`);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
if (!IS_DARTIUM) {
|
||||
it('should report a meaningful error when a directive is undefined',
|
||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
tb.overrideView(MyComp,
|
||||
new viewAnn.View({directives: [SomeDirectiveMissingAnnotation]}));
|
||||
|
||||
var undefinedValue;
|
||||
|
||||
tb.overrideView(MyComp, new viewAnn.View({directives: [undefinedValue]}));
|
||||
|
||||
PromiseWrapper.catchError(tb.createView(MyComp, {context: ctx}), (e) => {
|
||||
expect(e.message)
|
||||
.toEqual('No Directive annotation found on SomeDirectiveMissingAnnotation');
|
||||
expect(e.message).toEqual(
|
||||
`Unexpected directive value 'undefined' on the View of component '${stringify(MyComp)}'`);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should report a meaningful error when a directive is null',
|
||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
|
||||
tb.overrideView(MyComp, new viewAnn.View({directives: [[null]]}));
|
||||
|
||||
PromiseWrapper.catchError(tb.createView(MyComp, {context: ctx}), (e) => {
|
||||
expect(e.message)
|
||||
.toEqual("Unexpected directive value 'null' on the View of component 'MyComp'");
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
if (!IS_DARTIUM) {
|
||||
it('should report a meaningful error when a directive is undefined',
|
||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
|
||||
var undefinedValue;
|
||||
|
||||
tb.overrideView(MyComp, new viewAnn.View({directives: [undefinedValue]}));
|
||||
|
||||
PromiseWrapper.catchError(tb.createView(MyComp, {context: ctx}), (e) => {
|
||||
expect(e.message).toEqual(
|
||||
"Unexpected directive value 'undefined' on the View of component 'MyComp'");
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
it('should specify a location of an error that happened during change detection (text)',
|
||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
|
||||
tb.overrideView(MyComp, new viewAnn.View({template: '{{a.b}}'}));
|
||||
|
||||
tb.createView(MyComp, {context: ctx})
|
||||
.then((view) => {
|
||||
expect(() => view.detectChanges()).toThrowError(new RegExp('{{a.b}} in MyComp'));
|
||||
async.done();
|
||||
})
|
||||
}));
|
||||
|
||||
it('should specify a location of an error that happened during change detection (element property)',
|
||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
|
||||
tb.overrideView(MyComp, new viewAnn.View({template: '<div [prop]="a.b"></div>'}));
|
||||
|
||||
tb.createView(MyComp, {context: ctx})
|
||||
.then((view) => {
|
||||
expect(() => view.detectChanges()).toThrowError(new RegExp('a.b in MyComp'));
|
||||
async.done();
|
||||
})
|
||||
}));
|
||||
|
||||
it('should specify a location of an error that happened during change detection (directive property)',
|
||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
|
||||
tb.overrideView(
|
||||
MyComp,
|
||||
new viewAnn.View(
|
||||
{template: '<child-cmp [prop]="a.b"></child-cmp>', directives: [ChildComp]}));
|
||||
|
||||
tb.createView(MyComp, {context: ctx})
|
||||
.then((view) => {
|
||||
expect(() => view.detectChanges()).toThrowError(new RegExp('a.b in MyComp'));
|
||||
async.done();
|
||||
})
|
||||
}));
|
||||
}
|
||||
|
||||
it('should specify a location of an error that happened during change detection (text)',
|
||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
|
||||
tb.overrideView(MyComp, new viewAnn.View({template: '{{a.b}}'}));
|
||||
|
||||
tb.createView(MyComp, {context: ctx})
|
||||
.then((view) => {
|
||||
expect(() => view.detectChanges())
|
||||
.toThrowError(containsRegexp(`{{a.b}} in ${stringify(MyComp)}`));
|
||||
async.done();
|
||||
})
|
||||
}));
|
||||
|
||||
it('should specify a location of an error that happened during change detection (element property)',
|
||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
|
||||
tb.overrideView(MyComp, new viewAnn.View({template: '<div [prop]="a.b"></div>'}));
|
||||
|
||||
tb.createView(MyComp, {context: ctx})
|
||||
.then((view) => {
|
||||
expect(() => view.detectChanges())
|
||||
.toThrowError(containsRegexp(`a.b in ${stringify(MyComp)}`));
|
||||
async.done();
|
||||
})
|
||||
}));
|
||||
|
||||
it('should specify a location of an error that happened during change detection (directive property)',
|
||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
|
||||
tb.overrideView(
|
||||
MyComp,
|
||||
new viewAnn.View(
|
||||
{template: '<child-cmp [prop]="a.b"></child-cmp>', directives: [ChildComp]}));
|
||||
|
||||
tb.createView(MyComp, {context: ctx})
|
||||
.then((view) => {
|
||||
expect(() => view.detectChanges())
|
||||
.toThrowError(containsRegexp(`a.b in ${stringify(MyComp)}`));
|
||||
async.done();
|
||||
})
|
||||
}));
|
||||
});
|
||||
|
||||
it('should support imperative views', inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
|
||||
+24
-30
@@ -10,15 +10,19 @@ import {
|
||||
inject,
|
||||
IS_DARTIUM,
|
||||
it,
|
||||
SpyObject, proxy
|
||||
SpyObject,
|
||||
proxy
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
import {isBlank} from 'angular2/src/facade/lang';
|
||||
import {isBlank, IMPLEMENTS, stringify} from 'angular2/src/facade/lang';
|
||||
import {MapWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
import {ChangeDetection, ChangeDetectorDefinition} from 'angular2/change_detection';
|
||||
import {ProtoViewFactory, getChangeDetectorDefinitions} from 'angular2/src/core/compiler/proto_view_factory';
|
||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {
|
||||
ProtoViewFactory,
|
||||
getChangeDetectorDefinitions
|
||||
} from 'angular2/src/core/compiler/proto_view_factory';
|
||||
import {Component, Directive} from 'angular2/annotations';
|
||||
import {DirectiveResolver} from 'angular2/src/core/compiler/directive_resolver';
|
||||
import {DirectiveBinding} from 'angular2/src/core/compiler/element_injector';
|
||||
import * as renderApi from 'angular2/src/render/api';
|
||||
@@ -31,7 +35,7 @@ export function main() {
|
||||
var protoViewFactory;
|
||||
var directiveResolver;
|
||||
|
||||
beforeEach( () => {
|
||||
beforeEach(() => {
|
||||
directiveResolver = new DirectiveResolver();
|
||||
changeDetection = new ChangeDetectionSpy();
|
||||
protoViewFactory = new ProtoViewFactory(changeDetection);
|
||||
@@ -45,10 +49,10 @@ export function main() {
|
||||
|
||||
it('should create a ChangeDetectorDefinition for the root render proto view', () => {
|
||||
var renderPv = createRenderProtoView();
|
||||
var defs = getChangeDetectorDefinitions(bindDirective(MainComponent).metadata,
|
||||
renderPv, []);
|
||||
var defs =
|
||||
getChangeDetectorDefinitions(bindDirective(MainComponent).metadata, renderPv, []);
|
||||
expect(defs.length).toBe(1);
|
||||
expect(defs[0].id).toEqual('MainComponent_comp_0');
|
||||
expect(defs[0].id).toEqual(`${stringify(MainComponent)}_comp_0`);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -57,8 +61,7 @@ export function main() {
|
||||
|
||||
it('should create an AppProtoView for the root render proto view', () => {
|
||||
var renderPv = createRenderProtoView();
|
||||
var pvs = protoViewFactory.createAppProtoViews(bindDirective(MainComponent),
|
||||
renderPv, []);
|
||||
var pvs = protoViewFactory.createAppProtoViews(bindDirective(MainComponent), renderPv, []);
|
||||
expect(pvs.length).toBe(1);
|
||||
expect(pvs[0].render).toBe(renderPv.render);
|
||||
});
|
||||
@@ -68,42 +71,33 @@ export function main() {
|
||||
});
|
||||
}
|
||||
|
||||
function createRenderProtoView(elementBinders = null, type:number = null) {
|
||||
function createRenderProtoView(elementBinders = null, type: number = null) {
|
||||
if (isBlank(type)) {
|
||||
type = renderApi.ProtoViewDto.COMPONENT_VIEW_TYPE;
|
||||
}
|
||||
if (isBlank(elementBinders)) {
|
||||
elementBinders = [];
|
||||
}
|
||||
return new renderApi.ProtoViewDto({
|
||||
elementBinders: elementBinders,
|
||||
type: type,
|
||||
variableBindings: MapWrapper.create()
|
||||
});
|
||||
return new renderApi.ProtoViewDto(
|
||||
{elementBinders: elementBinders, type: type, variableBindings: MapWrapper.create()});
|
||||
}
|
||||
|
||||
function createRenderComponentElementBinder(directiveIndex) {
|
||||
return new renderApi.ElementBinder({
|
||||
directives: [new renderApi.DirectiveBinder({
|
||||
directiveIndex: directiveIndex
|
||||
})]
|
||||
});
|
||||
return new renderApi.ElementBinder(
|
||||
{directives: [new renderApi.DirectiveBinder({directiveIndex: directiveIndex})]});
|
||||
}
|
||||
|
||||
function createRenderViewportElementBinder(nestedProtoView) {
|
||||
return new renderApi.ElementBinder({
|
||||
nestedProtoView: nestedProtoView
|
||||
});
|
||||
return new renderApi.ElementBinder({nestedProtoView: nestedProtoView});
|
||||
}
|
||||
|
||||
@proxy
|
||||
@IMPLEMENTS(ChangeDetection)
|
||||
class ChangeDetectionSpy extends SpyObject {
|
||||
constructor(){super(ChangeDetection);}
|
||||
noSuchMethod(m){return super.noSuchMethod(m)}
|
||||
constructor() { super(ChangeDetection); }
|
||||
noSuchMethod(m) { return super.noSuchMethod(m) }
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'main-comp'
|
||||
})
|
||||
class MainComponent {}
|
||||
@Component({selector: 'main-comp'})
|
||||
class MainComponent {
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
beforeEach,
|
||||
ddescribe,
|
||||
describe,
|
||||
el,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
IS_NODEJS,
|
||||
it,
|
||||
xit,
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
import {TestBed} from 'angular2/src/test_lib/test_bed';
|
||||
|
||||
import {QueryList} from 'angular2/src/core/compiler/query_list';
|
||||
import {Query} from 'angular2/src/core/annotations_impl/di';
|
||||
|
||||
import {NgIf, NgFor} from 'angular2/angular2';
|
||||
|
||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
||||
|
||||
import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
|
||||
|
||||
export function main() {
|
||||
BrowserDomAdapter.makeCurrent();
|
||||
describe('Query API', () => {
|
||||
|
||||
it('should contain all directives in the light dom', inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
var template =
|
||||
'<div text="1"></div>' +
|
||||
'<needs-query text="2"><div text="3"></div></needs-query>' +
|
||||
'<div text="4"></div>';
|
||||
|
||||
tb.createView(MyComp, {html: template}).then((view) => {
|
||||
view.detectChanges();
|
||||
expect(view.rootNodes).toHaveText('2|3|');
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should reflect dynamically inserted directives', inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
var template =
|
||||
'<div text="1"></div>' +
|
||||
'<needs-query text="2"><div *ng-if="shouldShow" [text]="\'3\'"></div></needs-query>' +
|
||||
'<div text="4"></div>';
|
||||
|
||||
tb.createView(MyComp, {html: template}).then((view) => {
|
||||
|
||||
view.detectChanges();
|
||||
expect(view.rootNodes).toHaveText('2|');
|
||||
|
||||
view.context.shouldShow = true;
|
||||
view.detectChanges();
|
||||
// TODO(rado): figure out why the second tick is necessary.
|
||||
view.detectChanges();
|
||||
expect(view.rootNodes).toHaveText('2|3|');
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should reflect moved directives', inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
var template =
|
||||
'<div text="1"></div>' +
|
||||
'<needs-query text="2"><div *ng-for="var i of list" [text]="i"></div></needs-query>' +
|
||||
'<div text="4"></div>';
|
||||
|
||||
tb.createView(MyComp, {html: template}).then((view) => {
|
||||
view.detectChanges();
|
||||
view.detectChanges();
|
||||
|
||||
expect(view.rootNodes).toHaveText('2|1d|2d|3d|');
|
||||
|
||||
view.context.list = ['3d', '2d'];
|
||||
view.detectChanges();
|
||||
view.detectChanges();
|
||||
expect(view.rootNodes).toHaveText('2|3d|2d|');
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
@Component({selector: 'needs-query'})
|
||||
@View({
|
||||
directives: [NgFor],
|
||||
template: '<div *ng-for="var dir of query">{{dir.text}}|</div>'
|
||||
})
|
||||
class NeedsQuery {
|
||||
query: QueryList;
|
||||
constructor(@Query(TextDirective) query: QueryList) {
|
||||
this.query = query;
|
||||
}
|
||||
}
|
||||
|
||||
var _constructiontext = 0;
|
||||
|
||||
@Directive({
|
||||
selector: '[text]',
|
||||
properties: {
|
||||
'text': 'text'
|
||||
}
|
||||
})
|
||||
class TextDirective {
|
||||
text: string;
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
@Component({selector: 'my-comp'})
|
||||
@View({
|
||||
directives: [NeedsQuery, TextDirective, NgIf, NgFor]
|
||||
})
|
||||
class MyComp {
|
||||
shouldShow: boolean;
|
||||
list;
|
||||
constructor() {
|
||||
this.shouldShow = false;
|
||||
this.list = ['1d', '2d', '3d'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
beforeEach,
|
||||
ddescribe,
|
||||
describe,
|
||||
el,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
it,
|
||||
xit,
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
import {TestBed} from 'angular2/src/test_lib/test_bed';
|
||||
|
||||
import {Injectable} from 'angular2/di';
|
||||
import {QueryList} from 'angular2/core';
|
||||
import {Query, Component, Directive, View} from 'angular2/annotations';
|
||||
|
||||
import {NgIf, NgFor} from 'angular2/angular2';
|
||||
|
||||
import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter';
|
||||
|
||||
export function main() {
|
||||
BrowserDomAdapter.makeCurrent();
|
||||
describe('Query API', () => {
|
||||
|
||||
it('should contain all directives in the light dom',
|
||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
var template = '<div text="1"></div>' +
|
||||
'<needs-query text="2"><div text="3"></div></needs-query>' +
|
||||
'<div text="4"></div>';
|
||||
|
||||
tb.createView(MyComp, {html: template})
|
||||
.then((view) => {
|
||||
view.detectChanges();
|
||||
expect(view.rootNodes).toHaveText('2|3|');
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should reflect dynamically inserted directives',
|
||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
var template =
|
||||
'<div text="1"></div>' +
|
||||
'<needs-query text="2"><div *ng-if="shouldShow" [text]="\'3\'"></div></needs-query>' +
|
||||
'<div text="4"></div>';
|
||||
|
||||
tb.createView(MyComp, {html: template})
|
||||
.then((view) => {
|
||||
|
||||
view.detectChanges();
|
||||
expect(view.rootNodes).toHaveText('2|');
|
||||
|
||||
view.context.shouldShow = true;
|
||||
view.detectChanges();
|
||||
// TODO(rado): figure out why the second tick is necessary.
|
||||
view.detectChanges();
|
||||
expect(view.rootNodes).toHaveText('2|3|');
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should reflect moved directives', inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
var template =
|
||||
'<div text="1"></div>' +
|
||||
'<needs-query text="2"><div *ng-for="var i of list" [text]="i"></div></needs-query>' +
|
||||
'<div text="4"></div>';
|
||||
|
||||
tb.createView(MyComp, {html: template})
|
||||
.then((view) => {
|
||||
view.detectChanges();
|
||||
view.detectChanges();
|
||||
|
||||
expect(view.rootNodes).toHaveText('2|1d|2d|3d|');
|
||||
|
||||
view.context.list = ['3d', '2d'];
|
||||
view.detectChanges();
|
||||
view.detectChanges();
|
||||
expect(view.rootNodes).toHaveText('2|3d|2d|');
|
||||
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
@Directive({selector: '[text]', properties: {'text': 'text'}})
|
||||
@Injectable()
|
||||
class TextDirective {
|
||||
text: string;
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
@Component({selector: 'needs-query'})
|
||||
@View({directives: [NgFor], template: '<div *ng-for="var dir of query">{{dir.text}}|</div>'})
|
||||
@Injectable()
|
||||
class NeedsQuery {
|
||||
query: QueryList;
|
||||
constructor(@Query(TextDirective) query: QueryList) { this.query = query; }
|
||||
}
|
||||
|
||||
var _constructiontext = 0;
|
||||
|
||||
@Component({selector: 'my-comp'})
|
||||
@View({directives: [NeedsQuery, TextDirective, NgIf, NgFor]})
|
||||
@Injectable()
|
||||
class MyComp {
|
||||
shouldShow: boolean;
|
||||
list;
|
||||
constructor() {
|
||||
this.shouldShow = false;
|
||||
this.list = ['1d', '2d', '3d'];
|
||||
}
|
||||
}
|
||||
+2
-4
@@ -12,9 +12,7 @@ export function main() {
|
||||
log = '';
|
||||
});
|
||||
|
||||
function logAppend(item) {
|
||||
log += (log.length == 0 ? '' : ', ') + item;
|
||||
}
|
||||
function logAppend(item) { log += (log.length == 0 ? '' : ', ') + item; }
|
||||
|
||||
it('should support adding objects and iterating over them', () => {
|
||||
queryList.add('one');
|
||||
@@ -35,7 +33,7 @@ export function main() {
|
||||
describe('simple observable interface', () => {
|
||||
it('should fire callbacks on change', () => {
|
||||
var fires = 0;
|
||||
queryList.onChange(() => {fires += 1;});
|
||||
queryList.onChange(() => { fires += 1; });
|
||||
|
||||
queryList.fireCallbacks();
|
||||
expect(fires).toEqual(0);
|
||||
@@ -1,147 +0,0 @@
|
||||
import {ddescribe, describe, it, iit, expect, beforeEach, IS_DARTIUM} from 'angular2/test_lib';
|
||||
import {ReflectionCapabilities} from 'angular2/src/reflection/reflection_capabilities';
|
||||
import {isPresent, global, CONST} from 'angular2/src/facade/lang';
|
||||
|
||||
export function main() {
|
||||
var rc;
|
||||
beforeEach(() => {
|
||||
rc = new ReflectionCapabilities();
|
||||
});
|
||||
|
||||
function assertTestClassAnnotations(annotations) {
|
||||
expect(annotations[0]).toBeAnInstanceOf(ClassDec1);
|
||||
expect(annotations[1]).toBeAnInstanceOf(ClassDec2);
|
||||
}
|
||||
|
||||
function assertTestClassParameters(parameters) {
|
||||
expect(parameters.length).toBe(4);
|
||||
|
||||
expect(parameters[0].length).toBe(2);
|
||||
expect(parameters[0][0]).toEqual(P1);
|
||||
expect(parameters[0][1]).toBeAnInstanceOf(ParamDec);
|
||||
|
||||
expect(parameters[1].length).toBe(1);
|
||||
expect(parameters[1][0]).toEqual(P2);
|
||||
|
||||
|
||||
expect(parameters[2].length).toBe(1);
|
||||
expect(parameters[2][0]).toBeAnInstanceOf(ParamDec);
|
||||
|
||||
expect(parameters[3].length).toBe(0);
|
||||
}
|
||||
|
||||
describe('reflection capabilities', () => {
|
||||
describe("factory", () => {
|
||||
it("should create a factory for a type", () => {
|
||||
var f = rc.factory(ClassWithField);
|
||||
expect(f("value").field).toEqual("value");
|
||||
});
|
||||
|
||||
it("should throw when a constructor has more than 10 args", () => {
|
||||
expect(() => rc.factory(ClassWith11Fields)).toThrowError(
|
||||
new RegExp(`has more than 10 arguments`));
|
||||
});
|
||||
});
|
||||
|
||||
it('can read out class annotations through annotations key', () => {
|
||||
assertTestClassAnnotations(rc.annotations(TestClass));
|
||||
});
|
||||
|
||||
it('can read out parameter annotations through parameters key', () => {
|
||||
assertTestClassParameters(rc.parameters(TestClass));
|
||||
});
|
||||
|
||||
it('can read out parameter annotations through parameters key for types only class', () => {
|
||||
expect(rc.parameters(TestClassTypesOnly)).toEqual([[P1], [P2]]);
|
||||
});
|
||||
|
||||
if (!IS_DARTIUM) {
|
||||
// Mocking in the tests below is needed because the test runs through Traceur.
|
||||
// After the switch to TS the setup will have to change, where the direct key
|
||||
// access will be mocked, and the tests below will be direct.
|
||||
it('can read out class annotations though Reflect APIs', () => {
|
||||
var rc = new ReflectionCapabilities({
|
||||
'getMetadata': (key, targetCls) => {
|
||||
return (targetCls == TestClassDec) ? mockDataForTestClassDec[key] : null;
|
||||
}
|
||||
});
|
||||
assertTestClassAnnotations(rc.annotations(TestClassDec));
|
||||
});
|
||||
|
||||
it('can read out parameter annotations though Reflect APIs', () => {
|
||||
var rc = new ReflectionCapabilities({
|
||||
'getMetadata': (key, targetCls) => {
|
||||
return (targetCls == TestClassDec) ? mockDataForTestClassDec[key] : null;
|
||||
}
|
||||
});
|
||||
assertTestClassParameters(rc.parameters(TestClassDec));
|
||||
});
|
||||
|
||||
it('can read out parameter annotations though Reflect APIs for types only class', () => {
|
||||
var rc = new ReflectionCapabilities({
|
||||
'getMetadata': (key, targetCls) => {
|
||||
return (targetCls == TestClassTypesOnlyDec) ? mockDataForTestClassTypesOnly[key] : null;
|
||||
}
|
||||
});
|
||||
expect(rc.parameters(TestClassTypesOnlyDec)).toEqual([[P1], [P2]]);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class ClassDec1 {
|
||||
@CONST()
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
class ClassDec2 {
|
||||
@CONST()
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
|
||||
class ParamDec {
|
||||
@CONST()
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
class P1 {}
|
||||
class P2 {}
|
||||
|
||||
@ClassDec1()
|
||||
@ClassDec2()
|
||||
class TestClass {
|
||||
constructor(@ParamDec() a: P1, b: P2, @ParamDec() c, d) {}
|
||||
}
|
||||
|
||||
// Mocking the data stored in global.Reflect as if TS was compiling TestClass above.
|
||||
var mockDataForTestClassDec = {
|
||||
'annotations': [new ClassDec1(), new ClassDec2()],
|
||||
'parameters': [new ParamDec(), null, new ParamDec()],
|
||||
'design:paramtypes': [P1, P2, Object, Object]
|
||||
};
|
||||
class TestClassDec {}
|
||||
|
||||
|
||||
class TestClassTypesOnly {
|
||||
constructor(a: P1, b: P2) {}
|
||||
}
|
||||
|
||||
class ClassWithField {
|
||||
field;
|
||||
constructor(field) {
|
||||
this.field = field;
|
||||
}
|
||||
}
|
||||
class ClassWith11Fields {
|
||||
constructor(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) {
|
||||
}
|
||||
}
|
||||
|
||||
// Mocking the data stored in global.Reflect as if TS was compiling TestClass above.
|
||||
var mockDataForTestClassTypesOnly = {
|
||||
'annotations': null,
|
||||
'parameters': null,
|
||||
'design:paramtypes': [P1, P2]
|
||||
};
|
||||
class TestClassTypesOnlyDec {}
|
||||
+9
-16
@@ -12,7 +12,8 @@ import {
|
||||
beforeEachBindings,
|
||||
it,
|
||||
xit,
|
||||
SpyObject, proxy
|
||||
SpyObject,
|
||||
proxy
|
||||
} from 'angular2/test_lib';
|
||||
|
||||
import {MapWrapper} from 'angular2/src/facade/collection';
|
||||
@@ -32,23 +33,15 @@ export function main() {
|
||||
var view;
|
||||
var viewManager;
|
||||
|
||||
function wrapView(view:AppView):ViewRef {
|
||||
return new ViewRef(view);
|
||||
}
|
||||
function wrapView(view: AppView): ViewRef { return new ViewRef(view); }
|
||||
|
||||
function createProtoView() {
|
||||
return new AppProtoView(null, null, null);
|
||||
}
|
||||
function createProtoView() { return new AppProtoView(null, null, null); }
|
||||
|
||||
function createView() {
|
||||
return new AppView(null, createProtoView(), MapWrapper.create());
|
||||
}
|
||||
function createView() { return new AppView(null, createProtoView(), MapWrapper.create()); }
|
||||
|
||||
function createViewContainer() {
|
||||
return new ViewContainerRef(viewManager, location);
|
||||
}
|
||||
function createViewContainer() { return new ViewContainerRef(viewManager, location); }
|
||||
|
||||
beforeEach( () => {
|
||||
beforeEach(() => {
|
||||
viewManager = new AppViewManagerSpy();
|
||||
view = createView();
|
||||
view.viewContainers = [null];
|
||||
@@ -79,6 +72,6 @@ export function main() {
|
||||
@proxy
|
||||
@IMPLEMENTS(AppViewManager)
|
||||
class AppViewManagerSpy extends SpyObject {
|
||||
constructor(){super(AppViewManager);}
|
||||
noSuchMethod(m){return super.noSuchMethod(m)}
|
||||
constructor() { super(AppViewManager); }
|
||||
noSuchMethod(m) { return super.noSuchMethod(m) }
|
||||
}
|
||||
+192
-187
File diff suppressed because it is too large
Load Diff
+81
-101
File diff suppressed because it is too large
Load Diff
+8
-13
@@ -12,7 +12,8 @@ import {
|
||||
beforeEachBindings,
|
||||
it,
|
||||
xit,
|
||||
SpyObject, proxy
|
||||
SpyObject,
|
||||
proxy
|
||||
} from 'angular2/test_lib';
|
||||
import {AppViewPool} from 'angular2/src/core/compiler/view_pool';
|
||||
import {AppProtoView, AppView} from 'angular2/src/core/compiler/view';
|
||||
@@ -21,20 +22,14 @@ import {MapWrapper, Map} from 'angular2/src/facade/collection';
|
||||
export function main() {
|
||||
describe('AppViewPool', () => {
|
||||
|
||||
function createViewPool({capacity}):AppViewPool {
|
||||
return new AppViewPool(capacity);
|
||||
}
|
||||
function createViewPool({capacity}): AppViewPool { return new AppViewPool(capacity); }
|
||||
|
||||
function createProtoView() {
|
||||
return new AppProtoView(null, null, null);
|
||||
}
|
||||
function createProtoView() { return new AppProtoView(null, null, null); }
|
||||
|
||||
function createView(pv) {
|
||||
return new AppView(null, pv, MapWrapper.create());
|
||||
}
|
||||
function createView(pv) { return new AppView(null, pv, MapWrapper.create()); }
|
||||
|
||||
it('should support multiple AppProtoViews', () => {
|
||||
var vf = createViewPool({ capacity: 2 });
|
||||
var vf = createViewPool({capacity: 2});
|
||||
var pv1 = createProtoView();
|
||||
var pv2 = createProtoView();
|
||||
var view1 = createView(pv1);
|
||||
@@ -48,7 +43,7 @@ export function main() {
|
||||
|
||||
it('should reuse the newest view that has been returned', () => {
|
||||
var pv = createProtoView();
|
||||
var vf = createViewPool({ capacity: 2 });
|
||||
var vf = createViewPool({capacity: 2});
|
||||
var view1 = createView(pv);
|
||||
var view2 = createView(pv);
|
||||
vf.returnView(view1);
|
||||
@@ -59,7 +54,7 @@ export function main() {
|
||||
|
||||
it('should not add views when the capacity has been reached', () => {
|
||||
var pv = createProtoView();
|
||||
var vf = createViewPool({ capacity: 2 });
|
||||
var vf = createViewPool({capacity: 2});
|
||||
var view1 = createView(pv);
|
||||
var view2 = createView(pv);
|
||||
var view3 = createView(pv);
|
||||
@@ -1,84 +0,0 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
beforeEach,
|
||||
ddescribe,
|
||||
describe,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
it,
|
||||
xit
|
||||
} from 'angular2/test_lib';
|
||||
import {TestBed} from 'angular2/src/test_lib/test_bed';
|
||||
import {Directive, Component} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {Query} from 'angular2/src/core/annotations_impl/di';
|
||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
||||
import {QueryList, NgFor} from 'angular2/angular2';
|
||||
import {Inject} from 'angular2/src/di/annotations_impl';
|
||||
import {forwardRef, resolveForwardRef, bind} from 'angular2/di';
|
||||
import {Type} from 'angular2/src/facade/lang';
|
||||
|
||||
export function main() {
|
||||
describe("forwardRef integration", function () {
|
||||
it('should instantiate components which are declared using forwardRef', inject(
|
||||
[TestBed, AsyncTestCompleter],
|
||||
(tb, async) => {
|
||||
tb.createView(App).then((view) => {
|
||||
view.detectChanges();
|
||||
expect(view.rootNodes).toHaveText('frame(lock)');
|
||||
async.done();
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app',
|
||||
appInjector: [
|
||||
forwardRef(() => Frame)
|
||||
]
|
||||
})
|
||||
@View({
|
||||
template: `<door><lock></lock></door>`,
|
||||
directives: [
|
||||
bind(forwardRef(() => Door)).toClass(forwardRef(() => Door)),
|
||||
bind(forwardRef(() => Lock)).toClass(forwardRef(() => Lock))
|
||||
]
|
||||
})
|
||||
class App {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'Lock'
|
||||
})
|
||||
@View({
|
||||
directives: [NgFor],
|
||||
template: `{{frame.name}}(<span *ng-for="var lock of locks">{{lock.name}}</span>)`
|
||||
})
|
||||
class Door {
|
||||
locks: QueryList;
|
||||
frame: Frame;
|
||||
|
||||
constructor(@Query(forwardRef(() => Lock)) locks: QueryList, @Inject(forwardRef(() => Frame)) frame:Frame) {
|
||||
this.frame = frame;
|
||||
this.locks = locks;
|
||||
}
|
||||
}
|
||||
|
||||
class Frame {
|
||||
name: string;
|
||||
constructor() {
|
||||
this.name = 'frame';
|
||||
}
|
||||
}
|
||||
|
||||
@Directive({
|
||||
selector: 'lock'
|
||||
})
|
||||
class Lock {
|
||||
name: string;
|
||||
constructor() {
|
||||
this.name = 'lock';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import {
|
||||
AsyncTestCompleter,
|
||||
beforeEach,
|
||||
ddescribe,
|
||||
describe,
|
||||
expect,
|
||||
iit,
|
||||
inject,
|
||||
it,
|
||||
xit
|
||||
} from 'angular2/test_lib';
|
||||
import {TestBed} from 'angular2/src/test_lib/test_bed';
|
||||
import {Directive, Component, Query, View} from 'angular2/annotations';
|
||||
import {QueryList, NgFor} from 'angular2/angular2';
|
||||
import {forwardRef, resolveForwardRef, bind, Inject} from 'angular2/di';
|
||||
import {Type} from 'angular2/src/facade/lang';
|
||||
|
||||
export function main() {
|
||||
describe("forwardRef integration", function() {
|
||||
it('should instantiate components which are declared using forwardRef',
|
||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
tb.createView(App).then((view) => {
|
||||
view.detectChanges();
|
||||
expect(view.rootNodes).toHaveText('frame(lock)');
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
@Component({selector: 'app', appInjector: [forwardRef(() => Frame)]})
|
||||
@View({
|
||||
template: `<door><lock></lock></door>`,
|
||||
directives: [
|
||||
bind(forwardRef(() => Door))
|
||||
.toClass(forwardRef(() => Door)),
|
||||
bind(forwardRef(() => Lock)).toClass(forwardRef(() => Lock))
|
||||
]
|
||||
})
|
||||
class App {
|
||||
}
|
||||
|
||||
@Component({selector: 'Lock'})
|
||||
@View({
|
||||
directives: [NgFor],
|
||||
template: `{{frame.name}}(<span *ng-for="var lock of locks">{{lock.name}}</span>)`
|
||||
})
|
||||
class Door {
|
||||
locks: QueryList;
|
||||
frame: Frame;
|
||||
|
||||
constructor(@Query(forwardRef(() => Lock)) locks: QueryList,
|
||||
@Inject(forwardRef(() => Frame)) frame: Frame) {
|
||||
this.frame = frame;
|
||||
this.locks = locks;
|
||||
}
|
||||
}
|
||||
|
||||
class Frame {
|
||||
name: string;
|
||||
constructor() { this.name = 'frame'; }
|
||||
}
|
||||
|
||||
@Directive({selector: 'lock'})
|
||||
class Lock {
|
||||
name: string;
|
||||
constructor() { this.name = 'lock'; }
|
||||
}
|
||||
+2
-3
@@ -11,9 +11,8 @@ export function main() {
|
||||
executed = false;
|
||||
});
|
||||
|
||||
it('should start with a pending count of 0', () => {
|
||||
expect(testability.getPendingCount()).toEqual(0);
|
||||
});
|
||||
it('should start with a pending count of 0',
|
||||
() => { expect(testability.getPendingCount()).toEqual(0); });
|
||||
|
||||
it('should fire whenstable callbacks if pending count is 0', () => {
|
||||
testability.whenStable(() => executed = true);
|
||||
-595
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user