Skip to content

Commit

Permalink
fix(ngUpgrade): make AoT ngUpgrade work with the testability API and …
Browse files Browse the repository at this point in the history
…resumeBootstrap() (#12910)
  • Loading branch information
sjelin authored and chuckjaz committed Nov 17, 2016
1 parent b5f4336 commit dc1662a
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 4 deletions.
5 changes: 4 additions & 1 deletion modules/@angular/upgrade/src/aot/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ export const $INJECTOR = '$injector';
export const $PARSE = '$parse';
export const $ROOT_SCOPE = '$rootScope';
export const $SCOPE = '$scope';
export const $PROVIDE = '$provide';
export const $DELEGATE = '$delegate';
export const $$TESTABILITY = '$$testability';

export const $COMPILE = '$compile';
export const $TEMPLATE_CACHE = '$templateCache';
export const $HTTP_BACKEND = '$httpBackend';
export const $CONTROLLER = '$controller';
export const $CONTROLLER = '$controller';
51 changes: 49 additions & 2 deletions modules/@angular/upgrade/src/aot/upgrade_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
* found in the LICENSE file at https://angular.io/license
*/

import {Injector, NgModule, NgZone} from '@angular/core';
import {Injector, NgModule, NgZone, Testability} from '@angular/core';

import * as angular from '../angular_js';
import {controllerKey} from '../util';

import {angular1Providers, setTempInjectorRef} from './angular1_providers';
import {$INJECTOR, INJECTOR_KEY, UPGRADE_MODULE_NAME} from './constants';
import {$$TESTABILITY, $DELEGATE, $INJECTOR, $PROVIDE, $ROOT_SCOPE, INJECTOR_KEY, UPGRADE_MODULE_NAME} from './constants';



/**
Expand Down Expand Up @@ -40,6 +41,37 @@ export class UpgradeModule {

.value(INJECTOR_KEY, this.injector)

.config([
$PROVIDE, $INJECTOR,
($provide: angular.IProvideService, $injector: angular.IInjectorService) => {
if ($injector.has($$TESTABILITY)) {
$provide.decorator($$TESTABILITY, [
$DELEGATE,
(testabilityDelegate: angular.ITestabilityService) => {
const originalWhenStable: Function = testabilityDelegate.whenStable;
const injector = this.injector;
// Cannot use arrow function below because we need to grab the context
const newWhenStable = function(callback: Function) {
const whenStableContext: any = this;
originalWhenStable.call(this, function() {
const ng2Testability: Testability = injector.get(Testability);
if (ng2Testability.isStable()) {
callback.apply(this, arguments);
} else {
ng2Testability.whenStable(
newWhenStable.bind(whenStableContext, callback));
}
});
};

testabilityDelegate.whenStable = newWhenStable;
return testabilityDelegate;
}
]);
}
}
])

.run([
$INJECTOR,
($injector: angular.IInjectorService) => {
Expand All @@ -59,7 +91,22 @@ export class UpgradeModule {
}
]);

// Make sure resumeBootstrap() only exists if the current bootstrap is deferred
const windowAngular = (window as any /** TODO #???? */)['angular'];
windowAngular.resumeBootstrap = undefined;

// Bootstrap the angular 1 application inside our zone
this.ngZone.run(() => { angular.bootstrap(element, [upgradeModule.name], config); });

// Patch resumeBootstrap() to run inside the ngZone
if (windowAngular.resumeBootstrap) {
const originalResumeBootstrap: () => void = windowAngular.resumeBootstrap;
const ngZone = this.ngZone;
windowAngular.resumeBootstrap = function() {
let args = arguments;
windowAngular.resumeBootstrap = originalResumeBootstrap;
ngZone.run(() => { windowAngular.resumeBootstrap.apply(this, args); });
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import {NgModule, Testability, destroyPlatform} from '@angular/core';
import {NgZone} from '@angular/core/src/zone/ng_zone';
import {fakeAsync, tick} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
Expand All @@ -28,7 +29,11 @@ export function main() {

it('should handle deferred bootstrap', fakeAsync(() => {
let applicationRunning = false;
const ng1Module = angular.module('ng1', []).run(() => { applicationRunning = true; });
let stayedInTheZone: boolean;
const ng1Module = angular.module('ng1', []).run(() => {
applicationRunning = true;
stayedInTheZone = NgZone.isInAngularZone();
});

const element = html('<div></div>');
window.name = 'NG_DEFER_BOOTSTRAP!' + window.name;
Expand All @@ -40,6 +45,7 @@ export function main() {
expect(applicationRunning).toEqual(false);
tick(100);
expect(applicationRunning).toEqual(true);
expect(stayedInTheZone).toEqual(true);
}));

it('should wait for ng2 testability', fakeAsync(() => {
Expand Down

0 comments on commit dc1662a

Please sign in to comment.