refactor(ts'ify): ts’ify mocks, directives and test_lib

Also cleans up global types.
This commit is contained in:
Tobias Bosch
2015-05-21 15:33:37 -07:00
parent c5996529c3
commit aec51d616b
51 changed files with 610 additions and 671 deletions
@@ -4,16 +4,16 @@ import {NumberWrapper, BaseException, isBlank} from 'angular2/src/facade/lang';
var DOM = new BrowserDomAdapter();
export function getIntParameter(name:string) {
export function getIntParameter(name: string) {
return NumberWrapper.parseInt(getStringParameter(name), 10);
}
export function getStringParameter(name:string) {
var els = DOM.querySelectorAll(document, `input[name="${name}"]`)
export function getStringParameter(name: string) {
var els = DOM.querySelectorAll(document, `input[name="${name}"]`);
var value;
var el;
for (var i=0; i<els.length; i++) {
for (var i = 0; i < els.length; i++) {
el = els[i];
var type = DOM.type(el);
if ((type != 'radio' && type != 'checkbox') || DOM.getChecked(el)) {
@@ -29,11 +29,9 @@ export function getStringParameter(name:string) {
return value;
}
export function bindAction(selector:string, callback:Function) {
export function bindAction(selector: string, callback: Function) {
var el = DOM.querySelector(document, selector);
DOM.on(el, 'click', function(_) {
callback();
});
DOM.on(el, 'click', function(_) { callback(); });
}
export function microBenchmark(name, iterationCount, callback) {
@@ -0,0 +1,2 @@
library angular2.e2e_util;
// empty as this file is node.js specific and should not be transpiled to dart
@@ -1,17 +1,16 @@
var webdriver = require('selenium-webdriver');
/// <reference path="../../typings/node/node.d.ts" />
/// <reference path="../../typings/angular-protractor/angular-protractor.d.ts" />
module.exports = {
verifyNoBrowserErrors: verifyNoBrowserErrors,
clickAll: clickAll
};
import webdriver = require('selenium-webdriver');
function clickAll(buttonSelectors) {
buttonSelectors.forEach(function(selector) {
$(selector).click();
});
export var browser: protractor.IBrowser = global['browser'];
export var $: cssSelectorHelper = global['$'];
export function clickAll(buttonSelectors) {
buttonSelectors.forEach(function(selector) { $(selector).click(); });
}
function verifyNoBrowserErrors() {
export function verifyNoBrowserErrors() {
// TODO(tbosch): Bug in ChromeDriver: Need to execute at least one command
// so that the browser logs can be read out!
browser.executeScript('1+1');
@@ -25,4 +24,3 @@ function verifyNoBrowserErrors() {
expect(filteredLog.length).toEqual(0);
});
}
@@ -1,12 +1,19 @@
/// <reference path="../../typings/jasmine/jasmine"/>
import {BaseException, global} from 'angular2/src/facade/lang';
import {ListWrapper} from 'angular2/src/facade/collection';
import {NgZoneZone} from 'angular2/src/core/zone/ng_zone';
var _scheduler;
var _microtasks:List<Function> = [];
var _microtasks: List<Function> = [];
var _pendingPeriodicTimers: List<number> = [];
var _pendingTimers: List<number> = [];
var _error = null;
interface FakeAsyncZone extends NgZoneZone {
_inFakeAsyncZone: boolean;
}
/**
* Wraps a function to be executed in the fakeAsync zone:
* - microtasks are manually executed by calling `flushMicrotasks()`,
@@ -19,11 +26,11 @@ var _error = null;
*/
export function fakeAsync(fn: Function): Function {
// TODO(vicb) re-enable once the jasmine patch from zone.js is applied
//if (global.zone._inFakeAsyncZone) {
// if (global.zone._inFakeAsyncZone) {
// throw new Error('fakeAsync() calls can not be nested');
//}
var fakeAsyncZone = global.zone.fork({
var fakeAsyncZone = <FakeAsyncZone>global.zone.fork({
setTimeout: _setTimeout,
clearTimeout: _clearTimeout,
setInterval: _setInterval,
@@ -32,18 +39,18 @@ export function fakeAsync(fn: Function): Function {
_inFakeAsyncZone: true
});
return function(...args) {
_scheduler = global.jasmine.DelayedFunctionScheduler();
return function(... args) {
// TODO(tbosch): This class should already be part of the jasmine typings but it is not...
_scheduler = new (<any>jasmine).DelayedFunctionScheduler();
ListWrapper.clear(_microtasks);
ListWrapper.clear(_pendingPeriodicTimers);
ListWrapper.clear(_pendingTimers);
var res = fakeAsyncZone.run(() => {
var res = fn(...args);
});
var res = fakeAsyncZone.run(() => { var res = fn(... args); });
if (_pendingPeriodicTimers.length > 0) {
throw new BaseException(`${_pendingPeriodicTimers.length} periodic timer(s) still in the queue.`);
throw new BaseException(
`${_pendingPeriodicTimers.length} periodic timer(s) still in the queue.`);
}
if (_pendingTimers.length > 0) {
@@ -60,7 +67,8 @@ export function fakeAsync(fn: Function): Function {
/**
* Simulates the asynchronous passage of time for the timers in the fakeAsync zone.
*
* The microtasks queue is drained at the very start of this function and after any timer callback has been executed.
* The microtasks queue is drained at the very start of this function and after any timer callback
* has been executed.
*
* @param {number} millis Number of millisecond, defaults to 0
*/
@@ -81,7 +89,7 @@ export function flushMicrotasks(): void {
}
}
function _setTimeout(fn: Function, delay: number, ...args): number {
function _setTimeout(fn: Function, delay: number, ... args): number {
var cb = _fnAndFlush(fn);
var id = _scheduler.scheduleFunction(cb, delay, args);
ListWrapper.push(_pendingTimers, id);
@@ -94,7 +102,7 @@ function _clearTimeout(id: number) {
return _scheduler.removeFunctionWithId(id);
}
function _setInterval(fn: Function, interval: number, ...args) {
function _setInterval(fn: Function, interval: number, ... args) {
var cb = _fnAndFlush(fn);
var id = _scheduler.scheduleFunction(cb, interval, args, true);
_pendingPeriodicTimers.push(id);
@@ -106,11 +114,10 @@ function _clearInterval(id: number) {
return _scheduler.removeFunctionWithId(id);
}
function _fnAndFlush(fn: Function): void {
return () => {
fn.apply(global, arguments);
flushMicrotasks();
}
function _fnAndFlush(fn: Function): Function {
return (... args) => { fn.apply(global, args);
flushMicrotasks();
}
}
function _scheduleMicrotask(microtask: Function): void {
@@ -118,14 +125,11 @@ function _scheduleMicrotask(microtask: Function): void {
}
function _dequeueTimer(id: number): Function {
return function() {
ListWrapper.remove(_pendingTimers, id);
}
return function() { ListWrapper.remove(_pendingTimers, id); }
}
function _assertInFakeAsyncZone(): void {
if (!global.zone._inFakeAsyncZone) {
if (!(<FakeAsyncZone>global.zone)._inFakeAsyncZone) {
throw new Error('The code should be running in the fakeAsync zone to call this function');
}
}
@@ -2,7 +2,7 @@ export function getTypeOf(instance) {
return instance.constructor;
}
export function instantiateType(type: Function, params: Array = []) {
export function instantiateType(type: Function, params: Array<any> = []) {
var instance = Object.create(type.prototype);
instance.constructor.apply(instance, params);
return instance;
+3 -2
View File
@@ -1,4 +1,5 @@
var testUtil = require('./e2e_util');
var benchpress = require('benchpress/benchpress');
module.exports = {
@@ -47,7 +48,7 @@ function runBenchmark(config) {
}
function getScaleFactor(possibleScalings) {
return browser.executeScript('return navigator.userAgent').then(function(userAgent) {
return browser.executeScript('return navigator.userAgent').then(function(userAgent:string) {
var scaleFactor = 1;
possibleScalings.forEach(function(entry) {
if (userAgent.match(entry.userAgent)) {
@@ -60,7 +61,7 @@ function getScaleFactor(possibleScalings) {
function applyScaleFactor(value, scaleFactor, method) {
if (method === 'log2') {
return value + Math.log2(scaleFactor);
return value + Math.log(scaleFactor) / Math.LN2;
} else if (method === 'sqrt') {
return value * Math.sqrt(scaleFactor);
} else if (method === 'linear') {
@@ -0,0 +1,2 @@
library angular2.perf_util;
// empty as this file is node.js specific and should not be transpiled to dart
@@ -1,4 +1,4 @@
import {Injector, bind} from 'angular2/di';
import {Injector, bind, Injectable} from 'angular2/di';
import {Type, isPresent, BaseException} from 'angular2/src/facade/lang';
import {Promise} from 'angular2/src/facade/async';
@@ -10,7 +10,10 @@ import {View} from 'angular2/src/core/annotations_impl/view';
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
import {AppView} from 'angular2/src/core/compiler/view';
import {internalView} from 'angular2/src/core/compiler/view_ref';
import {DynamicComponentLoader, ComponentRef} from 'angular2/src/core/compiler/dynamic_component_loader';
import {
DynamicComponentLoader,
ComponentRef
} from 'angular2/src/core/compiler/dynamic_component_loader';
import {queryView, viewRootNodes, el} from './utils';
import {instantiateType, getTypeOf} from './lang_utils';
@@ -21,12 +24,11 @@ import {DOM} from 'angular2/src/dom/dom_adapter';
/**
* @exportedAs angular2/test
*/
@Injectable()
export class TestBed {
_injector: Injector;
constructor(injector: Injector) {
this._injector = injector;
}
constructor(injector: Injector) { this._injector = injector; }
/**
* Overrides the {@link View} of a {@link Component}.
@@ -70,11 +72,13 @@ export class TestBed {
*
* @param {Type} component
* @param {*} context
* @param {string} html Use as the component template when specified (shortcut for setInlineTemplate)
* @param {string} html Use as the component template when specified (shortcut for
* setInlineTemplate)
* @return {Promise<ViewProxy>}
*/
createView(component: Type,
{context = null, html = null}: {context:any, html: string} = {}): Promise<ViewProxy> {
{context = null,
html = null}: {context?: any, html?: string} = {}): Promise<ViewProxy> {
if (isBlank(component) && isBlank(context)) {
throw new BaseException('You must specified at least a component or a context');
}
@@ -94,14 +98,15 @@ export class TestBed {
DOM.appendChild(doc.body, rootEl);
var componentBinding = bind(component).toValue(context);
return this._injector.get(DynamicComponentLoader).loadAsRoot(componentBinding,'#root', this._injector).then((hostComponentRef) => {
return new ViewProxy(hostComponentRef);
});
return this._injector.get(DynamicComponentLoader)
.loadAsRoot(componentBinding, '#root', this._injector)
.then((hostComponentRef) => { return new ViewProxy(hostComponentRef); });
}
}
/**
* Proxy to `AppView` return by `createView` in {@link TestBed} which offers a high level API for tests.
* Proxy to `AppView` return by `createView` in {@link TestBed} which offers a high level API for
* tests.
*/
export class ViewProxy {
_componentRef: ComponentRef;
@@ -112,33 +117,23 @@ export class ViewProxy {
this._view = internalView(componentRef.hostView).componentChildViews[0];
}
get context(): any {
return this._view.context;
}
get context(): any { return this._view.context; }
get rootNodes(): List {
return viewRootNodes(this._view);
}
get rootNodes(): List</*node*/ any> { return viewRootNodes(this._view); }
detectChanges(): void {
this._view.changeDetector.detectChanges();
this._view.changeDetector.checkNoChanges();
}
querySelector(selector) {
return queryView(this._view, selector);
}
querySelector(selector) { return queryView(this._view, selector); }
destroy() {
this._componentRef.dispose();
}
destroy() { this._componentRef.dispose(); }
/**
* @returns `AppView` returns the underlying `AppView`.
*
* Prefer using the other methods which hide implementation details.
*/
get rawView(): AppView {
return this._view;
}
get rawView(): AppView { return this._view; }
}
@@ -1,16 +1,24 @@
import {bind} from 'angular2/di';
import {bind, Binding} 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,
PipeRegistry, defaultPipeRegistry} from 'angular2/change_detection';
import {
Parser,
Lexer,
ChangeDetection,
DynamicChangeDetection,
PipeRegistry,
defaultPipeRegistry
} from 'angular2/change_detection';
import {ExceptionHandler} from 'angular2/src/core/exception_handler';
import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
import {DirectiveResolver} from 'angular2/src/core/compiler/directive_resolver';
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
import {ShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/shadow_dom_strategy';
import {EmulatedUnscopedShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/emulated_unscoped_shadow_dom_strategy';
import {
EmulatedUnscopedShadowDomStrategy
} from 'angular2/src/render/dom/shadow_dom/emulated_unscoped_shadow_dom_strategy';
import {XHR} from 'angular2/src/services/xhr';
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
import {UrlResolver} from 'angular2/src/services/url_resolver';
@@ -31,7 +39,7 @@ import {TestBed} from './test_bed';
import {Injector} from 'angular2/di';
import {List, ListWrapper} from 'angular2/src/facade/collection';
import {FunctionWrapper} from 'angular2/src/facade/lang';
import {FunctionWrapper, Type} from 'angular2/src/facade/lang';
import {AppViewPool, APP_VIEW_POOL_CAPACITY} from 'angular2/src/core/compiler/view_pool';
import {AppViewManager} from 'angular2/src/core/compiler/view_manager';
@@ -50,7 +58,8 @@ import {DefaultDomCompiler} from 'angular2/src/render/dom/compiler/compiler';
*/
function _getRootBindings() {
return [
bind(Reflector).toValue(reflector),
bind(Reflector)
.toValue(reflector),
];
}
@@ -67,15 +76,17 @@ function _getAppBindings() {
// The document is only available in browser environment
try {
appDoc = DOM.defaultDoc();
} catch(e) {
} catch (e) {
appDoc = null;
}
return [
bind(DOCUMENT_TOKEN).toValue(appDoc),
bind(ShadowDomStrategy).toFactory(
(styleUrlResolver, doc) => new EmulatedUnscopedShadowDomStrategy(styleUrlResolver, doc.head),
[StyleUrlResolver, DOCUMENT_TOKEN]),
bind(DOCUMENT_TOKEN)
.toValue(appDoc),
bind(ShadowDomStrategy)
.toFactory((styleUrlResolver, doc) =>
new EmulatedUnscopedShadowDomStrategy(styleUrlResolver, doc.head),
[StyleUrlResolver, DOCUMENT_TOKEN]),
DomRenderer,
DefaultDomCompiler,
bind(Renderer).toAlias(DomRenderer),
@@ -103,16 +114,19 @@ function _getAppBindings() {
StyleInliner,
TestBed,
bind(NgZone).toClass(MockNgZone),
bind(EventManager).toFactory((zone) => {
var plugins = [
new DomEventsPlugin(),
];
return new EventManager(plugins, zone);
}, [NgZone]),
bind(EventManager)
.toFactory((zone) =>
{
var plugins = [
new DomEventsPlugin(),
];
return new EventManager(plugins, zone);
},
[NgZone]),
];
}
export function createTestInjector(bindings: List):Injector {
export function createTestInjector(bindings: List<Type | Binding | List<any>>): Injector {
var rootInjector = Injector.resolveAndCreate(_getRootBindings());
return rootInjector.resolveAndCreateChild(ListWrapper.concat(_getAppBindings(), bindings));
}
@@ -147,22 +161,21 @@ export function createTestInjector(bindings: List):Injector {
* @return {FunctionWithParamTokens}
* @exportedAs angular2/test
*/
export function inject(tokens: List, fn: Function):FunctionWithParamTokens {
export function inject(tokens: List<any>, fn: Function): FunctionWithParamTokens {
return new FunctionWithParamTokens(tokens, fn);
}
export class FunctionWithParamTokens {
_tokens: List;
_tokens: List<any>;
_fn: Function;
constructor(tokens: List, fn: Function) {
constructor(tokens: List<any>, fn: Function) {
this._tokens = tokens;
this._fn = fn;
}
execute(injector: Injector):void {
execute(injector: Injector): void {
var params = ListWrapper.map(this._tokens, (t) => injector.get(t));
FunctionWrapper.apply(this._fn, params);
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -4,32 +4,28 @@ import {isPresent} from 'angular2/src/facade/lang';
import {resolveInternalDomView} from 'angular2/src/render/dom/view/view';
export class Log {
_result:List;
_result: List<any>;
constructor() {
this._result = [];
}
constructor() { this._result = []; }
add(value):void {
ListWrapper.push(this._result, value);
}
add(value): void { ListWrapper.push(this._result, value); }
fn(value) {
return (a1 = null, a2 = null, a3 = null, a4 = null, a5 = null) => {
ListWrapper.push(this._result, value);
}
}
result():string {
return ListWrapper.join(this._result, "; ");
}
}
export function viewRootNodes(view):List {
result(): string {
return ListWrapper.join(this._result, "; ");
}
}
export function viewRootNodes(view): List</*node*/ any> {
return resolveInternalDomView(view.render).rootNodes;
}
export function queryView(view, selector:string) {
export function queryView(view, selector: string) {
var rootNodes = viewRootNodes(view);
for (var i = 0; i < rootNodes.length; ++i) {
var res = DOM.querySelector(rootNodes[i], selector);
@@ -44,6 +40,6 @@ export function dispatchEvent(element, eventType) {
DOM.dispatchEvent(element, DOM.createEvent(eventType));
}
export function el(html:string) {
export function el(html: string) {
return DOM.firstChild(DOM.content(DOM.createTemplate(html)));
}