test(upgrade): run tests against multiple AngularJS versions (#22167)

Fixes #19332

PR Close #22167
This commit is contained in:
George Kalpakas 2018-02-15 19:21:18 +02:00 committed by Victor Berchet
parent 28240625e6
commit 8e1e040f72
17 changed files with 142 additions and 67 deletions

View File

@ -21,11 +21,13 @@ module.exports = function(config) {
// Loaded through the System loader, in `test-main.js`.
{pattern: 'dist/all/@angular/**/*.js', included: false, watched: true},
'node_modules/core-js/client/core.js',
// include Angular v1 for upgrade module testing
'node_modules/angular/angular.js',
'node_modules/angular-mocks/angular-mocks.js',
// Serve AngularJS for `ngUpgrade` testing.
{pattern: 'node_modules/angular-1.5/angular.js', included: false, watched: false},
{pattern: 'node_modules/angular-mocks-1.5/angular-mocks.js', included: false, watched: false},
{pattern: 'node_modules/angular/angular.js', included: false, watched: false},
{pattern: 'node_modules/angular-mocks/angular-mocks.js', included: false, watched: false},
'node_modules/core-js/client/core.js',
'node_modules/zone.js/dist/zone.js',
'node_modules/zone.js/dist/long-stack-trace-zone.js',
'node_modules/zone.js/dist/proxy.js',

View File

@ -48,9 +48,10 @@
"@types/shelljs": "^0.7.8",
"@types/source-map": "^0.5.1",
"@types/systemjs": "0.19.32",
"angular": "1.5.0",
"angular-animate": "1.5.0",
"angular-mocks": "1.5.0",
"angular": "npm:angular@1.6",
"angular-1.5": "npm:angular@1.5",
"angular-mocks": "npm:angular-mocks@1.6",
"angular-mocks-1.5": "npm:angular-mocks@1.5",
"base64-js": "1.2.1",
"bower": "1.8.2",
"browserstacktunnel-wrapper": "2.0.1",

View File

@ -128,6 +128,7 @@ export type IAugmentedJQuery = Node[] & {
isolateScope?: () => IScope;
injector?: () => IInjectorService;
remove?: () => void;
removeData?: () => void;
};
export interface IProvider { $get: IInjectable; }
export interface IProvideService {
@ -229,7 +230,7 @@ let angular: {
bootstrap: noNg,
module: noNg,
element: noNg,
version: noNg,
version: undefined,
resumeBootstrap: noNg,
getTestability: noNg
};
@ -265,6 +266,7 @@ export function getAngularLib(): any {
*/
export function setAngularJSGlobal(ng: any): void {
angular = ng;
version = ng && ng.version;
}
/**
@ -289,4 +291,4 @@ export const resumeBootstrap = () => angular.resumeBootstrap();
export const getTestability = (e: Element) => angular.getTestability(e);
export const version = angular.version;
export let version = angular.version;

View File

@ -23,8 +23,12 @@ ts_web_test(
name = "test_web",
bootstrap = [
"//:web_test_bootstrap_scripts",
"//:angularjs",
# "//:angularjs",
],
# Disable since tests need to request different AngularJS versions at
# runtime, which is not yet supported.
# (Related issue: https://github.com/bazelbuild/rules_typescript/issues/131)
tags = ["manual"],
# do not sort
deps = [
"//tools/testing:browser",

View File

@ -10,9 +10,9 @@ import {TestBed, getTestBed, inject} from '@angular/core/testing';
import * as angular from '@angular/upgrade/src/common/angular1';
import {DowngradeComponentAdapter, groupNodesBySelector} from '@angular/upgrade/src/common/downgrade_component_adapter';
import {nodes} from './test_helpers';
import {nodes, withEachNg1Version} from './test_helpers';
{
withEachNg1Version(() => {
describe('DowngradeComponentAdapter', () => {
describe('groupNodesBySelector', () => {
it('should return an array of node collections for each selector', () => {
@ -190,4 +190,4 @@ import {nodes} from './test_helpers';
});
});
}
});

View File

@ -5,6 +5,57 @@
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {setAngularJSGlobal} from '@angular/upgrade/src/common/angular1';
const ng1Versions = [
{
label: '1.5',
files: ['angular-1.5/angular.js', 'angular-mocks-1.5/angular-mocks.js'],
},
{
label: '1.6',
files: ['angular/angular.js', 'angular-mocks/angular-mocks.js'],
},
];
export function createWithEachNg1VersionFn(setNg1: typeof setAngularJSGlobal) {
return (specSuite: () => void) => ng1Versions.forEach(({label, files}) => {
describe(`[AngularJS v${label}]`, () => {
beforeAll(done => {
// Load AngularJS before running tests.
files
.reduce(
(prev, file) => prev.then(() => new Promise<void>((resolve, reject) => {
const script = document.createElement('script');
script.src = `base/node_modules/${file}`;
script.onerror = reject;
script.onload = () => {
document.body.removeChild(script);
resolve();
};
document.body.appendChild(script);
})),
Promise.resolve())
.then(() => setNg1((window as any).angular))
.then(done, done.fail);
});
afterAll(() => {
// In these tests we are loading different versions of AngularJS on the same window.
// AngularJS leaves an "expandoId" property on `document`, which can trick subsequent
// `window.angular` instances into believing an app is already bootstrapped.
(window as any).angular.element(document).removeData();
// Remove AngularJS to leave a clean state for subsequent tests.
setNg1(undefined);
delete (window as any).angular;
});
specSuite();
});
});
}
export function html(html: string): Element {
// Don't return `body` itself, because using it as a `$rootElement` for ng1
@ -33,3 +84,5 @@ export function nodes(html: string) {
div.innerHTML = html.trim();
return Array.prototype.slice.call(div.childNodes);
}
export const withEachNg1Version = createWithEachNg1VersionFn(setAngularJSGlobal);

View File

@ -12,13 +12,13 @@ import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import * as angular from '@angular/upgrade/src/common/angular1';
import {UpgradeAdapter, UpgradeAdapterRef} from '@angular/upgrade/src/dynamic/upgrade_adapter';
import {$digest, html, multiTrim} from './test_helpers';
import {$digest, html, multiTrim, withEachNg1Version} from './test_helpers';
declare global {
export var inject: Function;
}
{
withEachNg1Version(() => {
describe('adapter: ng1 to ng2', () => {
beforeEach(() => destroyPlatform());
afterEach(() => destroyPlatform());
@ -2909,11 +2909,12 @@ declare global {
upgradeAdapterRef = upgradeAdapter.registerForNg1Tests(['ng1']);
});
beforeEach(
inject((_$compile_: angular.ICompileService, _$rootScope_: angular.IRootScopeService) => {
$compile = _$compile_;
$rootScope = _$rootScope_;
}));
beforeEach(() => {
inject((_$compile_: angular.ICompileService, _$rootScope_: angular.IRootScopeService) => {
$compile = _$compile_;
$rootScope = _$rootScope_;
});
});
it('should be able to test ng1 components that use ng2 components', async(() => {
upgradeAdapterRef.ready(() => {
@ -2924,4 +2925,4 @@ declare global {
}));
});
});
}
});

View File

@ -13,9 +13,9 @@ import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {UpgradeComponent, UpgradeModule, downgradeComponent} from '@angular/upgrade/static';
import * as angular from '@angular/upgrade/static/src/common/angular1';
import {bootstrap, html} from '../test_helpers';
import {bootstrap, html, withEachNg1Version} from '../test_helpers';
{
withEachNg1Version(() => {
describe('scope/component change-detection', () => {
beforeEach(() => destroyPlatform());
afterEach(() => destroyPlatform());
@ -156,4 +156,4 @@ import {bootstrap, html} from '../test_helpers';
// });
// }));
});
}
});

View File

@ -13,9 +13,9 @@ import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {UpgradeComponent, UpgradeModule, downgradeComponent} from '@angular/upgrade/static';
import * as angular from '@angular/upgrade/static/src/common/angular1';
import {bootstrap, html, multiTrim} from '../test_helpers';
import {bootstrap, html, multiTrim, withEachNg1Version} from '../test_helpers';
{
withEachNg1Version(() => {
describe('content projection', () => {
beforeEach(() => destroyPlatform());
@ -173,4 +173,4 @@ import {bootstrap, html, multiTrim} from '../test_helpers';
});
}));
});
}
});

View File

@ -13,9 +13,9 @@ import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {UpgradeModule, downgradeComponent} from '@angular/upgrade/static';
import * as angular from '@angular/upgrade/static/src/common/angular1';
import {$apply, bootstrap, html, multiTrim} from '../test_helpers';
import {$apply, bootstrap, html, multiTrim, withEachNg1Version} from '../test_helpers';
{
withEachNg1Version(() => {
describe('downgrade ng2 component', () => {
beforeEach(() => destroyPlatform());
@ -642,4 +642,4 @@ import {$apply, bootstrap, html, multiTrim} from '../test_helpers';
}));
});
}
});

View File

@ -16,10 +16,10 @@ import * as angular from '@angular/upgrade/static/src/common/angular1';
import {$ROOT_SCOPE, INJECTOR_KEY, LAZY_MODULE_REF} from '@angular/upgrade/static/src/common/constants';
import {LazyModuleRef} from '@angular/upgrade/static/src/common/util';
import {html, multiTrim} from '../test_helpers';
import {html, multiTrim, withEachNg1Version} from '../test_helpers';
{
withEachNg1Version(() => {
[true, false].forEach(propagateDigest => {
describe(`lazy-load ng2 module (propagateDigest: ${propagateDigest})`, () => {
@ -611,4 +611,4 @@ import {html, multiTrim} from '../test_helpers';
}));
});
});
}
});

View File

@ -13,9 +13,9 @@ import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {UpgradeComponent, UpgradeModule, downgradeComponent} from '@angular/upgrade/static';
import * as angular from '@angular/upgrade/static/src/common/angular1';
import {bootstrap, html, multiTrim} from '../test_helpers';
import {bootstrap, html, multiTrim, withEachNg1Version} from '../test_helpers';
{
withEachNg1Version(() => {
describe('examples', () => {
beforeEach(() => destroyPlatform());
@ -84,4 +84,4 @@ import {bootstrap, html, multiTrim} from '../test_helpers';
});
}));
});
}
});

View File

@ -14,9 +14,9 @@ import {UpgradeModule, downgradeInjectable, getAngularJSGlobal, setAngularJSGlob
import * as angular from '@angular/upgrade/static/src/common/angular1';
import {$INJECTOR, INJECTOR_KEY} from '@angular/upgrade/static/src/common/constants';
import {bootstrap, html} from '../test_helpers';
import {bootstrap, html, withEachNg1Version} from '../test_helpers';
{
withEachNg1Version(() => {
describe('injection', () => {
beforeEach(() => destroyPlatform());
@ -101,13 +101,13 @@ import {bootstrap, html} from '../test_helpers';
}));
it('should allow resetting angular at runtime', async(() => {
let wrappedBootstrapepedCalled = false;
let wrappedBootstrapCalled = false;
const n: any = getAngularJSGlobal();
setAngularJSGlobal({
bootstrap: (...args: any[]) => {
wrappedBootstrapepedCalled = true;
wrappedBootstrapCalled = true;
n.bootstrap(...args);
},
module: n.module,
@ -125,7 +125,8 @@ import {bootstrap, html} from '../test_helpers';
const ng1Module = angular.module('ng1Module', []);
bootstrap(platformBrowserDynamic(), Ng2Module, html('<div>'), ng1Module)
.then((upgrade) => { expect(wrappedBootstrapepedCalled).toEqual(true); });
.then(upgrade => expect(wrappedBootstrapCalled).toBe(true))
.then(() => setAngularJSGlobal(n)); // Reset the AngularJS global.
}));
});
}
});

View File

@ -14,9 +14,9 @@ import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {UpgradeModule} from '@angular/upgrade/static';
import * as angular from '@angular/upgrade/static/src/common/angular1';
import {bootstrap, html} from '../test_helpers';
import {bootstrap, html, withEachNg1Version} from '../test_helpers';
{
withEachNg1Version(() => {
describe('testability', () => {
beforeEach(() => destroyPlatform());
@ -111,4 +111,4 @@ import {bootstrap, html} from '../test_helpers';
});
}));
});
}
});

View File

@ -14,9 +14,9 @@ import {UpgradeComponent, UpgradeModule, downgradeComponent} from '@angular/upgr
import * as angular from '@angular/upgrade/static/src/common/angular1';
import {$SCOPE} from '@angular/upgrade/static/src/common/constants';
import {$digest, bootstrap, html, multiTrim} from '../test_helpers';
import {$digest, bootstrap, html, multiTrim, withEachNg1Version} from '../test_helpers';
{
withEachNg1Version(() => {
describe('upgrade ng1 component', () => {
beforeEach(() => destroyPlatform());
@ -3199,21 +3199,25 @@ import {$digest, bootstrap, html, multiTrim} from '../test_helpers';
const element = html(`<ng2></ng2>`);
bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(adapter => {
// Initial change
// Get to a stable `$digest` state.
$digest(adapter);
// Initial change.
// (Do not use a specific number due to differences between AngularJS 1.5/1.6.)
expect(controllerDoCheckA.calls.count()).toBeGreaterThan(0);
expect(controllerDoCheckB.calls.count()).toBeGreaterThan(0);
controllerDoCheckA.calls.reset();
controllerDoCheckB.calls.reset();
// Run a `$digest`
$digest(adapter);
expect(controllerDoCheckA.calls.count()).toBe(1);
expect(controllerDoCheckB.calls.count()).toBe(1);
// Run a `$digest`
// (Since it's the first one since the `$doCheck` watcher was added,
// the `watchFn` will be run twice.)
$digest(adapter);
expect(controllerDoCheckA.calls.count()).toBe(3);
expect(controllerDoCheckB.calls.count()).toBe(3);
// Run another `$digest`
$digest(adapter);
expect(controllerDoCheckA.calls.count()).toBe(4);
expect(controllerDoCheckB.calls.count()).toBe(4);
expect(controllerDoCheckA.calls.count()).toBe(2);
expect(controllerDoCheckB.calls.count()).toBe(2);
});
}));
@ -3958,4 +3962,4 @@ import {$digest, bootstrap, html, multiTrim} from '../test_helpers';
});
}));
});
}
});

View File

@ -11,6 +11,7 @@ import {UpgradeModule} from '@angular/upgrade/static';
import * as angular from '@angular/upgrade/static/src/common/angular1';
import {$ROOT_SCOPE} from '@angular/upgrade/static/src/common/constants';
import {createWithEachNg1VersionFn} from '../common/test_helpers';
export * from '../common/test_helpers';
export function bootstrap(
@ -35,6 +36,8 @@ export function bootstrap(
});
}
export const withEachNg1Version = createWithEachNg1VersionFn(angular.setAngularJSGlobal);
export function $apply(adapter: UpgradeModule, exp: angular.Ng1Expression) {
const $rootScope = adapter.$injector.get($ROOT_SCOPE) as angular.IRootScopeService;
$rootScope.$apply(exp);

View File

@ -250,17 +250,21 @@ amdetective@0.0.2:
dependencies:
esprima "~1.2.2"
angular-animate@1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/angular-animate/-/angular-animate-1.5.0.tgz#0e31f31fa7ab2ddf5ea5787e476548644d62fb93"
"angular-1.5@npm:angular@1.5":
version "1.5.11"
resolved "https://registry.yarnpkg.com/angular/-/angular-1.5.11.tgz#8c5ba7386f15965c9acf3429f6881553aada30d6"
angular-mocks@1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/angular-mocks/-/angular-mocks-1.5.0.tgz#81b3e4b21098d7c545c6f0a0a97f897b26879dd9"
"angular-mocks-1.5@npm:angular-mocks@1.5":
version "1.5.11"
resolved "https://registry.yarnpkg.com/angular-mocks/-/angular-mocks-1.5.11.tgz#a0e1dd0ea55fd77ee7a757d75536c5e964c86f81"
angular@1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/angular/-/angular-1.5.0.tgz#d96ee97ab6df6cfd0915accbee484d098adb74ec"
"angular-mocks@npm:angular-mocks@1.6":
version "1.6.9"
resolved "https://registry.yarnpkg.com/angular-mocks/-/angular-mocks-1.6.9.tgz#4fed8c8293a5080e0919a7ff0dcf0f704864b7ba"
"angular@npm:angular@1.6":
version "1.6.9"
resolved "https://registry.yarnpkg.com/angular/-/angular-1.6.9.tgz#bc812932e18909038412d594a5990f4bb66c0619"
ansi-align@^1.1.0:
version "1.1.0"