parent
d272f96e23
commit
430f367c2f
|
@ -97,16 +97,33 @@ export interface IControllerService {
|
|||
|
||||
export interface IInjectorService { get(key: string): any; }
|
||||
|
||||
export interface ITestabilityService {
|
||||
findBindings(element: Element, expression: string, opt_exactMatch?: boolean): Element[];
|
||||
findModels(element: Element, expression: string, opt_exactMatch?: boolean): Element[];
|
||||
getLocation(): string;
|
||||
setLocation(url: string): void;
|
||||
whenStable(callback: Function): void;
|
||||
}
|
||||
|
||||
function noNg() {
|
||||
throw new Error('AngularJS v1.x is not loaded!');
|
||||
}
|
||||
|
||||
var angular: {
|
||||
var angular:
|
||||
{
|
||||
bootstrap: (e: Element, modules: string[], config: IAngularBootstrapConfig) => void,
|
||||
module: (prefix: string, dependencies?: string[]) => IModule,
|
||||
element: (e: Element) => IAugmentedJQuery,
|
||||
version: {major: number}
|
||||
} = <any>{bootstrap: noNg, module: noNg, element: noNg, version: noNg};
|
||||
version: {major: number}, resumeBootstrap?: () => void,
|
||||
getTestability: (e: Element) => ITestabilityService
|
||||
} = <any>{
|
||||
bootstrap: noNg,
|
||||
module: noNg,
|
||||
element: noNg,
|
||||
version: noNg,
|
||||
resumeBootstrap: noNg,
|
||||
getTestability: noNg
|
||||
};
|
||||
|
||||
|
||||
try {
|
||||
|
@ -121,3 +138,5 @@ export var bootstrap = angular.bootstrap;
|
|||
export var module = angular.module;
|
||||
export var element = angular.element;
|
||||
export var version = angular.version;
|
||||
export var resumeBootstrap = angular.resumeBootstrap;
|
||||
export var getTestability = angular.getTestability;
|
||||
|
|
|
@ -12,4 +12,5 @@ export const NG1_HTTP_BACKEND = '$httpBackend';
|
|||
export const NG1_INJECTOR = '$injector';
|
||||
export const NG1_PARSE = '$parse';
|
||||
export const NG1_TEMPLATE_CACHE = '$templateCache';
|
||||
export const NG1_TESTABILITY = '$$testability';
|
||||
export const REQUIRE_INJECTOR = '^' + NG2_INJECTOR;
|
||||
|
|
|
@ -10,8 +10,10 @@ import {
|
|||
HostViewFactoryRef,
|
||||
Provider,
|
||||
Type,
|
||||
Testability,
|
||||
APPLICATION_COMMON_PROVIDERS
|
||||
} from 'angular2/core';
|
||||
import {global} from 'angular2/src/facade/lang';
|
||||
import {ObservableWrapper} from 'angular2/src/facade/async';
|
||||
import {BROWSER_PROVIDERS, BROWSER_APP_PROVIDERS} from 'angular2/platform/browser';
|
||||
|
||||
|
@ -23,6 +25,7 @@ import {
|
|||
NG1_PARSE,
|
||||
NG1_ROOT_SCOPE,
|
||||
NG1_SCOPE,
|
||||
NG1_TESTABILITY,
|
||||
NG2_APP_VIEW_MANAGER,
|
||||
NG2_COMPILER,
|
||||
NG2_INJECTOR,
|
||||
|
@ -309,6 +312,7 @@ export class UpgradeAdapter {
|
|||
var rootScope: angular.IRootScopeService;
|
||||
var hostViewFactoryRefMap: HostViewFactoryRefMap = {};
|
||||
var ng1Module = angular.module(this.idPrefix, modules);
|
||||
var ng1BootstrapPromise: Promise<any> = null;
|
||||
var ng1compilePromise: Promise<any> = null;
|
||||
ng1Module.value(NG2_INJECTOR, injector)
|
||||
.value(NG2_ZONE, ngZone)
|
||||
|
@ -331,23 +335,68 @@ export class UpgradeAdapter {
|
|||
return rootScope = rootScopeDelegate;
|
||||
}
|
||||
]);
|
||||
provide.decorator(NG1_TESTABILITY, [
|
||||
'$delegate',
|
||||
function(testabilityDelegate: angular.ITestabilityService) {
|
||||
var ng2Testability: Testability = injector.get(Testability);
|
||||
|
||||
var origonalWhenStable: Function = testabilityDelegate.whenStable;
|
||||
var newWhenStable = (callback: Function): void => {
|
||||
var whenStableContext: any = this;
|
||||
origonalWhenStable.call(this, function() {
|
||||
if (ng2Testability.isStable()) {
|
||||
callback.apply(this, arguments);
|
||||
} else {
|
||||
ng2Testability.whenStable(newWhenStable.bind(whenStableContext, callback));
|
||||
}
|
||||
])
|
||||
.run([
|
||||
});
|
||||
};
|
||||
|
||||
testabilityDelegate.whenStable = newWhenStable;
|
||||
return testabilityDelegate;
|
||||
}
|
||||
]);
|
||||
}
|
||||
]);
|
||||
|
||||
ng1compilePromise = new Promise((resolve, reject) => {
|
||||
ng1Module.run([
|
||||
'$injector',
|
||||
'$rootScope',
|
||||
(injector: angular.IInjectorService, rootScope: angular.IRootScopeService) => {
|
||||
ng1Injector = injector;
|
||||
ObservableWrapper.subscribe(ngZone.onMicrotaskEmpty,
|
||||
(_) => ngZone.runOutsideAngular(() => rootScope.$apply()));
|
||||
ng1compilePromise =
|
||||
UpgradeNg1ComponentAdapterBuilder.resolve(this.downgradedComponents, injector);
|
||||
UpgradeNg1ComponentAdapterBuilder.resolve(this.downgradedComponents, injector)
|
||||
.then(resolve, reject);
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
// Make sure resumeBootstrap() only exists if the current bootstrap is deferred
|
||||
var windowAngular = (<any>global).angular;
|
||||
windowAngular.resumeBootstrap = undefined;
|
||||
|
||||
angular.element(element).data(controllerKey(NG2_INJECTOR), injector);
|
||||
ngZone.run(() => { angular.bootstrap(element, [this.idPrefix], config); });
|
||||
Promise.all([this.compileNg2Components(compiler, hostViewFactoryRefMap), ng1compilePromise])
|
||||
ng1BootstrapPromise = new Promise((resolve, reject) => {
|
||||
if (windowAngular.resumeBootstrap) {
|
||||
var originalResumeBootstrap: () => void = windowAngular.resumeBootstrap;
|
||||
windowAngular.resumeBootstrap = function() {
|
||||
windowAngular.resumeBootstrap = originalResumeBootstrap;
|
||||
windowAngular.resumeBootstrap.apply(this, arguments);
|
||||
resolve();
|
||||
};
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
|
||||
Promise.all([
|
||||
this.compileNg2Components(compiler, hostViewFactoryRefMap),
|
||||
ng1BootstrapPromise,
|
||||
ng1compilePromise
|
||||
])
|
||||
.then(() => {
|
||||
ngZone.run(() => {
|
||||
if (rootScopePrototype) {
|
||||
|
|
|
@ -12,7 +12,16 @@ import {
|
|||
} from 'angular2/testing_internal';
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
|
||||
import {Component, Class, Inject, EventEmitter, ApplicationRef, provide} from 'angular2/core';
|
||||
import {global} from 'angular2/src/facade/lang';
|
||||
import {
|
||||
Component,
|
||||
Class,
|
||||
Inject,
|
||||
EventEmitter,
|
||||
ApplicationRef,
|
||||
provide,
|
||||
Testability,
|
||||
} from 'angular2/core';
|
||||
import {UpgradeAdapter} from 'angular2/upgrade';
|
||||
import * as angular from 'angular2/src/upgrade/angular_js';
|
||||
|
||||
|
@ -559,6 +568,52 @@ export function main() {
|
|||
}));
|
||||
});
|
||||
|
||||
describe('testability', () => {
|
||||
it('should handle deferred bootstrap', inject([AsyncTestCompleter], (async) => {
|
||||
var adapter: UpgradeAdapter = new UpgradeAdapter();
|
||||
var ng1Module = angular.module('ng1', []);
|
||||
var bootstrapResumed: boolean = false;
|
||||
|
||||
var element = html("<div></div>");
|
||||
window.name = 'NG_DEFER_BOOTSTRAP!' + window.name;
|
||||
|
||||
adapter.bootstrap(element, ['ng1'])
|
||||
.ready((ref) => {
|
||||
expect(bootstrapResumed).toEqual(true);
|
||||
ref.dispose();
|
||||
async.done();
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
bootstrapResumed = true;
|
||||
(<any>global).angular.resumeBootstrap();
|
||||
}, 100);
|
||||
}));
|
||||
|
||||
it('should wait for ng2 testability', inject([AsyncTestCompleter], (async) => {
|
||||
var adapter: UpgradeAdapter = new UpgradeAdapter();
|
||||
var ng1Module = angular.module('ng1', []);
|
||||
var element = html("<div></div>");
|
||||
adapter.bootstrap(element, ['ng1'])
|
||||
.ready((ref) => {
|
||||
var ng2Testability: Testability = ref.ng2Injector.get(Testability);
|
||||
ng2Testability.increasePendingRequestCount();
|
||||
var ng2Stable = false;
|
||||
|
||||
angular.getTestability(element).whenStable(function() {
|
||||
expect(ng2Stable).toEqual(true);
|
||||
ref.dispose();
|
||||
async.done();
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
ng2Stable = true;
|
||||
ng2Testability.decreasePendingRequestCount();
|
||||
}, 100);
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
describe('examples', () => {
|
||||
it('should verify UpgradeAdapter example', inject([AsyncTestCompleter], (async) => {
|
||||
var adapter = new UpgradeAdapter();
|
||||
|
@ -594,7 +649,6 @@ export function main() {
|
|||
});
|
||||
}));
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue