feat(tests): add a test injector

fixes #614

Asynchronous test should inject an AsyncTestCompleter:

Before:

  it("async test", (done) => {
    // ...
    done();
  });

After:

  it("async test", inject([AsyncTestCompleter], (async) => {
    // ...
    async.done();
  }));

Note: inject() is currently a function and the first parameter is the
array of DI tokens to inject as the test function parameters. This
construct is linked to Traceur limitations. The planned syntax is:

  it("async test", @Inject (async: AsyncTestCompleter) => {
    // ...
    async.done();
  });
This commit is contained in:
Victor Berchet 2015-03-13 11:10:11 +01:00
parent 5926d2e2f7
commit 33b5ba863e
29 changed files with 1241 additions and 640 deletions

View File

@ -0,0 +1,114 @@
import {bind} from 'angular2/di';
import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
import {Reflector, reflector} from 'angular2/src/reflection/reflection';
import {Parser, Lexer, ChangeDetection, dynamicChangeDetection} from 'angular2/change_detection';
import {ExceptionHandler} from 'angular2/src/core/exception_handler';
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
import {ShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
import {XHR} from 'angular2/src/core/compiler/xhr/xhr';
import {XHRMock} from 'angular2/src/mock/xhr_mock';
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
import {StyleInliner} from 'angular2/src/core/compiler/style_inliner';
import {CssProcessor} from 'angular2/src/core/compiler/css_processor';
import {Injector} from 'angular2/di';
import {List, ListWrapper} from 'angular2/src/facade/collection';
import {FunctionWrapper} from 'angular2/src/facade/lang';
/**
* Returns the root injector bindings.
*
* This must be kept in sync with the _rootBindings in application.js
*
* @returns {*[]}
*/
function _getRootBindings() {
return [
bind(Reflector).toValue(reflector),
];
}
/**
* Returns the application injector bindings.
*
* This must be kept in sync with _injectorBindings() in application.js
*
* @returns {*[]}
*/
function _getAppBindings() {
return [
bind(ShadowDomStrategy).toClass(NativeShadowDomStrategy),
Compiler,
CompilerCache,
TemplateResolver,
bind(ChangeDetection).toValue(dynamicChangeDetection),
TemplateLoader,
DirectiveMetadataReader,
Parser,
Lexer,
ExceptionHandler,
bind(XHR).toClass(XHRMock),
ComponentUrlMapper,
UrlResolver,
StyleUrlResolver,
StyleInliner,
bind(CssProcessor).toFactory(() => new CssProcessor(null), []),
];
}
export function createTestInjector(bindings: List) {
var rootInjector = new Injector(_getRootBindings());
return rootInjector.createChild(ListWrapper.concat(_getAppBindings(), bindings));
}
/**
* Allows injecting dependencies in beforeEach() and it().
*
* Example:
*
* beforeEach(inject([Dependency, AClass], (dep, object) => {
* // some code that uses `dep` and `object`
* // ...
* }));
*
* it('...', inject([AClass, AsyncTestCompleter], (object, async) => {
* object.doSomething().then(() => {
* expect(...);
* async.done();
* });
* })
*
* Notes:
* - injecting an `AsyncTestCompleter` allow completing async tests - this is the equivalent of
* adding a `done` parameter in Jasmine,
* - inject is currently a function because of some Traceur limitation the syntax should eventually
* becomes `it('...', @Inject (object: AClass, async: AsyncTestCompleter) => { ... });`
*
* @param {Array} tokens
* @param {Function} fn
* @return {FunctionWithParamTokens}
*/
export function inject(tokens: List, fn: Function) {
return new FunctionWithParamTokens(tokens, fn);
}
export class FunctionWithParamTokens {
_tokens: List;
_fn: Function;
constructor(tokens: List, fn: Function) {
this._tokens = tokens;
this._fn = fn;
}
execute(injector: Injector) {
var params = ListWrapper.map(this._tokens, (t) => injector.get(t));
FunctionWrapper.apply(this._fn, params);
}
}

View File

@ -1,18 +1,76 @@
library test_lib.test_lib;
import 'package:guinness/guinness.dart' as gns;
export 'package:guinness/guinness.dart' hide Expect, expect, NotExpect, beforeEach, it, iit;
export 'package:guinness/guinness.dart' hide Expect, expect, NotExpect, beforeEach, it, iit, xit;
import 'package:unittest/unittest.dart' hide expect;
import 'dart:mirrors';
import 'dart:async';
import 'package:angular2/src/reflection/reflection.dart';
import 'package:angular2/src/reflection/reflection_capabilities.dart';
import 'package:collection/equality.dart';
import 'package:angular2/src/dom/dom_adapter.dart' show DOM;
import 'package:angular2/src/reflection/reflection.dart';
import 'package:angular2/src/reflection/reflection_capabilities.dart';
import 'package:angular2/src/di/binding.dart' show bind;
import 'package:angular2/src/di/injector.dart' show Injector;
import './test_injector.dart';
export './test_injector.dart' show inject;
bool IS_DARTIUM = true;
bool IS_NODEJS = false;
List _testBindings = [];
Injector _injector;
bool _isCurrentTestAsync;
bool _inIt = false;
class AsyncTestCompleter {
Completer _completer;
AsyncTestCompleter() {
_completer = new Completer();
}
done() {
_completer.complete();
}
get future => _completer.future;
}
testSetup() {
reflector.reflectionCapabilities = new ReflectionCapabilities();
// beforeEach configuration:
// - Priority 3: clear the bindings before each test,
// - Priority 2: collect the bindings before each test, see beforeEachBindings(),
// - Priority 1: create the test injector to be used in beforeEach() and it()
gns.beforeEach(
() {
_testBindings.clear();
},
priority: 3
);
var completerBinding = bind(AsyncTestCompleter).toFactory(() {
// Mark the test as async when an AsyncTestCompleter is injected in an it(),
if (!_inIt) throw 'AsyncTestCompleter can only be injected in an "it()"';
_isCurrentTestAsync = true;
return new AsyncTestCompleter();
});
gns.beforeEach(
() {
_isCurrentTestAsync = false;
_testBindings.add(completerBinding);
_injector = createTestInjector(_testBindings);
},
priority: 1
);
}
Expect expect(actual, [matcher]) {
final expect = new Expect(actual);
if (matcher != null) expect.to(matcher);
@ -46,38 +104,55 @@ class NotExpect extends gns.NotExpect {
}
beforeEach(fn) {
gns.beforeEach(_enableReflection(fn));
if (fn is! FunctionWithParamTokens) fn = new FunctionWithParamTokens([], fn);
gns.beforeEach(() {
fn.execute(_injector);
});
}
/**
* Allows overriding default bindings defined in test_injector.js.
*
* The given function must return a list of DI bindings.
*
* Example:
*
* beforeEachBindings(() => [
* bind(Compiler).toClass(MockCompiler),
* bind(SomeToken).toValue(myValue),
* ]);
*/
beforeEachBindings(fn) {
gns.beforeEach(
() {
var bindings = fn();
if (bindings != null) _testBindings.addAll(bindings);
},
priority: 2
);
}
_it(gnsFn, name, fn) {
if (fn is! FunctionWithParamTokens) fn = new FunctionWithParamTokens([], fn);
gnsFn(name, () {
_inIt = true;
fn.execute(_injector);
_inIt = false;
if (_isCurrentTestAsync) return _injector.get(AsyncTestCompleter).future;
});
}
it(name, fn) {
gns.it(name, _enableReflection(_handleAsync(fn)));
_it(gns.it, name, fn);
}
iit(name, fn) {
gns.iit(name, _enableReflection(_handleAsync(fn)));
_it(gns.iit, name, fn);
}
_enableReflection(fn) {
return () {
reflector.reflectionCapabilities = new ReflectionCapabilities();
return fn();
};
}
_handleAsync(fn) {
ClosureMirror cm = reflect(fn);
MethodMirror mm = cm.function;
var completer = new Completer();
if (mm.parameters.length == 1) {
return () {
cm.apply([completer.complete]);
return completer.future;
};
}
return fn;
xit(name, fn) {
_it(gns.xit, name, fn);
}
// TODO(tbosch): remove when https://github.com/vsavkin/guinness/issues/41

View File

@ -1,20 +1,160 @@
import {DOM} from 'angular2/src/dom/dom_adapter';
import {bind} from 'angular2/di';
import {createTestInjector, FunctionWithParamTokens, inject} from './test_injector';
export {inject} from './test_injector';
export {proxy} from 'rtts_assert/rtts_assert';
var _global = typeof window === 'undefined' ? global : window;
export {proxy} from 'rtts_assert/rtts_assert';
export var describe = _global.describe;
export var xdescribe = _global.xdescribe;
export var ddescribe = _global.ddescribe;
export var it = _global.it;
export var xit = _global.xit;
export var iit = _global.iit;
export var beforeEach = _global.beforeEach;
export var afterEach = _global.afterEach;
export var expect = _global.expect;
export var IS_DARTIUM = false;
export var IS_NODEJS = typeof window === 'undefined';
export class AsyncTestCompleter {
_done: Function;
constructor(done: Function) {
this._done = done;
}
done() {
this._done();
}
}
var jsmBeforeEach = _global.beforeEach;
var jsmDescribe = _global.describe;
var jsmDDescribe = _global.ddescribe;
var jsmXDescribe = _global.xdescribe;
var jsmIt = _global.it;
var jsmIIt = _global.iit;
var jsmXIt = _global.xit;
var runnerStack = [];
var inIt = false;
var testBindings;
class BeforeEachRunner {
constructor(parent: BeforeEachRunner) {
this._fns = [];
this._parent = parent;
}
beforeEach(fn: FunctionWithParamTokens) {
this._fns.push(fn);
}
run(injector) {
if (this._parent) this._parent.run();
this._fns.forEach((fn) => fn.execute(injector));
}
}
// Reset the test bindings before each test
jsmBeforeEach(() => { testBindings = []; });
function _describe(jsmFn, ...args) {
var parentRunner = runnerStack.length === 0 ? null : runnerStack[runnerStack.length - 1];
var runner = new BeforeEachRunner(parentRunner);
runnerStack.push(runner);
var suite = jsmFn(...args);
runnerStack.pop();
return suite;
}
export function describe(...args) {
return _describe(jsmDescribe, ...args);
}
export function ddescribe(...args) {
return _describe(jsmDDescribe, ...args);
}
export function xdescribe(...args) {
return _describe(jsmXDescribe, ...args);
}
export function beforeEach(fn) {
if (runnerStack.length > 0) {
// Inside a describe block, beforeEach() uses a BeforeEachRunner
var runner = runnerStack[runnerStack.length - 1];
if (!(fn instanceof FunctionWithParamTokens)) {
fn = inject([], fn);
}
runner.beforeEach(fn);
} else {
// Top level beforeEach() are delegated to jasmine
jsmBeforeEach(fn);
}
}
/**
* Allows overriding default bindings defined in test_injector.js.
*
* The given function must return a list of DI bindings.
*
* Example:
*
* beforeEachBindings(() => [
* bind(Compiler).toClass(MockCompiler),
* bind(SomeToken).toValue(myValue),
* ]);
*/
export function beforeEachBindings(fn) {
jsmBeforeEach(() => {
var bindings = fn();
if (!bindings) return;
testBindings = [...testBindings, ...bindings];
});
}
function _it(jsmFn, name, fn) {
var runner = runnerStack[runnerStack.length - 1];
jsmFn(name, function(done) {
var async = false;
var completerBinding = bind(AsyncTestCompleter).toFactory(() => {
// Mark the test as async when an AsyncTestCompleter is injected in an it()
if (!inIt) throw new Error('AsyncTestCompleter can only be injected in an "it()"');
async = true;
return new AsyncTestCompleter(done);
});
var injector = createTestInjector([...testBindings, completerBinding]);
runner.run(injector);
if (!(fn instanceof FunctionWithParamTokens)) {
fn = inject([], fn);
}
inIt = true;
fn.execute(injector);
inIt = false;
if (!async) done();
});
}
export function it(name, fn) {
return _it(jsmIt, name, fn);
}
export function xit(name, fn) {
return _it(jsmXIt, name, fn);
}
export function iit(name, fn) {
return _it(jsmIIt, name, fn);
}
// To make testing consistent between dart and js
_global.print = function(msg) {
if (_global.dump) {
@ -151,7 +291,6 @@ export class SpyObject {
}
}
function elementText(n) {
var hasNodes = (n) => {var children = DOM.childNodes(n); return children && children.length > 0;}
if (!IS_NODEJS) {

View File

@ -1,4 +1,15 @@
import {describe, ddescribe, it, iit, xit, xdescribe, expect, beforeEach} from 'angular2/test_lib';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xdescribe,
xit,
} from 'angular2/test_lib';
import {bootstrap, appDocumentToken, appElementToken}
from 'angular2/src/core/application';
import {Component} from 'angular2/src/core/annotations/annotations';
@ -69,55 +80,56 @@ export function main() {
});
describe('bootstrap factory method', () => {
it('should throw if no element is found', (done) => {
it('should throw if no element is found', inject([AsyncTestCompleter], (async) => {
var injectorPromise = bootstrap(HelloRootCmp, [], (e,t) => {throw e;});
PromiseWrapper.then(injectorPromise, null, (reason) => {
expect(reason.message).toContain(
'The app selector "hello-app" did not match any elements');
done();
});
async.done();
});
}));
it('should create an injector promise', () => {
var injectorPromise = bootstrap(HelloRootCmp, testBindings);
expect(injectorPromise).not.toBe(null);
});
it('should resolve an injector promise and contain bindings', (done) => {
it('should resolve an injector promise and contain bindings', inject([AsyncTestCompleter], (async) => {
var injectorPromise = bootstrap(HelloRootCmp, testBindings);
injectorPromise.then((injector) => {
expect(injector.get(appElementToken)).toBe(el);
done();
});
async.done();
});
}));
it('should provide the application component in the injector', (done) => {
it('should provide the application component in the injector', inject([AsyncTestCompleter], (async) => {
var injectorPromise = bootstrap(HelloRootCmp, testBindings);
injectorPromise.then((injector) => {
expect(injector.get(HelloRootCmp)).toBeAnInstanceOf(HelloRootCmp);
done();
});
async.done();
});
}));
it('should display hello world', (done) => {
it('should display hello world', inject([AsyncTestCompleter], (async) => {
var injectorPromise = bootstrap(HelloRootCmp, testBindings);
injectorPromise.then((injector) => {
expect(injector.get(appElementToken)).toHaveText('hello world!');
done();
});
});
it('should support multiple calls to bootstrap', (done) => {
expect(injector.get(appElementToken)).toHaveText('hello world!');
async.done();
});
}));
it('should support multiple calls to bootstrap', inject([AsyncTestCompleter], (async) => {
var injectorPromise1 = bootstrap(HelloRootCmp, testBindings);
var injectorPromise2 = bootstrap(HelloRootCmp2, testBindings);
PromiseWrapper.all([injectorPromise1, injectorPromise2]).then((injectors) => {
expect(injectors[0].get(appElementToken)).toHaveText('hello world!');
expect(injectors[1].get(appElementToken)).toHaveText('hello world, again!');
done();
});
async.done();
});
}));
it("should make the provided bindings available to the application component", (done) => {
it("should make the provided bindings available to the application component", inject([AsyncTestCompleter], (async) => {
var injectorPromise = bootstrap(HelloRootCmp3, [
testBindings,
bind("appBinding").toValue("BoundValue")
@ -125,25 +137,25 @@ export function main() {
injectorPromise.then((injector) => {
expect(injector.get(HelloRootCmp3).appBinding).toEqual("BoundValue");
done();
});
async.done();
});
}));
it("should avoid cyclic dependencies when root component requires Lifecycle through DI", (done) => {
it("should avoid cyclic dependencies when root component requires Lifecycle through DI", inject([AsyncTestCompleter], (async) => {
var injectorPromise = bootstrap(HelloRootCmp4, testBindings);
injectorPromise.then((injector) => {
expect(injector.get(HelloRootCmp4).lc).toBe(injector.get(LifeCycle));
done();
});
async.done();
});
}));
it("should support shadow dom content tag", (done) => {
it("should support shadow dom content tag", inject([AsyncTestCompleter], (async) => {
var injectorPromise = bootstrap(HelloRootCmpContent, testBindings);
injectorPromise.then((injector) => {
expect(injector.get(appElementToken)).toHaveText('before: loading after: done');
done();
});
async.done();
});
}));
});
}

View File

@ -1,4 +1,15 @@
import {describe, beforeEach, it, expect, ddescribe, iit, el, IS_DARTIUM} from 'angular2/test_lib';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
IS_DARTIUM,
it,
} from 'angular2/test_lib';
import {DOM} from 'angular2/src/dom/dom_adapter';
import {List, ListWrapper, Map, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
@ -51,7 +62,7 @@ export function runCompilerCommonTests() {
urlResolver, new ComponentUrlMapper());
}
it('should run the steps and return the ProtoView of the root element', (done) => {
it('should run the steps and return the ProtoView of the root element', inject([AsyncTestCompleter], (async) => {
var rootProtoView = new ProtoView(null, null, null);
var compiler = createCompiler( (parent, current, control) => {
current.inheritedProtoView = rootProtoView;
@ -59,21 +70,21 @@ export function runCompilerCommonTests() {
tplResolver.setTemplate(MainComponent, new Template({inline: '<div></div>'}));
compiler.compile(MainComponent).then( (protoView) => {
expect(protoView).toBe(rootProtoView);
done();
});
async.done();
});
}));
it('should use the inline template', (done) => {
it('should use the inline template', inject([AsyncTestCompleter], (async) => {
var compiler = createCompiler( (parent, current, control) => {
current.inheritedProtoView = new ProtoView(current.element, null, null);
});
compiler.compile(MainComponent).then( (protoView) => {
expect(DOM.getInnerHTML(protoView.element)).toEqual('inline component');
done();
});
async.done();
});
}));
it('should wait for async styles to be resolved', (done) => {
it('should wait for async styles to be resolved', inject([AsyncTestCompleter], (async) => {
var styleResolved = false;
var completer = PromiseWrapper.completer();
@ -95,11 +106,11 @@ export function runCompilerCommonTests() {
completer.resolve(null);
pvPromise.then((protoView) => {
expect(styleResolved).toEqual(true);
done();
});
async.done();
});
}));
it('should load nested components', (done) => {
it('should load nested components', inject([AsyncTestCompleter], (async) => {
var compiler = createCompiler( (parent, current, control) => {
if (DOM.hasClass(current.element, 'nested')) {
current.componentDirective = reader.read(NestedComponent);
@ -113,11 +124,11 @@ export function runCompilerCommonTests() {
compiler.compile(MainComponent).then( (protoView) => {
var nestedView = protoView.elementBinders[0].nestedProtoView;
expect(DOM.getInnerHTML(nestedView.element)).toEqual('nested component');
done();
});
async.done();
});
}));
it('should cache compiled components', (done) => {
it('should cache compiled components', inject([AsyncTestCompleter], (async) => {
var compiler = createCompiler( (parent, current, control) => {
current.inheritedProtoView = new ProtoView(current.element, null, null);
});
@ -128,11 +139,11 @@ export function runCompilerCommonTests() {
return compiler.compile(MainComponent);
}).then( (protoView) => {
expect(firstProtoView).toBe(protoView);
done();
});
async.done();
});
}));
it('should re-use components being compiled', (done) => {
it('should re-use components being compiled', inject([AsyncTestCompleter], (async) => {
var nestedElBinders = [];
var compiler = createCompiler( (parent, current, control) => {
current.inheritedProtoView = new ProtoView(current.element, null, null);
@ -146,11 +157,11 @@ export function runCompilerCommonTests() {
new Template({inline: '<div><div class="nested"></div><div class="nested"></div></div>'}));
compiler.compile(MainComponent).then( (protoView) => {
expect(nestedElBinders[0].nestedProtoView).toBe(nestedElBinders[1].nestedProtoView);
done();
});
async.done();
});
}));
it('should allow recursive components', (done) => {
it('should allow recursive components', inject([AsyncTestCompleter], (async) => {
var compiler = createCompiler( (parent, current, control) => {
current.inheritedProtoView = new ProtoView(current.element, null, null);
current.inheritedElementBinder = current.inheritedProtoView.bindElement(null);
@ -158,9 +169,9 @@ export function runCompilerCommonTests() {
});
compiler.compile(RecursiveComponent).then( (protoView) => {
expect(protoView.elementBinders[0].nestedProtoView).toBe(protoView);
done();
});
async.done();
});
}));
});
});
@ -176,7 +187,7 @@ export function runCompilerCommonTests() {
}
function createNestedComponentSpec(name, resolver: TemplateResolver, error:string = null) {
it(`should load nested components ${name}`, (done) => {
it(`should load nested components ${name}`, inject([AsyncTestCompleter], (async) => {
var compiler = createCompiler((parent, current, control) => {
if (DOM.hasClass(current.element, 'parent')) {
@ -193,14 +204,14 @@ export function runCompilerCommonTests() {
var nestedView = protoView.elementBinders[0].nestedProtoView;
expect(error).toBeNull();
expect(DOM.getInnerHTML(nestedView.element)).toEqual('nested component');
done();
async.done();
},
function(compileError) {
expect(compileError.message).toEqual(error);
done();
async.done();
}
);
});
}));
}
var templateResolver = new FakeTemplateResolver();
@ -244,7 +255,7 @@ export function runCompilerCommonTests() {
});
describe('URL resolution', () => {
it('should resolve template URLs by combining application, component and template URLs', (done) => {
it('should resolve template URLs by combining application, component and template URLs', inject([AsyncTestCompleter], (async) => {
var steps = [new MockStep((parent, current, control) => {
current.inheritedProtoView = new ProtoView(current.element, null, null);
})];
@ -263,9 +274,9 @@ export function runCompilerCommonTests() {
tplResolver.setTemplate(MainComponent, template);
compiler.compile(MainComponent).then((protoView) => {
expect(tplLoader.getTemplateUrl(template)).toEqual('http://www.app.com/cmp/tpl.html');
done();
async.done();
});
})
}))
});
});
}

View File

@ -1,9 +1,11 @@
library angular2.compiler.html5lib_dom_adapter.test;
import 'package:angular2/src/dom/html5lib_adapter.dart';
import 'package:angular2/src/test_lib/test_lib.dart' show testSetup;
import 'compiler_common_tests.dart';
void main() {
Html5LibDomAdapter.makeCurrent();
testSetup();
runCompilerCommonTests();
}

View File

@ -1,4 +1,15 @@
import {describe, xit, it, expect, beforeEach, ddescribe, iit, el} from 'angular2/test_lib';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
xit,
} from 'angular2/test_lib';
import {DOM} from 'angular2/src/dom/dom_adapter';
import {Type, isPresent, BaseException, assertionsEnabled, isJsObject} from 'angular2/src/facade/lang';
@ -61,7 +72,7 @@ export function main() {
cd = view.changeDetector;
}
it('should consume text node changes', (done) => {
it('should consume text node changes', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp, new Template({inline: '<div>{{ctxProp}}</div>'}));
compiler.compile(MyComp).then((pv) => {
createView(pv);
@ -69,11 +80,11 @@ export function main() {
cd.detectChanges();
expect(DOM.getInnerHTML(view.nodes[0])).toEqual('Hello World!');
done();
});
async.done();
});
}));
it('should consume element binding changes', (done) => {
it('should consume element binding changes', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp, new Template({inline: '<div [id]="ctxProp"></div>'}));
compiler.compile(MyComp).then((pv) => {
@ -83,11 +94,11 @@ export function main() {
cd.detectChanges();
expect(view.nodes[0].id).toEqual('Hello World!');
done();
});
async.done();
});
}));
it('should consume binding to aria-* attributes', (done) => {
it('should consume binding to aria-* attributes', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp, new Template({inline: '<div [aria-label]="ctxProp"></div>'}));
compiler.compile(MyComp).then((pv) => {
@ -101,11 +112,11 @@ export function main() {
cd.detectChanges();
expect(DOM.getAttribute(view.nodes[0], 'aria-label')).toEqual('Changed aria label');
done();
});
async.done();
});
}));
it('should consume binding to property names where attr name and property name do not match', (done) => {
it('should consume binding to property names where attr name and property name do not match', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp, new Template({inline: '<div [tabindex]="ctxNumProp"></div>'}));
compiler.compile(MyComp).then((pv) => {
@ -118,11 +129,11 @@ export function main() {
cd.detectChanges();
expect(view.nodes[0].tabIndex).toEqual(5);
done();
});
async.done();
});
}));
it('should consume binding to inner-html', (done) => {
it('should consume binding to inner-html', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp, new Template({inline: '<div inner-html="{{ctxProp}}"></div>'}));
compiler.compile(MyComp).then((pv) => {
@ -136,11 +147,11 @@ export function main() {
cd.detectChanges();
expect(DOM.getInnerHTML(view.nodes[0])).toEqual('Some other <div>HTML</div>');
done();
});
async.done();
});
}));
it('should consume directive watch expression change.', (done) => {
it('should consume directive watch expression change.', inject([AsyncTestCompleter], (async) => {
var tpl =
'<div>' +
'<div my-dir [elprop]="ctxProp"></div>' +
@ -160,11 +171,11 @@ export function main() {
expect(view.elementInjectors[1].get(MyDir).dirProp).toEqual('Hi there!');
expect(view.elementInjectors[2].get(MyDir).dirProp).toEqual('Hi there!');
expect(view.elementInjectors[3].get(MyDir).dirProp).toEqual('One more Hello World!');
done();
});
async.done();
});
}));
it("should support pipes in bindings and bind config", (done) => {
it("should support pipes in bindings and bind config", inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp,
new Template({
inline: '<component-with-pipes #comp [prop]="ctxProp | double"></component-with-pipes>',
@ -187,11 +198,11 @@ export function main() {
// it is doubled twice: once in the binding, second time in the bind config
expect(comp.prop).toEqual('aaaa');
done();
});
async.done();
});
}));
it('should support nested components.', (done) => {
it('should support nested components.', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp, new Template({
inline: '<child-cmp></child-cmp>',
directives: [ChildComp]
@ -203,12 +214,12 @@ export function main() {
cd.detectChanges();
expect(view.nodes[0].shadowRoot.childNodes[0].nodeValue).toEqual('hello');
done();
});
async.done();
});
}));
// GH issue 328 - https://github.com/angular/angular/issues/328
it('should support different directive types on a single node', (done) => {
it('should support different directive types on a single node', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp,
new Template({
inline: '<child-cmp my-dir [elprop]="ctxProp"></child-cmp>',
@ -225,11 +236,11 @@ export function main() {
expect(elInj.get(MyDir).dirProp).toEqual('Hello World!');
expect(elInj.get(ChildComp).dirProp).toEqual(null);
done();
});
async.done();
});
}));
it('should support directives where a binding attribute is not given', function(done) {
it('should support directives where a binding attribute is not given', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp,
new Template({
// No attribute "el-prop" specified.
@ -239,11 +250,11 @@ export function main() {
compiler.compile(MyComp).then((pv) => {
createView(pv);
done();
});
async.done();
});
}));
it('should support directives where a selector matches property binding', function(done) {
it('should support directives where a selector matches property binding', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp,
new Template({
inline: '<p [id]="ctxProp"></p>',
@ -263,11 +274,11 @@ export function main() {
expect(view.nodes[0].id).toEqual('other_id');
expect(DOM.getInnerHTML(view.nodes[0].shadowRoot.childNodes[0])).toEqual('Matched on id with other_id');
done();
});
async.done();
});
}));
it('should support template directives via `<template>` elements.', (done) => {
it('should support template directives via `<template>` elements.', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp,
new Template({
inline: '<div><template some-viewport var-greeting="some-tmpl"><copy-me>{{greeting}}</copy-me></template></div>',
@ -284,11 +295,11 @@ export function main() {
expect(childNodesOfWrapper.length).toBe(3);
expect(childNodesOfWrapper[1].childNodes[0].nodeValue).toEqual('hello');
expect(childNodesOfWrapper[2].childNodes[0].nodeValue).toEqual('again');
done();
});
async.done();
});
}));
it('should support template directives via `template` attribute.', (done) => {
it('should support template directives via `template` attribute.', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp, new Template({
inline: '<div><copy-me template="some-viewport: var greeting=some-tmpl">{{greeting}}</copy-me></div>',
directives: [SomeViewport]
@ -304,11 +315,11 @@ export function main() {
expect(childNodesOfWrapper.length).toBe(3);
expect(childNodesOfWrapper[1].childNodes[0].nodeValue).toEqual('hello');
expect(childNodesOfWrapper[2].childNodes[0].nodeValue).toEqual('again');
done();
});
async.done();
});
}));
it('should assign the component instance to a var-', (done) => {
it('should assign the component instance to a var-', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp, new Template({
inline: '<p><child-cmp var-alice></child-cmp></p>',
directives: [ChildComp]
@ -320,11 +331,11 @@ export function main() {
expect(view.contextWithLocals).not.toBe(null);
expect(view.contextWithLocals.get('alice')).toBeAnInstanceOf(ChildComp);
done();
async.done();
})
});
}));
it('should assign two component instances each with a var-', (done) => {
it('should assign two component instances each with a var-', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp, new Template({
inline: '<p><child-cmp var-alice></child-cmp><child-cmp var-bob></p>',
directives: [ChildComp]
@ -338,11 +349,11 @@ export function main() {
expect(view.contextWithLocals.get('bob')).toBeAnInstanceOf(ChildComp);
expect(view.contextWithLocals.get('alice')).not.toBe(view.contextWithLocals.get('bob'));
done();
async.done();
})
});
}));
it('should assign the component instance to a var- with shorthand syntax', (done) => {
it('should assign the component instance to a var- with shorthand syntax', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp, new Template({
inline: '<child-cmp #alice></child-cmp>',
directives: [ChildComp]
@ -354,11 +365,11 @@ export function main() {
expect(view.contextWithLocals).not.toBe(null);
expect(view.contextWithLocals.get('alice')).toBeAnInstanceOf(ChildComp);
done();
async.done();
})
});
}));
it('should assign the element instance to a user-defined variable', (done) => {
it('should assign the element instance to a user-defined variable', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp,
new Template({inline: '<p><div var-alice><i>Hello</i></div></p>'}));
@ -370,11 +381,11 @@ export function main() {
expect(value).not.toBe(null);
expect(value.tagName.toLowerCase()).toEqual('div');
done();
async.done();
})
});
}));
it('should provide binding configuration config to the component', (done) => {
it('should provide binding configuration config to the component', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp, new Template({
inline: '<push-cmp #cmp></push-cmp>',
directives: [[[PushBasedComp]]]
@ -395,11 +406,11 @@ export function main() {
cd.detectChanges();
expect(cmp.numberOfChecks).toEqual(2);
done();
async.done();
})
});
}));
it('should create a component that injects a @Parent', (done) => {
it('should create a component that injects a @Parent', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp, new Template({
inline: '<some-directive><cmp-with-parent #child></cmp-with-parent></some-directive>',
directives: [SomeDirective, CompWithParent]
@ -411,11 +422,11 @@ export function main() {
var childComponent = view.contextWithLocals.get('child');
expect(childComponent.myParent).toBeAnInstanceOf(SomeDirective);
done();
async.done();
})
});
}));
it('should create a component that injects an @Ancestor', (done) => {
it('should create a component that injects an @Ancestor', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp, new Template({
inline: `
<some-directive>
@ -432,11 +443,11 @@ export function main() {
var childComponent = view.contextWithLocals.get('child');
expect(childComponent.myAncestor).toBeAnInstanceOf(SomeDirective);
done();
async.done();
})
});
}));
it('should create a component that injects an @Ancestor through viewport directive', (done) => {
it('should create a component that injects an @Ancestor through viewport directive', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp, new Template({
inline: `
<some-directive>
@ -455,11 +466,11 @@ export function main() {
var childComponent = subview.contextWithLocals.get('child');
expect(childComponent.myAncestor).toBeAnInstanceOf(SomeDirective);
done();
})
async.done();
});
}));
it('should support events', (done) => {
it('should support events', inject([AsyncTestCompleter], (async) => {
tplResolver.setTemplate(MyComp, new Template({
inline: '<div emitter listener></div>',
directives: [DecoratorEmitingEvent, DecoratorListeningEvent]
@ -480,9 +491,9 @@ export function main() {
expect(emitter.msg).toEqual('fired !');
expect(listener.msg).toEqual('fired !');
done();
});
async.done();
});
}));
});
@ -492,7 +503,7 @@ export function main() {
tplResolver.setTemplate(MyComp, new Template({inline: inlineTpl}));
PromiseWrapper.then(compiler.compile(MyComp),
(value) => {
done("Test failure: should not have come here as an exception was expected");
throw new BaseException("Test failure: should not have come here as an exception was expected");
},
(err) => {
expect(err.message).toEqual(errMessage);
@ -501,45 +512,45 @@ export function main() {
);
}
it('should raise an error if no directive is registered for an unsupported DOM property', (done) => {
it('should raise an error if no directive is registered for an unsupported DOM property', inject([AsyncTestCompleter], (async) => {
expectCompileError(
'<div [some-prop]="foo"></div>',
'Missing directive to handle \'some-prop\' in MyComp: <div [some-prop]="foo">',
done
() => async.done()
);
});
}));
it('should raise an error if no directive is registered for a template with template bindings', (done) => {
it('should raise an error if no directive is registered for a template with template bindings', inject([AsyncTestCompleter], (async) => {
expectCompileError(
'<div><div template="if: foo"></div></div>',
'Missing directive to handle \'if\' in <div template="if: foo">',
done
() => async.done()
);
});
}));
it('should raise an error for missing template directive (1)', (done) => {
it('should raise an error for missing template directive (1)', inject([AsyncTestCompleter], (async) => {
expectCompileError(
'<div><template foo></template></div>',
'Missing directive to handle: <template foo>',
done
() => async.done()
);
});
}));
it('should raise an error for missing template directive (2)', (done) => {
it('should raise an error for missing template directive (2)', inject([AsyncTestCompleter], (async) => {
expectCompileError(
'<div><template *if="condition"></template></div>',
'Missing directive to handle: <template *if="condition">',
done
() => async.done()
);
});
}));
it('should raise an error for missing template directive (3)', (done) => {
it('should raise an error for missing template directive (3)', inject([AsyncTestCompleter], (async) => {
expectCompileError(
'<div *if="condition"></div>',
'Missing directive to handle \'if\' in MyComp: <div *if="condition">',
done
() => async.done()
);
});
}));
}
});
}

View File

@ -1,4 +1,16 @@
import {describe, xit, it, expect, beforeEach, ddescribe, iit, el, IS_NODEJS} from 'angular2/test_lib';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
IS_NODEJS,
it,
xit,
} from 'angular2/test_lib';
import {StringMapWrapper, List} from 'angular2/src/facade/collection';
import {Type} from 'angular2/src/facade/lang';
@ -80,7 +92,7 @@ export function main() {
});
}
it('should support multiple content tags', (done) => {
it('should support multiple content tags', inject([AsyncTestCompleter], (async) => {
var temp = '<multiple-content-tags>' +
'<div>B</div>' +
'<div>C</div>' +
@ -89,11 +101,11 @@ export function main() {
compile(temp, [MultipleContentTagsComponent], (view, lc) => {
expect(view.nodes).toHaveText('(A, BC)');
done();
});
async.done();
});
}));
it('should redistribute only direct children', (done) => {
it('should redistribute only direct children', inject([AsyncTestCompleter], (async) => {
var temp = '<multiple-content-tags>' +
'<div>B<div class="left">A</div></div>' +
'<div>C</div>' +
@ -101,11 +113,11 @@ export function main() {
compile(temp, [MultipleContentTagsComponent], (view, lc) => {
expect(view.nodes).toHaveText('(, BAC)');
done();
});
async.done();
});
}));
it("should redistribute direct child viewcontainers when the light dom changes", (done) => {
it("should redistribute direct child viewcontainers when the light dom changes", inject([AsyncTestCompleter], (async) => {
var temp = '<multiple-content-tags>' +
'<div><div template="manual" class="left">A</div></div>' +
'<div>B</div>' +
@ -126,11 +138,11 @@ export function main() {
expect(view.nodes).toHaveText('(, B)');
done();
});
async.done();
});
}));
it("should redistribute when the light dom changes", (done) => {
it("should redistribute when the light dom changes", inject([AsyncTestCompleter], (async) => {
var temp = '<multiple-content-tags>' +
'<div template="manual" class="left">A</div>' +
'<div>B</div>' +
@ -151,11 +163,11 @@ export function main() {
expect(view.nodes).toHaveText('(, B)');
done();
});
async.done();
});
}));
it("should support nested components", (done) => {
it("should support nested components", inject([AsyncTestCompleter], (async) => {
var temp = '<outer-with-indirect-nested>' +
'<div>A</div>' +
'<div>B</div>' +
@ -164,11 +176,11 @@ export function main() {
compile(temp, [OuterWithIndirectNestedComponent], (view, lc) => {
expect(view.nodes).toHaveText('OUTER(SIMPLE(AB))');
done();
});
async.done();
});
}));
it("should support nesting with content being direct child of a nested component", (done) => {
it("should support nesting with content being direct child of a nested component", inject([AsyncTestCompleter], (async) => {
var temp = '<outer>' +
'<div template="manual" class="left">A</div>' +
'<div>B</div>' +
@ -184,11 +196,11 @@ export function main() {
lc.tick();
expect(view.nodes).toHaveText('OUTER(INNER(INNERINNER(A,BC)))');
done();
});
async.done();
});
}));
it('should redistribute when the shadow dom changes', (done) => {
it('should redistribute when the shadow dom changes', inject([AsyncTestCompleter], (async) => {
var temp = '<conditional-content>' +
'<div class="left">A</div>' +
'<div>B</div>' +
@ -211,9 +223,9 @@ export function main() {
expect(view.nodes).toHaveText('(, ABC)');
done();
});
async.done();
});
}));
//Implement once NgElement support changing a class
//it("should redistribute when a class has been added or removed");

View File

@ -1,4 +1,15 @@
import {describe, beforeEach, it, expect, ddescribe, iit, SpyObject, el} from 'angular2/test_lib';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
SpyObject,
} from 'angular2/test_lib';
import {
NativeShadowDomStrategy,
@ -114,7 +125,7 @@ export function main() {
expect(styleElement).toHaveText(".foo[_ngcontent-0] {\n\n}\n\n[_nghost-0] {\n\n}");
});
it('should inline @import rules', (done) => {
it('should inline @import rules', inject([AsyncTestCompleter], (async) => {
xhr.reply('http://base/one.css', '.one {}');
var template = el('<div><style>@import "one.css";</style></div>');
@ -133,9 +144,9 @@ export function main() {
expect(styleElement).toHaveText('');
parentpv.stylePromises[0].then((_) => {
expect(styleElement).toHaveText('.one[_ngcontent-0] {\n\n}');
done();
});
async.done();
});
}));
it('should return the same style given the same component', () => {
var template = el('<div><style>.foo {} :host {}</style></div>');

View File

@ -1,4 +1,15 @@
import {describe, it, expect, beforeEach, ddescribe, iit, xit, el} from 'angular2/test_lib';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
xit,
} from 'angular2/test_lib';
import {StyleInliner} from 'angular2/src/core/compiler/style_inliner';
import {isBlank} from 'angular2/src/facade/lang';
@ -28,7 +39,7 @@ export function main() {
expect(loadedCss).toEqual(css);
});
it('should inline @import rules', (done) => {
it('should inline @import rules', inject([AsyncTestCompleter], (async) => {
xhr.reply('http://base/one.css', '.one {}');
var css = '@import url("one.css");.main {}';
var loadedCss = inliner.inlineImports(css, 'http://base');
@ -37,16 +48,15 @@ export function main() {
loadedCss,
function(css) {
expect(css).toEqual('.one {}\n.main {}');
done();
async.done();
},
function(e) {
throw 'fail;'
}
);
});
}));
// TODO(vicb): fix the StyleInliner
it('should support url([unquoted url]) in @import rules', (done) => {
it('should support url([unquoted url]) in @import rules', inject([AsyncTestCompleter], (async) => {
xhr.reply('http://base/one.css', '.one {}');
var css = '@import url(one.css);.main {}';
var loadedCss = inliner.inlineImports(css, 'http://base');
@ -55,15 +65,15 @@ export function main() {
loadedCss,
function(css) {
expect(css).toEqual('.one {}\n.main {}');
done();
async.done();
},
function(e) {
throw 'fail;'
}
);
});
}));
it('should handle @import error gracefuly', (done) => {
it('should handle @import error gracefuly', inject([AsyncTestCompleter], (async) => {
var css = '@import "one.css";.main {}';
var loadedCss = inliner.inlineImports(css, 'http://base');
expect(loadedCss).toBePromise();
@ -71,15 +81,15 @@ export function main() {
loadedCss,
function(css) {
expect(css).toEqual('/* failed to import http://base/one.css */\n.main {}');
done();
async.done();
},
function(e) {
throw 'fail;'
}
);
});
}));
it('should inline multiple @import rules', (done) => {
it('should inline multiple @import rules', inject([AsyncTestCompleter], (async) => {
xhr.reply('http://base/one.css', '.one {}');
xhr.reply('http://base/two.css', '.two {}');
var css = '@import "one.css";@import "two.css";.main {}';
@ -89,15 +99,15 @@ export function main() {
loadedCss,
function(css) {
expect(css).toEqual('.one {}\n.two {}\n.main {}');
done();
async.done();
},
function(e) {
throw 'fail;'
}
);
});
}));
it('should inline nested @import rules', (done) => {
it('should inline nested @import rules', inject([AsyncTestCompleter], (async) => {
xhr.reply('http://base/one.css', '@import "two.css";.one {}');
xhr.reply('http://base/two.css', '.two {}');
var css = '@import "one.css";.main {}';
@ -107,15 +117,15 @@ export function main() {
loadedCss,
function(css) {
expect(css).toEqual('.two {}\n.one {}\n.main {}');
done();
async.done();
},
function(e) {
throw 'fail;'
}
);
});
}));
it('should handle circular dependencies gracefuly', (done) => {
it('should handle circular dependencies gracefuly', inject([AsyncTestCompleter], (async) => {
xhr.reply('http://base/one.css', '@import "two.css";.one {}');
xhr.reply('http://base/two.css', '@import "one.css";.two {}');
var css = '@import "one.css";.main {}';
@ -125,15 +135,15 @@ export function main() {
loadedCss,
function(css) {
expect(css).toEqual('.two {}\n.one {}\n.main {}');
done();
async.done();
},
function(e) {
throw 'fail;'
}
);
});
}));
it('should handle invalid @import fracefuly', (done) => {
it('should handle invalid @import fracefuly', inject([AsyncTestCompleter], (async) => {
// Invalid rule: the url is not quoted
var css = '@import one.css;.main {}';
var loadedCss = inliner.inlineImports(css, 'http://base/');
@ -142,17 +152,17 @@ export function main() {
loadedCss,
function(css) {
expect(css).toEqual('/* Invalid import rule: "@import one.css;" */.main {}');
done();
async.done();
},
function(e) {
throw 'fail;'
}
);
});
}));
});
describe('media query', () => {
it('should wrap inlined content in media query', (done) => {
it('should wrap inlined content in media query', inject([AsyncTestCompleter], (async) => {
xhr.reply('http://base/one.css', '.one {}');
var css = '@import "one.css" (min-width: 700px) and (orientation: landscape);';
var loadedCss = inliner.inlineImports(css, 'http://base/');
@ -161,17 +171,17 @@ export function main() {
loadedCss,
function(css) {
expect(css).toEqual('@media (min-width: 700px) and (orientation: landscape) {\n.one {}\n}\n');
done();
async.done();
},
function(e) {
throw 'fail;'
}
);
});
}));
});
describe('url rewritting', () => {
it('should rewrite url in inlined content', (done) => {
it('should rewrite url in inlined content', inject([AsyncTestCompleter], (async) => {
// it should rewrite both '@import' and 'url()'
xhr.reply('http://base/one.css', '@import "./nested/two.css";.one {background-image: url("one.jpg");}');
xhr.reply('http://base/nested/two.css', '.two {background-image: url("../img/two.jpg");}');
@ -185,13 +195,13 @@ export function main() {
".two {background-image: url('http://base/img/two.jpg');}\n" +
".one {background-image: url('http://base/one.jpg');}\n"
);
done();
async.done();
},
function(e) {
throw 'fail;'
}
);
});
}));
});
});
}

View File

@ -1,4 +1,15 @@
import {describe, it, expect, beforeEach, ddescribe, iit, xit, el} from 'angular2/test_lib';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
xit,
} from 'angular2/test_lib';
import {DOM} from 'angular2/src/dom/dom_adapter';
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
@ -21,18 +32,18 @@ export function main() {
expect(DOM.content(loader.load(template))).toHaveText('inline template');
});
it('should load templates through XHR', (done) => {
it('should load templates through XHR', inject([AsyncTestCompleter], (async) => {
xhr.expect('base/foo', 'xhr template');
var template = new Template({url: '/foo'});
loader.setBaseUrl(template, 'base');
loader.load(template).then((el) => {
expect(DOM.content(el)).toHaveText('xhr template');
done();
async.done();
});
xhr.flush();
});
}));
it('should cache template loaded through XHR', (done) => {
it('should cache template loaded through XHR', inject([AsyncTestCompleter], (async) => {
var firstEl;
xhr.expect('base/foo', 'xhr template');
var template = new Template({url: '/foo'});
@ -45,10 +56,10 @@ export function main() {
.then((el) =>{
expect(el).toBe(firstEl);
expect(DOM.content(el)).toHaveText('xhr template');
done();
async.done();
});
xhr.flush();
});
}));
it('should throw when no template is defined', () => {
var template = new Template({inline: null, url: null});
@ -56,7 +67,7 @@ export function main() {
.toThrowError('Templates should have either their url or inline property set');
});
it('should return a rejected Promise when xhr loading fails', (done) => {
it('should return a rejected Promise when xhr loading fails', inject([AsyncTestCompleter], (async) => {
xhr.expect('base/foo', null);
var template = new Template({url: '/foo'});
loader.setBaseUrl(template, 'base');
@ -64,11 +75,11 @@ export function main() {
function(_) { throw 'Unexpected response'; },
function(error) {
expect(error).toEqual('Failed to load base/foo');
done();
async.done();
}
)
xhr.flush();
});
}));
});
}

View File

@ -1,4 +1,15 @@
import {describe, ddescribe, it, iit, xit, xdescribe, expect, beforeEach, async, tick} from 'angular2/test_lib';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xdescribe,
xit,
} from 'angular2/test_lib';
import {Log, once} from 'angular2/test_lib';
import {PromiseWrapper} from 'angular2/src/facade/async';
import {BaseException} from 'angular2/src/facade/lang';
@ -44,7 +55,7 @@ export function main() {
});
it('should call onTurnStart and onTurnDone before and after each turn', (done) => {
it('should call onTurnStart and onTurnDone before and after each turn', inject([AsyncTestCompleter], (async) => {
var a = PromiseWrapper.completer();
var b = PromiseWrapper.completer();
@ -59,9 +70,9 @@ export function main() {
PromiseWrapper.all([a.promise, b.promise]).then((_) => {
expect(log.result()).toEqual('onTurnStart; run start; onTurnDone; onTurnStart; a then; onTurnDone; onTurnStart; b then; onTurnDone');
done();
});
async.done();
});
}));
});
describe("runOutsideAngular", () => {
@ -101,7 +112,7 @@ export function main() {
}).toThrowError('bbb');
});
it('should produce long stack traces', (done) => {
it('should produce long stack traces', inject([AsyncTestCompleter], (async) => {
zone.initCallbacks({onErrorHandler: saveStackTrace});
var c = PromiseWrapper.completer();
@ -118,11 +129,11 @@ export function main() {
c.promise.then((_) => {
// then number of traces for JS and Dart is different
expect(trace.length).toBeGreaterThan(1);
done();
});
async.done();
});
}));
it('should produce long stack traces (when using promises)', (done) => {
it('should produce long stack traces (when using promises)', inject([AsyncTestCompleter], (async) => {
zone.initCallbacks({onErrorHandler: saveStackTrace});
var c = PromiseWrapper.completer();
@ -139,11 +150,11 @@ export function main() {
c.promise.then((_) => {
// then number of traces for JS and Dart is different
expect(trace.length).toBeGreaterThan(1);
done();
});
async.done();
});
}));
it('should disable long stack traces', (done) => {
it('should disable long stack traces', inject([AsyncTestCompleter], (async) => {
var zone = new VmTurnZone({enableLongStackTrace: false});
zone.initCallbacks({onErrorHandler: saveStackTrace});
@ -160,9 +171,9 @@ export function main() {
c.promise.then((_) => {
expect(trace.length).toEqual(1);
done();
});
async.done();
});
}));
});
});
}

View File

@ -1,4 +1,14 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach} from 'angular2/test_lib';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xit,
} from 'angular2/test_lib';
import {Injector, Inject, InjectPromise, bind, Key} from 'angular2/di';
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
@ -54,17 +64,17 @@ export function main() {
expect(injector.asyncGet(UserList)).toBePromise();
});
it('should return the injector', function (done) {
it('should return the injector', inject([AsyncTestCompleter], (async) => {
var injector = new Injector([]);
var p = injector.asyncGet(Injector);
p.then(function (injector) {
expect(injector).toBe(injector);
done();
});
async.done();
});
}));
it('should return a promise when instantiating a sync binding ' +
'with an async dependency', function (done) {
'with an async dependency', inject([AsyncTestCompleter], (async) => {
var injector = new Injector([
bind(UserList).toAsyncFactory(fetchUsers),
UserController
@ -73,11 +83,11 @@ export function main() {
injector.asyncGet(UserController).then(function (userController) {
expect(userController).toBeAnInstanceOf(UserController);
expect(userController.list).toBeAnInstanceOf(UserList);
done();
});
async.done();
});
}));
it("should create only one instance (async + async)", function (done) {
it("should create only one instance (async + async)", inject([AsyncTestCompleter], (async) => {
var injector = new Injector([
bind(UserList).toAsyncFactory(fetchUsers)
]);
@ -87,11 +97,11 @@ export function main() {
PromiseWrapper.all([ul1, ul2]).then(function (uls) {
expect(uls[0]).toBe(uls[1]);
done();
});
async.done();
});
}));
it("should create only one instance (sync + async)", function (done) {
it("should create only one instance (sync + async)", inject([AsyncTestCompleter], (async) => {
var injector = new Injector([
UserList
]);
@ -104,11 +114,11 @@ export function main() {
promise.then(function (ful) {
expect(ful).toBe(ul);
done();
});
async.done();
});
}));
it('should show the full path when error happens in a constructor', function (done) {
it('should show the full path when error happens in a constructor', inject([AsyncTestCompleter], (async) => {
var injector = new Injector([
UserController,
bind(UserList).toAsyncFactory(function () {
@ -119,9 +129,9 @@ export function main() {
var promise = injector.asyncGet(UserController);
PromiseWrapper.then(promise, null, function (e) {
expect(e.message).toContain("Error during instantiation of UserList! (UserController -> UserList)");
done();
});
async.done();
});
}));
});
describe("get", function () {

View File

@ -1,4 +1,15 @@
import {describe, xit, it, expect, beforeEach, ddescribe, iit, el} from 'angular2/test_lib';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
xit,
} from 'angular2/test_lib';
import {DOM} from 'angular2/src/dom/dom_adapter';
import {ListWrapper} from 'angular2/src/facade/collection';
@ -60,17 +71,17 @@ export function main() {
var TEMPLATE = '<div><copy-me template="foreach #item in items">{{item.toString()}};</copy-me></div>';
it('should reflect initial elements', (done) => {
it('should reflect initial elements', inject([AsyncTestCompleter], (async) => {
compileWithTemplate(TEMPLATE).then((pv) => {
createView(pv);
cd.detectChanges();
expect(DOM.getText(view.nodes[0])).toEqual('1;2;');
done();
});
async.done();
});
}));
it('should reflect added elements', (done) => {
it('should reflect added elements', inject([AsyncTestCompleter], (async) => {
compileWithTemplate(TEMPLATE).then((pv) => {
createView(pv);
cd.detectChanges();
@ -79,11 +90,11 @@ export function main() {
cd.detectChanges();
expect(DOM.getText(view.nodes[0])).toEqual('1;2;3;');
done();
});
async.done();
});
}));
it('should reflect removed elements', (done) => {
it('should reflect removed elements', inject([AsyncTestCompleter], (async) => {
compileWithTemplate(TEMPLATE).then((pv) => {
createView(pv);
cd.detectChanges();
@ -92,11 +103,11 @@ export function main() {
cd.detectChanges();
expect(DOM.getText(view.nodes[0])).toEqual('1;');
done();
});
async.done();
});
}));
it('should reflect moved elements', (done) => {
it('should reflect moved elements', inject([AsyncTestCompleter], (async) => {
compileWithTemplate(TEMPLATE).then((pv) => {
createView(pv);
cd.detectChanges();
@ -106,11 +117,11 @@ export function main() {
cd.detectChanges();
expect(DOM.getText(view.nodes[0])).toEqual('2;1;');
done();
});
async.done();
});
}));
it('should reflect a mix of all changes (additions/removals/moves)', (done) => {
it('should reflect a mix of all changes (additions/removals/moves)', inject([AsyncTestCompleter], (async) => {
compileWithTemplate(TEMPLATE).then((pv) => {
createView(pv);
component.items = [0, 1, 2, 3, 4, 5];
@ -120,9 +131,9 @@ export function main() {
cd.detectChanges();
expect(DOM.getText(view.nodes[0])).toEqual('6;2;7;0;4;8;');
done();
});
async.done();
});
}));
it('should iterate over an array of objects', () => {
compileWithTemplate('<ul><li template="foreach #item in items">{{item["name"]}};</li></ul>').then((pv) => {
@ -148,16 +159,16 @@ export function main() {
});
});
it('should gracefully handle nulls', (done) => {
it('should gracefully handle nulls', inject([AsyncTestCompleter], (async) => {
compileWithTemplate('<ul><li template="foreach #item in null">{{item}};</li></ul>').then((pv) => {
createView(pv);
cd.detectChanges();
expect(DOM.getText(view.nodes[0])).toEqual('');
done();
});
async.done();
});
}));
it('should gracefully handle ref changing to null and back', (done) => {
it('should gracefully handle ref changing to null and back', inject([AsyncTestCompleter], (async) => {
compileWithTemplate(TEMPLATE).then((pv) => {
createView(pv);
cd.detectChanges();
@ -170,11 +181,11 @@ export function main() {
component.items = [1, 2, 3];
cd.detectChanges();
expect(DOM.getText(view.nodes[0])).toEqual('1;2;3;');
done();
});
async.done();
});
}));
it('should throw on ref changing to string', (done) => {
it('should throw on ref changing to string', inject([AsyncTestCompleter], (async) => {
compileWithTemplate(TEMPLATE).then((pv) => {
createView(pv);
cd.detectChanges();
@ -182,22 +193,22 @@ export function main() {
component.items = 'whaaa';
expect(() => cd.detectChanges()).toThrowError();
done();
});
async.done();
});
}));
it('should works with duplicates', (done) => {
it('should works with duplicates', inject([AsyncTestCompleter], (async) => {
compileWithTemplate(TEMPLATE).then((pv) => {
createView(pv);
var a = new Foo();
component.items = [a, a];
cd.detectChanges();
expect(DOM.getText(view.nodes[0])).toEqual('foo;foo;');
done();
});
async.done();
});
}));
it('should repeat over nested arrays', (done) => {
it('should repeat over nested arrays', inject([AsyncTestCompleter], (async) => {
compileWithTemplate(
'<div><div template="foreach #item in items">' +
'<div template="foreach #subitem in item">' +
@ -210,12 +221,12 @@ export function main() {
cd.detectChanges();
cd.detectChanges();
expect(DOM.getText(view.nodes[0])).toEqual('a;b;|c;d;|');
done();
});
async.done();
});
}));
it('should display indices correctly', (done) => {
it('should display indices correctly', inject([AsyncTestCompleter], (async) => {
var INDEX_TEMPLATE =
'<div><copy-me template="foreach: var item in items; var i=index">{{i.toString()}}</copy-me></div>';
compileWithTemplate(INDEX_TEMPLATE).then((pv) => {
@ -227,9 +238,9 @@ export function main() {
component.items = [1, 2, 6, 7, 4, 3, 5, 8, 9, 0];
cd.detectChanges();
expect(DOM.getText(view.nodes[0])).toEqual('0123456789');
done();
});
async.done();
});
}));
});
}

View File

@ -1,4 +1,16 @@
import {describe, xit, it, expect, beforeEach, ddescribe, iit, el, IS_DARTIUM} from 'angular2/test_lib';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
IS_DARTIUM,
it,
xit,
} from 'angular2/test_lib';
import {DOM} from 'angular2/src/dom/dom_adapter';
@ -58,29 +70,29 @@ export function main() {
return compiler.compile(TestComponent);
}
it('should work in a template attribute', (done) => {
it('should work in a template attribute', inject([AsyncTestCompleter], (async) => {
compileWithTemplate('<div><copy-me template="if booleanCondition">hello</copy-me></div>').then((pv) => {
createView(pv);
cd.detectChanges();
expect(view.nodes[0].querySelectorAll('copy-me').length).toEqual(1);
expect(DOM.getText(view.nodes[0])).toEqual('hello');
done();
});
async.done();
});
}));
it('should work in a template element', (done) => {
it('should work in a template element', inject([AsyncTestCompleter], (async) => {
compileWithTemplate('<div><template [if]="booleanCondition"><copy-me>hello2</copy-me></template></div>').then((pv) => {
createView(pv);
cd.detectChanges();
expect(view.nodes[0].querySelectorAll('copy-me').length).toEqual(1);
expect(DOM.getText(view.nodes[0])).toEqual('hello2');
done();
});
async.done();
});
}));
it('should toggle node when condition changes', (done) => {
it('should toggle node when condition changes', inject([AsyncTestCompleter], (async) => {
compileWithTemplate('<div><copy-me template="if booleanCondition">hello</copy-me></div>').then((pv) => {
createView(pv);
@ -100,11 +112,11 @@ export function main() {
expect(view.nodes[0].querySelectorAll('copy-me').length).toEqual(0);
expect(DOM.getText(view.nodes[0])).toEqual('');
done();
});
async.done();
});
}));
it('should update several nodes with if', (done) => {
it('should update several nodes with if', inject([AsyncTestCompleter], (async) => {
var templateString =
'<div>' +
'<copy-me template="if numberCondition + 1 >= 2">helloNumber</copy-me>' +
@ -128,46 +140,46 @@ export function main() {
cd.detectChanges();
expect(view.nodes[0].querySelectorAll('copy-me').length).toEqual(1);
expect(DOM.getText(view.nodes[0])).toEqual('helloNumber');
done();
});
async.done();
});
}));
if (!IS_DARTIUM) {
it('should leave the element if the condition is a non-empty string (JS)', (done) => {
it('should leave the element if the condition is a non-empty string (JS)', inject([AsyncTestCompleter], (async) => {
compileWithTemplate('<div><copy-me template="if stringCondition">hello</copy-me></div>').then((pv) => {
createView(pv);
cd.detectChanges();
expect(view.nodes[0].querySelectorAll('copy-me').length).toEqual(1);
expect(DOM.getText(view.nodes[0])).toEqual('hello');
done();
});
async.done();
});
}));
it('should leave the element if the condition is an object (JS)', (done) => {
it('should leave the element if the condition is an object (JS)', inject([AsyncTestCompleter], (async) => {
compileWithTemplate('<div><copy-me template="if objectCondition">hello</copy-me></div>').then((pv) => {
createView(pv);
cd.detectChanges();
expect(view.nodes[0].querySelectorAll('copy-me').length).toEqual(1);
expect(DOM.getText(view.nodes[0])).toEqual('hello');
done();
});
async.done();
});
}));
it('should remove the element if the condition is null (JS)', (done) => {
it('should remove the element if the condition is null (JS)', inject([AsyncTestCompleter], (async) => {
compileWithTemplate('<div><copy-me template="if nullCondition">hello</copy-me></div>').then((pv) => {
createView(pv);
cd.detectChanges();
expect(view.nodes[0].querySelectorAll('copy-me').length).toEqual(0);
expect(DOM.getText(view.nodes[0])).toEqual('');
done();
});
async.done();
});
}));
it('should not add the element twice if the condition goes from true to true (JS)', (done) => {
it('should not add the element twice if the condition goes from true to true (JS)', inject([AsyncTestCompleter], (async) => {
compileWithTemplate('<div><copy-me template="if numberCondition">hello</copy-me></div>').then((pv) => {
createView(pv);
@ -180,11 +192,11 @@ export function main() {
expect(view.nodes[0].querySelectorAll('copy-me').length).toEqual(1);
expect(DOM.getText(view.nodes[0])).toEqual('hello');
done();
});
async.done();
});
}));
it('should not recreate the element if the condition goes from true to true (JS)', (done) => {
it('should not recreate the element if the condition goes from true to true (JS)', inject([AsyncTestCompleter], (async) => {
compileWithTemplate('<div><copy-me template="if numberCondition">hello</copy-me></div>').then((pv) => {
createView(pv);
@ -195,19 +207,19 @@ export function main() {
cd.detectChanges();
expect(DOM.hasClass(view.nodes[0].childNodes[1], "foo")).toBe(true);
done();
});
async.done();
});
}));
} else {
it('should not create the element if the condition is not a boolean (DART)', (done) => {
it('should not create the element if the condition is not a boolean (DART)', inject([AsyncTestCompleter], (async) => {
compileWithTemplate('<div><copy-me template="if numberCondition">hello</copy-me></div>').then((pv) => {
createView(pv);
expect(function(){cd.detectChanges();}).toThrowError();
expect(view.nodes[0].querySelectorAll('copy-me').length).toEqual(0);
expect(DOM.getText(view.nodes[0])).toEqual('');
done();
});
async.done();
});
}));
}
});

View File

@ -1,4 +1,15 @@
import {describe, xit, it, expect, beforeEach, ddescribe, iit, el} from 'angular2/test_lib';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
xit,
} from 'angular2/test_lib';
import {DOM} from 'angular2/src/dom/dom_adapter';
import {Injector} from 'angular2/di';
import {Lexer, Parser, ChangeDetector, dynamicChangeDetection} from 'angular2/change_detection';
@ -56,37 +67,37 @@ export function main() {
return compiler.compile(TestComponent);
}
it('should not interpolate children', (done) => {
it('should not interpolate children', inject([AsyncTestCompleter], (async) => {
var template = '<div>{{text}}<span non-bindable>{{text}}</span></div>';
compileWithTemplate(template).then((pv) => {
createView(pv);
cd.detectChanges();
expect(DOM.getText(view.nodes[0])).toEqual('foo{{text}}');
done();
});
async.done();
});
}));
it('should ignore directives on child nodes', (done) => {
it('should ignore directives on child nodes', inject([AsyncTestCompleter], (async) => {
var template = '<div non-bindable><span id=child test-dec>{{text}}</span></div>';
compileWithTemplate(template).then((pv) => {
createView(pv);
cd.detectChanges();
var span = DOM.querySelector(view.nodes[0], '#child');
expect(DOM.hasClass(span, 'compiled')).toBeFalsy();
done();
});
async.done();
});
}));
it('should trigger directives on the same node', (done) => {
it('should trigger directives on the same node', inject([AsyncTestCompleter], (async) => {
var template = '<div><span id=child non-bindable test-dec>{{text}}</span></div>';
compileWithTemplate(template).then((pv) => {
createView(pv);
cd.detectChanges();
var span = DOM.querySelector(view.nodes[0], '#child');
expect(DOM.hasClass(span, 'compiled')).toBeTruthy();
done();
});
async.done();
});
}));
})
}

View File

@ -1,4 +1,15 @@
import {describe, xit, it, expect, beforeEach, ddescribe, iit, el} from 'angular2/test_lib';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
xit,
} from 'angular2/test_lib';
import {DOM} from 'angular2/src/dom/dom_adapter';
import {Injector} from 'angular2/di';
import {Lexer, Parser, dynamicChangeDetection} from 'angular2/change_detection';
@ -54,7 +65,7 @@ export function main() {
}
describe('switch value changes', () => {
it('should switch amongst when values', (done) => {
it('should switch amongst when values', inject([AsyncTestCompleter], (async) => {
var template = '<div>' +
'<ul [switch]="switchValue">' +
'<template [switch-when]="\'a\'"><li>when a</li></template>' +
@ -73,11 +84,11 @@ export function main() {
cd.detectChanges();
expect(DOM.getText(view.nodes[0])).toEqual('when b');
done();
});
async.done();
});
}));
it('should switch amongst when values with fallback to default', (done) => {
it('should switch amongst when values with fallback to default', inject([AsyncTestCompleter], (async) => {
var template = '<div>' +
'<ul [switch]="switchValue">' +
'<li template="switch-when \'a\'">when a</li>' +
@ -96,11 +107,11 @@ export function main() {
cd.detectChanges();
expect(DOM.getText(view.nodes[0])).toEqual('when default');
done();
});
async.done();
});
}));
it('should support multiple whens with the same value', (done) => {
it('should support multiple whens with the same value', inject([AsyncTestCompleter], (async) => {
var template = '<div>' +
'<ul [switch]="switchValue">' +
'<template [switch-when]="\'a\'"><li>when a1;</li></template>' +
@ -123,13 +134,13 @@ export function main() {
cd.detectChanges();
expect(DOM.getText(view.nodes[0])).toEqual('when b1;when b2;');
done();
});
async.done();
});
}));
});
describe('when values changes', () => {
it('should switch amongst when values', (done) => {
it('should switch amongst when values', inject([AsyncTestCompleter], (async) => {
var template = '<div>' +
'<ul [switch]="switchValue">' +
'<template [switch-when]="when1"><li>when 1;</li></template>' +
@ -161,9 +172,9 @@ export function main() {
cd.detectChanges();
expect(DOM.getText(view.nodes[0])).toEqual('when default;');
done();
});
async.done();
});
}));
});
});
}

View File

@ -1,5 +1,18 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach,
el, queryView, dispatchEvent} from 'angular2/test_lib';
import {
afterEach,
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
dispatchEvent,
el,
expect,
iit,
inject,
it,
queryView,
xit,
} from 'angular2/test_lib';
import {Lexer, Parser, ChangeDetector, dynamicChangeDetection} from 'angular2/change_detection';
import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
@ -56,7 +69,7 @@ export function main() {
}
describe("integration tests", () => {
it("should initialize DOM elements with the given form object", (done) => {
it("should initialize DOM elements with the given form object", inject([AsyncTestCompleter], (async) => {
var ctx = new MyComp(new ControlGroup({
"login": new Control("loginValue")
}));
@ -68,11 +81,11 @@ export function main() {
compile(MyComp, t, ctx, (view) => {
var input = queryView(view, "input")
expect(input.value).toEqual("loginValue");
done();
});
async.done();
});
}));
it("should update the control group values on DOM change", (done) => {
it("should update the control group values on DOM change", inject([AsyncTestCompleter], (async) => {
var form = new ControlGroup({
"login": new Control("oldValue")
});
@ -89,11 +102,11 @@ export function main() {
dispatchEvent(input, "change");
expect(form.value).toEqual({"login": "updatedValue"});
done();
});
async.done();
});
}));
it("should update DOM elements when rebinding the control group", (done) => {
it("should update DOM elements when rebinding the control group", inject([AsyncTestCompleter], (async) => {
var form = new ControlGroup({
"login": new Control("oldValue")
});
@ -111,11 +124,11 @@ export function main() {
var input = queryView(view, "input")
expect(input.value).toEqual("newValue");
done();
});
async.done();
});
}));
it("should update DOM element when rebinding the control name", (done) => {
it("should update DOM element when rebinding the control name", inject([AsyncTestCompleter], (async) => {
var ctx = new MyComp(new ControlGroup({
"one": new Control("one"),
"two": new Control("two")
@ -133,12 +146,12 @@ export function main() {
detectChanges(view);
expect(input.value).toEqual("two");
done();
});
async.done();
});
}));
describe("different control types", () => {
it("should support type=checkbox", (done) => {
it("should support type=checkbox", inject([AsyncTestCompleter], (async) => {
var ctx = new MyComp(new ControlGroup({"checkbox": new Control(true)}));
var t = `<div [control-group]="form">
@ -153,11 +166,11 @@ export function main() {
dispatchEvent(input, "change");
expect(ctx.form.value).toEqual({"checkbox" : false});
done();
});
async.done();
});
}));
it("should support custom value accessors", (done) => {
it("should support custom value accessors", inject([AsyncTestCompleter], (async) => {
var ctx = new MyComp(new ControlGroup({"name": new Control("aa")}));
var t = `<div [control-group]="form">
@ -172,13 +185,13 @@ export function main() {
dispatchEvent(input, "change");
expect(ctx.form.value).toEqual({"name" : "bb"});
done();
});
async.done();
});
}));
});
describe("validations", () => {
it("should use validators defined in html",(done) => {
it("should use validators defined in html", inject([AsyncTestCompleter], (async) => {
var form = new ControlGroup({"login": new Control("aa")});
var ctx = new MyComp(form);
@ -195,11 +208,11 @@ export function main() {
dispatchEvent(input, "change");
expect(form.valid).toEqual(false);
done();
});
async.done();
});
}));
it("should use validators defined in the model",(done) => {
it("should use validators defined in the model", inject([AsyncTestCompleter], (async) => {
var form = new ControlGroup({"login": new Control("aa", validators.required)});
var ctx = new MyComp(form);
@ -216,13 +229,13 @@ export function main() {
dispatchEvent(input, "change");
expect(form.valid).toEqual(false);
done();
});
async.done();
});
}));
});
describe("nested forms", () => {
it("should init DOM with the given form object", (done) => {
it("should init DOM with the given form object",inject([AsyncTestCompleter], (async) => {
var form = new ControlGroup({
"nested": new ControlGroup({
"login": new Control("value")
@ -239,11 +252,11 @@ export function main() {
compile(MyComp, t, ctx, (view) => {
var input = queryView(view, "input")
expect(input.value).toEqual("value");
done();
});
async.done();
});
}));
it("should update the control group values on DOM change", (done) => {
it("should update the control group values on DOM change", inject([AsyncTestCompleter], (async) => {
var form = new ControlGroup({
"nested": new ControlGroup({
"login": new Control("value")
@ -264,9 +277,9 @@ export function main() {
dispatchEvent(input, "change");
expect(form.value).toEqual({"nested" : {"login" : "updatedValue"}});
done();
});
async.done();
});
}));
});
});
}

View File

@ -1,4 +1,15 @@
import {describe, beforeEach, it, expect, ddescribe, iit, el, IS_DARTIUM} from 'angular2/test_lib';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
IS_DARTIUM,
it,
} from 'angular2/test_lib';
import {XHRMock} from 'angular2/src/mock/xhr_mock';
import {PromiseWrapper, Promise} from 'angular2/src/facade/async';
import {isPresent} from 'angular2/src/facade/lang';
@ -33,37 +44,37 @@ export function main() {
PromiseWrapper.then(request, onResponse, onError);
}
it('should return a response from the definitions', (done) => {
it('should return a response from the definitions', inject([AsyncTestCompleter], (async) => {
var url = '/foo';
var response = 'bar';
xhr.when(url, response);
expectResponse(xhr.get(url), url, response, done);
expectResponse(xhr.get(url), url, response, () => async.done());
xhr.flush();
});
}));
it('should return an error from the definitions', (done) => {
it('should return an error from the definitions', inject([AsyncTestCompleter], (async) => {
var url = '/foo';
var response = null;
xhr.when(url, response);
expectResponse(xhr.get(url), url, response, done);
expectResponse(xhr.get(url), url, response, () => async.done());
xhr.flush();
});
}));
it('should return a response from the expectations', (done) => {
it('should return a response from the expectations', inject([AsyncTestCompleter], (async) => {
var url = '/foo';
var response = 'bar';
xhr.expect(url, response);
expectResponse(xhr.get(url), url, response, done);
expectResponse(xhr.get(url), url, response, () => async.done());
xhr.flush();
});
}));
it('should return an error from the expectations', (done) => {
it('should return an error from the expectations', inject([AsyncTestCompleter], (async) => {
var url = '/foo';
var response = null;
xhr.expect(url, response);
expectResponse(xhr.get(url), url, response, done);
expectResponse(xhr.get(url), url, response, () => async.done());
xhr.flush();
});
}));
it('should not reuse expectations', () => {
var url = '/foo';
@ -76,14 +87,14 @@ export function main() {
}).toThrowError('Unexpected request /foo');
});
it('should return expectations before definitions', (done) => {
it('should return expectations before definitions', inject([AsyncTestCompleter], (async) => {
var url = '/foo';
xhr.when(url, 'when');
xhr.expect(url, 'expect');
expectResponse(xhr.get(url), url, 'expect');
expectResponse(xhr.get(url), url, 'when', done);
expectResponse(xhr.get(url), url, 'when', () => async.done());
xhr.flush();
});
}));
it('should throw when there is no definitions or expectations', () => {
xhr.get('/foo');

View File

@ -1,4 +1,15 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
import {
afterEach,
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xit,
} from 'angular2/test_lib';
import { List, ListWrapper, StringMap } from 'angular2/src/facade/collection';
import { PromiseWrapper, Promise } from 'angular2/src/facade/async';
@ -15,28 +26,28 @@ export function main() {
describe('multi metric', () => {
it('should merge descriptions', (done) => {
it('should merge descriptions', inject([AsyncTestCompleter], (async) => {
createMetric(['m1', 'm2']).then( (m) => {
expect(m.describe()).toEqual({
'm1': 'describe', 'm2': 'describe'
});
done();
});
async.done();
});
}));
it('should merge all beginMeasure calls', (done) => {
it('should merge all beginMeasure calls', inject([AsyncTestCompleter], (async) => {
createMetric(['m1', 'm2'])
.then( (m) => m.beginMeasure() )
.then( (values) => {
expect(values).toEqual([
'm1_beginMeasure', 'm2_beginMeasure'
]);
done();
});
async.done();
});
}));
[false, true].forEach( (restartFlag) => {
it(`should merge all endMeasure calls for restart=${restartFlag}`, (done) => {
it(`should merge all endMeasure calls for restart=${restartFlag}`, inject([AsyncTestCompleter], (async) => {
createMetric(['m1', 'm2'])
.then( (m) => m.endMeasure(restartFlag) )
.then( (values) => {
@ -44,9 +55,9 @@ export function main() {
'm1': { 'restart': restartFlag },
'm2': { 'restart': restartFlag }
});
done();
});
async.done();
});
}));
});
});

View File

@ -1,4 +1,15 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
import {
afterEach,
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xit,
} from 'angular2/test_lib';
import { List, ListWrapper } from 'angular2/src/facade/collection';
import { PromiseWrapper, Promise } from 'angular2/src/facade/async';
@ -34,20 +45,20 @@ export function main() {
describe('beginMeasure', () => {
it('should mark the timeline', (done) => {
it('should mark the timeline', inject([AsyncTestCompleter], (async) => {
var metric = createMetric([[]]);
metric.beginMeasure().then((_) => {
expect(commandLog).toEqual([['timeBegin', 'benchpress0']]);
done();
});
async.done();
});
}));
});
describe('endMeasure', () => {
it('should mark and aggregate events in between the marks', (done) => {
it('should mark and aggregate events in between the marks', inject([AsyncTestCompleter], (async) => {
var events = [
[
eventFactory.markStart('benchpress0', 0),
@ -67,11 +78,11 @@ export function main() {
]);
expect(data['script']).toBe(2);
done();
});
async.done();
});
}));
it('should restart timing', (done) => {
it('should restart timing', inject([AsyncTestCompleter], (async) => {
var events = [
[
eventFactory.markStart('benchpress0', 0),
@ -94,11 +105,11 @@ export function main() {
'readPerfLog'
]);
done();
});
async.done();
});
}));
it('should loop and aggregate until the end mark is present', (done) => {
it('should loop and aggregate until the end mark is present', inject([AsyncTestCompleter], (async) => {
var events = [
[ eventFactory.markStart('benchpress0', 0), eventFactory.start('script', 1) ],
[ eventFactory.end('script', 2) ],
@ -119,11 +130,11 @@ export function main() {
]);
expect(data['script']).toBe(3);
done();
});
async.done();
});
}));
it('should store events after the end mark for the next call', (done) => {
it('should store events after the end mark for the next call', inject([AsyncTestCompleter], (async) => {
var events = [
[ eventFactory.markStart('benchpress0', 0), eventFactory.markEnd('benchpress0', 1), eventFactory.markStart('benchpress1', 1),
eventFactory.start('script', 1), eventFactory.end('script', 2) ],
@ -146,9 +157,9 @@ export function main() {
]);
expect(data['script']).toBe(3);
done();
});
async.done();
});
}));
});
@ -163,17 +174,17 @@ export function main() {
}
it('should report a single interval', (done) => {
it('should report a single interval', inject([AsyncTestCompleter], (async) => {
aggregate([
eventFactory.start('script', 0),
eventFactory.end('script', 5)
]).then((data) => {
expect(data['script']).toBe(5);
done();
});
async.done();
});
}));
it('should sum up multiple intervals', (done) => {
it('should sum up multiple intervals', inject([AsyncTestCompleter], (async) => {
aggregate([
eventFactory.start('script', 0),
eventFactory.end('script', 5),
@ -181,29 +192,29 @@ export function main() {
eventFactory.end('script', 17)
]).then((data) => {
expect(data['script']).toBe(12);
done();
});
async.done();
});
}));
it('should ignore not started intervals', (done) => {
it('should ignore not started intervals', inject([AsyncTestCompleter], (async) => {
aggregate([
eventFactory.end('script', 10)
]).then((data) => {
expect(data['script']).toBe(0);
done();
});
async.done();
});
}));
it('should ignore not ended intervals', (done) => {
it('should ignore not ended intervals', inject([AsyncTestCompleter], (async) => {
aggregate([
eventFactory.start('script', 10)
]).then((data) => {
expect(data['script']).toBe(0);
done();
});
async.done();
});
}));
it('should ignore events from different processed as the start mark', (done) => {
it('should ignore events from different processed as the start mark', inject([AsyncTestCompleter], (async) => {
var otherProcessEventFactory = new TraceEventFactory('timeline', 'pid1');
var metric = createMetric([[
eventFactory.markStart('benchpress0', 0),
@ -217,23 +228,23 @@ export function main() {
.then( (_) => metric.endMeasure(false) )
.then((data) => {
expect(data['script']).toBe(5);
done();
});
async.done();
});
}));
['script', 'render'].forEach( (metricName) => {
it(`should support ${metricName} metric`, (done) => {
it(`should support ${metricName} metric`, inject([AsyncTestCompleter], (async) => {
aggregate([
eventFactory.start(metricName, 0),
eventFactory.end(metricName, 5)
]).then((data) => {
expect(data[metricName]).toBe(5);
done();
});
async.done();
});
}));
});
it('should support gcTime/gcAmount metric', (done) => {
it('should support gcTime/gcAmount metric', inject([AsyncTestCompleter], (async) => {
aggregate([
eventFactory.start('gc', 0, {'usedHeapSize': 2500}),
eventFactory.end('gc', 5, {'usedHeapSize': 1000})
@ -242,11 +253,11 @@ export function main() {
expect(data['gcAmount']).toBe(1.5);
expect(data['majorGcTime']).toBe(0);
expect(data['majorGcAmount']).toBe(0);
done();
});
async.done();
});
}));
it('should support majorGcTime/majorGcAmount metric', (done) => {
it('should support majorGcTime/majorGcAmount metric', inject([AsyncTestCompleter], (async) => {
aggregate([
eventFactory.start('gc', 0, {'usedHeapSize': 2500}),
eventFactory.end('gc', 5, {'usedHeapSize': 1000, 'majorGc': true})
@ -255,11 +266,11 @@ export function main() {
expect(data['gcAmount']).toBe(1.5);
expect(data['majorGcTime']).toBe(5);
expect(data['majorGcAmount']).toBe(1.5);
done();
});
async.done();
});
}));
it('should subtract gcTime in script from script time', (done) => {
it('should subtract gcTime in script from script time', inject([AsyncTestCompleter], (async) => {
aggregate([
eventFactory.start('script', 0),
eventFactory.start('gc', 1, {'usedHeapSize': 1000}),
@ -267,32 +278,32 @@ export function main() {
eventFactory.end('script', 5)
]).then((data) => {
expect(data['script']).toBe(2);
done();
});
async.done();
});
}));
describe('microIterations', () => {
it('should not report scriptMicroAvg if microIterations = 0', (done) => {
it('should not report scriptMicroAvg if microIterations = 0', inject([AsyncTestCompleter], (async) => {
aggregate([
eventFactory.start('script', 0),
eventFactory.end('script', 5)
], 0).then((data) => {
expect(isPresent(data['scriptMicroAvg'])).toBe(false);
done();
});
async.done();
});
}));
it('should report scriptMicroAvg', (done) => {
it('should report scriptMicroAvg', inject([AsyncTestCompleter], (async) => {
aggregate([
eventFactory.start('script', 0),
eventFactory.end('script', 5)
], 4).then((data) => {
expect(data['script']).toBe(5);
expect(data['scriptMicroAvg']).toBe(5/4);
done();
});
async.done();
});
}));
});

View File

@ -1,4 +1,15 @@
import {describe, ddescribe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
import {
afterEach,
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xit,
} from 'angular2/test_lib';
import { DateWrapper, Json, RegExpWrapper, isPresent } from 'angular2/src/facade/lang';
import { PromiseWrapper } from 'angular2/src/facade/async';
@ -32,7 +43,7 @@ export function main() {
return new Injector(bindings).get(JsonFileReporter);
}
it('should write all data into a file', (done) => {
it('should write all data into a file', inject([AsyncTestCompleter], (async) => {
createReporter({
sampleId: 'someId',
descriptions: [{ 'a': 2 }],
@ -85,8 +96,8 @@ export function main() {
}
]
});
done();
});
async.done();
}));
});
}

View File

@ -1,4 +1,15 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
import {
afterEach,
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xit,
} from 'angular2/test_lib';
import { List, ListWrapper, StringMap } from 'angular2/src/facade/collection';
import { PromiseWrapper, Promise } from 'angular2/src/facade/async';
@ -16,7 +27,7 @@ export function main() {
describe('multi reporter', () => {
it('should reportMeasureValues to all', (done) => {
it('should reportMeasureValues to all', inject([AsyncTestCompleter], (async) => {
var mv = new MeasureValues(0, DateWrapper.now(), {});
createReporters(['m1', 'm2'])
.then( (r) => r.reportMeasureValues(mv) )
@ -26,11 +37,11 @@ export function main() {
{'id': 'm1', 'values': mv},
{'id': 'm2', 'values': mv}
]);
done();
});
async.done();
});
}));
it('should reportSample to call', (done) => {
it('should reportSample to call', inject([AsyncTestCompleter], (async) => {
var completeSample = [
new MeasureValues(0, DateWrapper.now(), {}),
new MeasureValues(1, DateWrapper.now(), {})
@ -45,9 +56,9 @@ export function main() {
{'id': 'm1', 'completeSample': completeSample, 'validSample': validSample},
{'id': 'm2', 'completeSample': completeSample, 'validSample': validSample}
]);
done();
async.done();
})
});
}));
});
}

View File

@ -1,4 +1,15 @@
import {describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
import {
afterEach,
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xit,
} from 'angular2/test_lib';
import {
Runner, Sampler, SampleDescription,
Validator, bind, Injector, Metric,
@ -31,16 +42,16 @@ export function main() {
return runner;
}
it('should set SampleDescription.id', (done) => {
it('should set SampleDescription.id', inject([AsyncTestCompleter], (async) => {
createRunner().sample({id: 'someId'})
.then( (_) => injector.asyncGet(SampleDescription) )
.then( (desc) => {
expect(desc.id).toBe('someId');
done();
});
async.done();
});
}));
it('should merge SampleDescription.description', (done) => {
it('should merge SampleDescription.description', inject([AsyncTestCompleter], (async) => {
createRunner([
bind(Options.DEFAULT_DESCRIPTION).toValue({'a': 1})
]).sample({id: 'someId', bindings: [
@ -55,44 +66,44 @@ export function main() {
'b': 2,
'v': 11
});
done();
});
async.done();
});
}));
it('should fill SampleDescription.metrics from the Metric', (done) => {
it('should fill SampleDescription.metrics from the Metric', inject([AsyncTestCompleter], (async) => {
createRunner().sample({id: 'someId'})
.then( (_) => injector.asyncGet(SampleDescription) )
.then( (desc) => {
expect(desc.metrics).toEqual({ 'm1': 'some metric' });
done();
});
async.done();
});
}));
it('should bind Options.EXECUTE', (done) => {
it('should bind Options.EXECUTE', inject([AsyncTestCompleter], (async) => {
var execute = () => {};
createRunner().sample({id: 'someId', execute: execute}).then( (_) => {
expect(injector.get(Options.EXECUTE)).toEqual(execute);
done();
});
async.done();
});
}));
it('should bind Options.PREPARE', (done) => {
it('should bind Options.PREPARE', inject([AsyncTestCompleter], (async) => {
var prepare = () => {};
createRunner().sample({id: 'someId', prepare: prepare}).then( (_) => {
expect(injector.get(Options.PREPARE)).toEqual(prepare);
done();
});
async.done();
});
}));
it('should bind Options.MICRO_ITERATIONS', (done) => {
it('should bind Options.MICRO_ITERATIONS', inject([AsyncTestCompleter], (async) => {
createRunner().sample({id: 'someId', microIterations: 23}).then( (_) => {
expect(injector.get(Options.MICRO_ITERATIONS)).toEqual(23);
done();
});
async.done();
});
}));
it('should overwrite bindings per sample call', (done) => {
it('should overwrite bindings per sample call', inject([AsyncTestCompleter], (async) => {
createRunner([
bind(Options.DEFAULT_DESCRIPTION).toValue({'a': 1}),
]).sample({id: 'someId', bindings: [
@ -101,10 +112,10 @@ export function main() {
.then( (desc) => {
expect(injector.get(SampleDescription).description['a']).toBe(2);
done();
async.done();
});
});
}));
});
}

View File

@ -1,4 +1,15 @@
import {describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
import {
afterEach,
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xit,
} from 'angular2/test_lib';
import { isBlank, isPresent, BaseException, stringify, Date, DateWrapper } from 'angular2/src/facade/lang';
import { ListWrapper, List } from 'angular2/src/facade/collection';
@ -58,7 +69,7 @@ export function main() {
sampler = new Injector(bindings).get(Sampler);
}
it('should call the prepare and execute callbacks using WebDriverAdapter.waitFor', (done) => {
it('should call the prepare and execute callbacks using WebDriverAdapter.waitFor', inject([AsyncTestCompleter], (async) => {
var log = [];
var count = 0;
var driver = new MockDriverAdapter([], (callback) => {
@ -79,12 +90,12 @@ export function main() {
sampler.sample().then( (_) => {
expect(count).toBe(4);
expect(log).toEqual([0,1,2,3]);
done();
async.done();
});
});
}));
it('should call prepare, gc, beginMeasure, execute, gc, endMeasure for every iteration', (done) => {
it('should call prepare, gc, beginMeasure, execute, gc, endMeasure for every iteration', inject([AsyncTestCompleter], (async) => {
var workCount = 0;
var log = [];
createSampler({
@ -115,11 +126,11 @@ export function main() {
['gc'],
['endMeasure', false, {'script': 1}],
]);
done();
});
async.done();
});
}));
it('should call execute, gc, endMeasure for every iteration if there is no prepare callback', (done) => {
it('should call execute, gc, endMeasure for every iteration if there is no prepare callback', inject([AsyncTestCompleter], (async) => {
var log = [];
var workCount = 0;
createSampler({
@ -143,11 +154,11 @@ export function main() {
['gc'],
['endMeasure', true, {'script': 1}],
]);
done();
});
async.done();
});
}));
it('should not gc if the flag is not set', (done) => {
it('should not gc if the flag is not set', inject([AsyncTestCompleter], (async) => {
var log = [];
createSampler({
metric: createCountingMetric(),
@ -158,11 +169,11 @@ export function main() {
});
sampler.sample().then( (_) => {
expect(log).toEqual([]);
done();
});
async.done();
});
}));
it('should only collect metrics for execute and ignore metrics from prepare', (done) => {
it('should only collect metrics for execute and ignore metrics from prepare', inject([AsyncTestCompleter], (async) => {
var scriptTime = 0;
var iterationCount = 1;
createSampler({
@ -184,11 +195,11 @@ export function main() {
expect(state.completeSample.length).toBe(2);
expect(state.completeSample[0]).toEqual(mv(0, 1000, {'script': 10}));
expect(state.completeSample[1]).toEqual(mv(1, 1001, {'script': 20}));
done();
});
async.done();
});
}));
it('should call the validator for every execution and store the valid sample', (done) => {
it('should call the validator for every execution and store the valid sample', inject([AsyncTestCompleter], (async) => {
var log = [];
var validSample = [{}];
@ -213,11 +224,11 @@ export function main() {
['validate', [mv(0, 1000, {'script': 0}), mv(1, 1001, {'script': 1})], validSample]
);
done();
});
async.done();
});
}));
it('should report the metric values', (done) => {
it('should report the metric values', inject([AsyncTestCompleter], (async) => {
var log = [];
var validSample = [{}];
createSampler({
@ -244,9 +255,9 @@ export function main() {
['reportSample', [mv(0, 1000, {'script': 0}), mv(1, 1001, {'script': 1})], validSample]
);
done();
});
async.done();
});
}));
});
}

View File

@ -1,4 +1,15 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
import {
afterEach,
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xit,
} from 'angular2/test_lib';
import { StringMap, ListWrapper } from 'angular2/src/facade/collection';
import { isPresent, StringWrapper } from 'angular2/src/facade/lang';
@ -17,22 +28,22 @@ export function main() {
describe('WebDriverExtension.bindTo', () => {
it('should bind the extension that matches the capabilities', (done) => {
it('should bind the extension that matches the capabilities', inject([AsyncTestCompleter], (async) => {
createExtension(['m1', 'm2', 'm3'], {'browser': 'm2'}).then( (m) => {
expect(m.id).toEqual('m2');
done();
});
async.done();
});
}));
it('should throw if there is no match', (done) => {
it('should throw if there is no match', inject([AsyncTestCompleter], (async) => {
PromiseWrapper.catchError(
createExtension(['m1'], {'browser': 'm2'}),
(err) => {
expect(isPresent(err)).toBe(true);
done();
async.done();
}
);
});
}));
});
}

View File

@ -1,4 +1,15 @@
import {describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
import {
afterEach,
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xit,
} from 'angular2/test_lib';
import { ListWrapper } from 'angular2/src/facade/collection';
import { PromiseWrapper } from 'angular2/src/facade/async';
@ -34,111 +45,111 @@ export function main() {
return extension;
}
it('should force gc via window.gc()', (done) => {
it('should force gc via window.gc()', inject([AsyncTestCompleter], (async) => {
createExtension().gc().then( (_) => {
expect(log).toEqual([['executeScript', 'window.gc()']]);
done();
});
async.done();
});
}));
it('should mark the timeline via console.time()', (done) => {
it('should mark the timeline via console.time()', inject([AsyncTestCompleter], (async) => {
createExtension().timeBegin('someName').then( (_) => {
expect(log).toEqual([['executeScript', `console.time('someName');`]]);
done();
});
async.done();
});
}));
it('should mark the timeline via console.timeEnd()', (done) => {
it('should mark the timeline via console.timeEnd()', inject([AsyncTestCompleter], (async) => {
createExtension().timeEnd('someName').then( (_) => {
expect(log).toEqual([['executeScript', `console.timeEnd('someName');`]]);
done();
});
async.done();
});
}));
it('should mark the timeline via console.time() and console.timeEnd()', (done) => {
it('should mark the timeline via console.time() and console.timeEnd()', inject([AsyncTestCompleter], (async) => {
createExtension().timeEnd('name1', 'name2').then( (_) => {
expect(log).toEqual([['executeScript', `console.timeEnd('name1');console.time('name2');`]]);
done();
});
async.done();
});
}));
describe('readPerfLog', () => {
it('should execute a dummy script before reading them', (done) => {
it('should execute a dummy script before reading them', inject([AsyncTestCompleter], (async) => {
// TODO(tbosch): This seems to be a bug in ChromeDriver:
// Sometimes it does not report the newest events of the performance log
// to the WebDriver client unless a script is executed...
createExtension([]).readPerfLog().then( (_) => {
expect(log).toEqual([ [ 'executeScript', '1+1' ], [ 'logs', 'performance' ] ]);
done();
});
async.done();
});
}));
it('should normalize times to ms and forward ph and pid event properties', (done) => {
it('should normalize times to ms and forward ph and pid event properties', inject([AsyncTestCompleter], (async) => {
createExtension([
chromeTimelineEvents.complete('FunctionCall', 1100, 5500, null)
]).readPerfLog().then( (events) => {
expect(events).toEqual([
normEvents.complete('script', 1.1, 5.5, null),
]);
done();
});
async.done();
});
}));
it('should normalize "tdur" to "dur"', (done) => {
it('should normalize "tdur" to "dur"', inject([AsyncTestCompleter], (async) => {
var event = chromeTimelineEvents.create('X', 'FunctionCall', 1100, null);
event['tdur'] = 5500;
createExtension([event]).readPerfLog().then( (events) => {
expect(events).toEqual([
normEvents.complete('script', 1.1, 5.5, null),
]);
done();
});
async.done();
});
}));
it('should report FunctionCall events as "script"', (done) => {
it('should report FunctionCall events as "script"', inject([AsyncTestCompleter], (async) => {
createExtension([
chromeTimelineEvents.start('FunctionCall', 0)
]).readPerfLog().then( (events) => {
expect(events).toEqual([
normEvents.start('script', 0),
]);
done();
});
async.done();
});
}));
it('should ignore FunctionCalls from webdriver', (done) => {
it('should ignore FunctionCalls from webdriver', inject([AsyncTestCompleter], (async) => {
createExtension([
chromeTimelineEvents.start('FunctionCall', 0, {'data': {'scriptName': 'InjectedScript'}})
]).readPerfLog().then( (events) => {
expect(events).toEqual([]);
done();
});
async.done();
});
}));
it('should report begin timestamps', (done) => {
it('should report begin timestamps', inject([AsyncTestCompleter], (async) => {
createExtension([
blinkEvents.create('S', 'someName', 1000)
]).readPerfLog().then( (events) => {
expect(events).toEqual([
normEvents.markStart('someName', 1.0)
]);
done();
});
async.done();
});
}));
it('should report end timestamps', (done) => {
it('should report end timestamps', inject([AsyncTestCompleter], (async) => {
createExtension([
blinkEvents.create('F', 'someName', 1000)
]).readPerfLog().then( (events) => {
expect(events).toEqual([
normEvents.markEnd('someName', 1.0)
]);
done();
});
async.done();
});
}));
it('should report gc', (done) => {
it('should report gc', inject([AsyncTestCompleter], (async) => {
createExtension([
chromeTimelineEvents.start('GCEvent', 1000, {'usedHeapSizeBefore': 1000}),
chromeTimelineEvents.end('GCEvent', 2000, {'usedHeapSizeAfter': 0}),
@ -147,11 +158,11 @@ export function main() {
normEvents.start('gc', 1.0, {'usedHeapSize': 1000}),
normEvents.end('gc', 2.0, {'usedHeapSize': 0, 'majorGc': false}),
]);
done();
});
async.done();
});
}));
it('should report major gc', (done) => {
it('should report major gc', inject([AsyncTestCompleter], (async) => {
createExtension([
chromeTimelineEvents.start('GCEvent', 1000, {'usedHeapSizeBefore': 1000}),
v8EventsOtherProcess.start('majorGC', 1100, null),
@ -162,11 +173,11 @@ export function main() {
normEvents.start('gc', 1.0, {'usedHeapSize': 1000}),
normEvents.end('gc', 2.0, {'usedHeapSize': 0, 'majorGc': false}),
]);
done();
});
async.done();
});
}));
it('should ignore major gc from different processes', (done) => {
it('should ignore major gc from different processes', inject([AsyncTestCompleter], (async) => {
createExtension([
chromeTimelineEvents.start('GCEvent', 1000, {'usedHeapSizeBefore': 1000}),
v8Events.start('majorGC', 1100, null),
@ -177,12 +188,12 @@ export function main() {
normEvents.start('gc', 1.0, {'usedHeapSize': 1000}),
normEvents.end('gc', 2.0, {'usedHeapSize': 0, 'majorGc': true}),
]);
done();
});
async.done();
});
}));
['RecalculateStyles', 'Layout', 'UpdateLayerTree', 'Paint', 'Rasterize', 'CompositeLayers'].forEach( (recordType) => {
it(`should report ${recordType} as "render"`, (done) => {
it(`should report ${recordType} as "render"`, inject([AsyncTestCompleter], (async) => {
createExtension([
chromeTimelineEvents.start(recordType, 1234),
chromeTimelineEvents.end(recordType, 2345)
@ -191,21 +202,21 @@ export function main() {
normEvents.start('render', 1.234),
normEvents.end('render', 2.345),
]);
done();
});
async.done();
});
}));
});
it('should throw an error on buffer overflow', (done) => {
it('should throw an error on buffer overflow', inject([AsyncTestCompleter], (async) => {
PromiseWrapper.catchError(createExtension([
chromeTimelineEvents.start('FunctionCall', 1234),
], 'Tracing.bufferUsage').readPerfLog(), (err) => {
expect( () => {
throw err;
}).toThrowError('The DevTools trace buffer filled during the test!');
done();
});
async.done();
});
}));
it('should match chrome browsers', () => {
expect(createExtension().supports({

View File

@ -1,4 +1,15 @@
import {describe, ddescribe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
import {
afterEach,
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xit,
} from 'angular2/test_lib';
import { ListWrapper } from 'angular2/src/facade/collection';
import { PromiseWrapper } from 'angular2/src/facade/async';
@ -30,47 +41,47 @@ export function main() {
return extension;
}
it('should force gc via window.gc()', (done) => {
it('should force gc via window.gc()', inject([AsyncTestCompleter], (async) => {
createExtension().gc().then( (_) => {
expect(log).toEqual([['executeScript', 'window.gc()']]);
done();
});
async.done();
});
}));
it('should mark the timeline via console.time()', (done) => {
it('should mark the timeline via console.time()', inject([AsyncTestCompleter], (async) => {
createExtension().timeBegin('someName').then( (_) => {
expect(log).toEqual([['executeScript', `console.time('someName');`]]);
done();
});
async.done();
});
}));
it('should mark the timeline via console.timeEnd()', (done) => {
it('should mark the timeline via console.timeEnd()', inject([AsyncTestCompleter], (async) => {
createExtension().timeEnd('someName').then( (_) => {
expect(log).toEqual([['executeScript', `console.timeEnd('someName');`]]);
done();
});
async.done();
});
}));
it('should mark the timeline via console.time() and console.timeEnd()', (done) => {
it('should mark the timeline via console.time() and console.timeEnd()', inject([AsyncTestCompleter], (async) => {
createExtension().timeEnd('name1', 'name2').then( (_) => {
expect(log).toEqual([['executeScript', `console.timeEnd('name1');console.time('name2');`]]);
done();
});
async.done();
});
}));
describe('readPerfLog', () => {
it('should execute a dummy script before reading them', (done) => {
it('should execute a dummy script before reading them', inject([AsyncTestCompleter], (async) => {
// TODO(tbosch): This seems to be a bug in ChromeDriver:
// Sometimes it does not report the newest events of the performance log
// to the WebDriver client unless a script is executed...
createExtension([]).readPerfLog().then( (_) => {
expect(log).toEqual([ [ 'executeScript', '1+1' ], [ 'logs', 'performance' ] ]);
done();
});
async.done();
});
}));
it('should report FunctionCall records as "script"', (done) => {
it('should report FunctionCall records as "script"', inject([AsyncTestCompleter], (async) => {
createExtension([
durationRecord('FunctionCall', 1, 5)
]).readPerfLog().then( (events) => {
@ -78,42 +89,42 @@ export function main() {
normEvents.start('script', 1),
normEvents.end('script', 5)
]);
done();
});
async.done();
});
}));
it('should ignore FunctionCalls from webdriver', (done) => {
it('should ignore FunctionCalls from webdriver', inject([AsyncTestCompleter], (async) => {
createExtension([
internalScriptRecord(1, 5)
]).readPerfLog().then( (events) => {
expect(events).toEqual([]);
done();
});
async.done();
});
}));
it('should report begin time', (done) => {
it('should report begin time', inject([AsyncTestCompleter], (async) => {
createExtension([
timeBeginRecord('someName', 12)
]).readPerfLog().then( (events) => {
expect(events).toEqual([
normEvents.markStart('someName', 12)
]);
done();
});
async.done();
});
}));
it('should report end timestamps', (done) => {
it('should report end timestamps', inject([AsyncTestCompleter], (async) => {
createExtension([
timeEndRecord('someName', 12)
]).readPerfLog().then( (events) => {
expect(events).toEqual([
normEvents.markEnd('someName', 12)
]);
done();
});
async.done();
});
}));
it('should report gc', (done) => {
it('should report gc', inject([AsyncTestCompleter], (async) => {
createExtension([
gcRecord(1, 3, 21)
]).readPerfLog().then( (events) => {
@ -121,12 +132,12 @@ export function main() {
normEvents.start('gc', 1, {'usedHeapSize': 0}),
normEvents.end('gc', 3, {'usedHeapSize': -21}),
]);
done();
});
async.done();
});
}));
['RecalculateStyles', 'Layout', 'UpdateLayerTree', 'Paint', 'Rasterize', 'CompositeLayers'].forEach( (recordType) => {
it(`should report ${recordType}`, (done) => {
it(`should report ${recordType}`, inject([AsyncTestCompleter], (async) => {
createExtension([
durationRecord(recordType, 0, 1)
]).readPerfLog().then( (events) => {
@ -134,13 +145,13 @@ export function main() {
normEvents.start('render', 0),
normEvents.end('render', 1),
]);
done();
});
async.done();
});
}));
});
it('should walk children', (done) => {
it('should walk children', inject([AsyncTestCompleter], (async) => {
createExtension([
durationRecord('FunctionCall', 1, 5, [
timeBeginRecord('someName', 2)
@ -151,9 +162,9 @@ export function main() {
normEvents.markStart('someName', 2),
normEvents.end('script', 5)
]);
done();
});
async.done();
});
}));
it('should match safari browsers', () => {
expect(createExtension().supports({

View File

@ -2,6 +2,8 @@ import 'package:guinness/guinness.dart';
import 'package:unittest/unittest.dart' as unit;
import 'package:angular2/src/dom/browser_adapter.dart';
import 'package:angular2/src/test_lib/test_lib.dart' show testSetup;
main() {
BrowserDomAdapter.makeCurrent();
unit.filterStacks = true;
@ -12,6 +14,8 @@ main() {
guinness.autoInit = false;
guinness.initSpecs();
testSetup();
}
_printWarnings () {