feat(upgrade): provide unit test helpers for wiring up injectors (#16848)
Adds two new helper functions that can be used when unit testing Angular services that depend upon upgraded AngularJS services, or vice versa. The functions return a module (AngularJS or NgModule) that is configured to wire up the Angular and AngularJS injectors without the need to actually bootstrap a full hybrid application. This makes it simpler and faster to unit test services. PR Close #16848
This commit is contained in:
parent
5e53956c2b
commit
3fb78aaacc
|
@ -115,6 +115,7 @@ module.exports =
|
|||
'service-worker/index.ts',
|
||||
'upgrade/index.ts',
|
||||
'upgrade/static/index.ts',
|
||||
'upgrade/static/testing/index.ts',
|
||||
];
|
||||
|
||||
readFilesProcessor.fileReaders.push(packageContentFileReader);
|
||||
|
|
|
@ -24,7 +24,7 @@ const packageMap = {
|
|||
'platform-webworker-dynamic': ['platform-webworker-dynamic/index.ts'],
|
||||
router: ['router/index.ts', 'router/testing/index.ts', 'router/upgrade/index.ts'],
|
||||
'service-worker': ['service-worker/index.ts'],
|
||||
upgrade: ['upgrade/index.ts', 'upgrade/static/index.ts']
|
||||
upgrade: ['upgrade/index.ts', 'upgrade/static/index.ts', 'upgrade/static/testing/index.ts']
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ import * as routerUpgrade from '@angular/router/upgrade';
|
|||
import * as serviceWorker from '@angular/service-worker';
|
||||
import * as upgrade from '@angular/upgrade';
|
||||
import * as upgradeStatic from '@angular/upgrade/static';
|
||||
import * as upgradeTesting from '@angular/upgrade/static/testing';
|
||||
|
||||
export default {
|
||||
animations,
|
||||
|
@ -71,5 +72,6 @@ export default {
|
|||
routerUpgrade,
|
||||
serviceWorker,
|
||||
upgrade,
|
||||
upgradeStatic
|
||||
upgradeStatic,
|
||||
upgradeTesting,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
// #docregion angular-setup
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {createAngularJSTestingModule, createAngularTestingModule} from '@angular/upgrade/static/testing';
|
||||
|
||||
import {HeroesService, Ng2AppModule, ng1AppModule} from './module';
|
||||
|
||||
const {module, inject} = (window as any).angular.mock;
|
||||
|
||||
// #enddocregion angular-setup
|
||||
describe('HeroesService (from Angular)', () => {
|
||||
|
||||
// #docregion angular-setup
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule(
|
||||
{imports: [createAngularTestingModule([ng1AppModule.name]), Ng2AppModule]});
|
||||
});
|
||||
// #enddocregion angular-setup
|
||||
|
||||
// #docregion angular-spec
|
||||
it('should have access to the HeroesService', () => {
|
||||
const heroesService = TestBed.get(HeroesService) as HeroesService;
|
||||
expect(heroesService).toBeDefined();
|
||||
});
|
||||
// #enddocregion angular-spec
|
||||
});
|
||||
|
||||
|
||||
describe('HeroesService (from AngularJS)', () => {
|
||||
// #docregion angularjs-setup
|
||||
beforeEach(module(createAngularJSTestingModule([Ng2AppModule])));
|
||||
beforeEach(module(ng1AppModule.name));
|
||||
// #enddocregion angularjs-setup
|
||||
|
||||
// #docregion angularjs-spec
|
||||
it('should have access to the HeroesService',
|
||||
inject((heroesService: HeroesService) => { expect(heroesService).toBeDefined(); }));
|
||||
// #enddocregion angularjs-spec
|
||||
});
|
|
@ -13,13 +13,13 @@ import {UpgradeComponent, UpgradeModule, downgradeComponent, downgradeInjectable
|
|||
|
||||
declare var angular: ng.IAngularStatic;
|
||||
|
||||
interface Hero {
|
||||
export interface Hero {
|
||||
name: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
// #docregion ng1-text-formatter-service
|
||||
class TextFormatter {
|
||||
export class TextFormatter {
|
||||
titleCase(value: string) { return value.replace(/((^|\s)[a-z])/g, (_, c) => c.toUpperCase()); }
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ class TextFormatter {
|
|||
</div>
|
||||
<button (click)="addHero.emit()">Add Hero</button>`,
|
||||
})
|
||||
class Ng2HeroesComponent {
|
||||
export class Ng2HeroesComponent {
|
||||
@Input() heroes !: Hero[];
|
||||
@Output() addHero = new EventEmitter();
|
||||
@Output() removeHero = new EventEmitter();
|
||||
|
@ -48,7 +48,7 @@ class Ng2HeroesComponent {
|
|||
// #docregion ng2-heroes-service
|
||||
// This Angular service will be "downgraded" to be used in AngularJS
|
||||
@Injectable()
|
||||
class HeroesService {
|
||||
export class HeroesService {
|
||||
heroes: Hero[] = [
|
||||
{name: 'superman', description: 'The man of steel'},
|
||||
{name: 'wonder woman', description: 'Princess of the Amazons'},
|
||||
|
@ -74,7 +74,7 @@ class HeroesService {
|
|||
// #docregion ng1-hero-wrapper
|
||||
// This Angular directive will act as an interface to the "upgraded" AngularJS component
|
||||
@Directive({selector: 'ng1-hero'})
|
||||
class Ng1HeroComponentWrapper extends UpgradeComponent {
|
||||
export class Ng1HeroComponentWrapper extends UpgradeComponent {
|
||||
// The names of the input and output properties here must match the names of the
|
||||
// `<` and `&` bindings in the AngularJS component that is being wrapped
|
||||
@Input() hero !: Hero;
|
||||
|
@ -104,7 +104,7 @@ class Ng1HeroComponentWrapper extends UpgradeComponent {
|
|||
imports: [BrowserModule, UpgradeModule]
|
||||
})
|
||||
// #docregion bootstrap-ng1
|
||||
class Ng2AppModule {
|
||||
export class Ng2AppModule {
|
||||
// #enddocregion ng2-module
|
||||
constructor(private upgrade: UpgradeModule) {}
|
||||
|
||||
|
@ -122,7 +122,7 @@ class Ng2AppModule {
|
|||
// #docregion Angular 1 Stuff
|
||||
// #docregion ng1-module
|
||||
// This Angular 1 module represents the AngularJS pieces of the application
|
||||
const ng1AppModule = angular.module('ng1AppModule', []);
|
||||
export const ng1AppModule: ng.IModule = angular.module('ng1AppModule', []);
|
||||
// #enddocregion
|
||||
|
||||
// #docregion ng1-hero
|
||||
|
|
|
@ -17,10 +17,13 @@ def create_upgrade_example_targets(name, srcs, e2e_srcs, entry_module, assets =
|
|||
type_check = False,
|
||||
deps = [
|
||||
"@npm//@types/angular",
|
||||
"@npm//@types/jasmine",
|
||||
"//packages/core",
|
||||
"//packages/platform-browser",
|
||||
"//packages/platform-browser-dynamic",
|
||||
"//packages/upgrade/static",
|
||||
"//packages/core/testing",
|
||||
"//packages/upgrade/static/testing",
|
||||
],
|
||||
tsconfig = "//packages/examples/upgrade:tsconfig-build.json",
|
||||
)
|
||||
|
|
|
@ -23,6 +23,7 @@ ng_package(
|
|||
srcs = [
|
||||
"package.json",
|
||||
"//packages/upgrade/static:package.json",
|
||||
"//packages/upgrade/static/testing:package.json",
|
||||
],
|
||||
entry_point = ":index.ts",
|
||||
tags = [
|
||||
|
@ -34,5 +35,6 @@ ng_package(
|
|||
deps = [
|
||||
":upgrade",
|
||||
"//packages/upgrade/static",
|
||||
"//packages/upgrade/static/testing",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -234,6 +234,7 @@ let angular: {
|
|||
(e: string | Element | Document | IAugmentedJQuery): IAugmentedJQuery;
|
||||
cleanData: (nodes: Node[] | NodeList) => void;
|
||||
},
|
||||
injector: (modules: Array<string|IInjectable>, strictDi?: boolean) => IInjectorService,
|
||||
version: {major: number},
|
||||
resumeBootstrap: () => void,
|
||||
getTestability: (e: Element) => ITestabilityService
|
||||
|
@ -241,6 +242,7 @@ let angular: {
|
|||
bootstrap: noNg,
|
||||
module: noNg,
|
||||
element: noNgElement,
|
||||
injector: noNg,
|
||||
version: undefined as any,
|
||||
resumeBootstrap: noNg,
|
||||
getTestability: noNg
|
||||
|
@ -304,6 +306,9 @@ export const module_: typeof angular.module = (prefix, dependencies?) =>
|
|||
export const element: typeof angular.element = (e => angular.element(e)) as typeof angular.element;
|
||||
element.cleanData = nodes => angular.element.cleanData(nodes);
|
||||
|
||||
export const injector: typeof angular.injector =
|
||||
(modules: Array<string|IInjectable>, strictDi?: boolean) => angular.injector(modules, strictDi);
|
||||
|
||||
export const resumeBootstrap: typeof angular.resumeBootstrap = () => angular.resumeBootstrap();
|
||||
|
||||
export const getTestability: typeof angular.getTestability = e => angular.getTestability(e);
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
load("//tools:defaults.bzl", "ng_module")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
exports_files(["package.json"])
|
||||
|
||||
ng_module(
|
||||
name = "testing",
|
||||
srcs = glob(
|
||||
[
|
||||
"*.ts",
|
||||
"src/*.ts",
|
||||
],
|
||||
),
|
||||
deps = [
|
||||
"//packages/core/testing",
|
||||
"//packages/upgrade/src/common",
|
||||
],
|
||||
)
|
|
@ -0,0 +1,9 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
export * from './public_api';
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "@angular/upgrade/static/testing",
|
||||
"main": "../../bundles/upgrade-static-testing.umd.js",
|
||||
"module": "../../fesm5/static/testing.js",
|
||||
"es2015": "../../fesm2015/static/testing.js",
|
||||
"esm5": "../../esm5/static/testing/testing.js",
|
||||
"esm2015": "../../esm2015/static/testing/testing.js",
|
||||
"fesm5": "../../fesm5/static/testing.js",
|
||||
"fesm2015": "../../fesm2015/static/testing.js",
|
||||
"typings": "./testing.d.ts"
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
export {createAngularTestingModule} from './src/create_angular_testing_module';
|
||||
export {createAngularJSTestingModule} from './src/create_angularjs_testing_module';
|
|
@ -0,0 +1,99 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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 {Injector, NgModule, Type} from '@angular/core';
|
||||
|
||||
import * as angular from '../../../src/common/src/angular1';
|
||||
import {$INJECTOR, INJECTOR_KEY, UPGRADE_APP_TYPE_KEY} from '../../../src/common/src/constants';
|
||||
import {UpgradeAppType} from '../../../src/common/src/util';
|
||||
|
||||
export let $injector: angular.IInjectorService|null = null;
|
||||
let injector: Injector;
|
||||
|
||||
export function $injectorFactory() {
|
||||
return $injector;
|
||||
}
|
||||
|
||||
@NgModule({providers: [{provide: $INJECTOR, useFactory: $injectorFactory}]})
|
||||
export class AngularTestingModule {
|
||||
constructor(i: Injector) { injector = i; }
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper function to use when unit testing Angular services that depend upon upgraded AngularJS
|
||||
* services.
|
||||
*
|
||||
* This function returns an `NgModule` decorated class that is configured to wire up the Angular
|
||||
* and AngularJS injectors without the need to actually bootstrap a hybrid application.
|
||||
* This makes it simpler and faster to unit test services.
|
||||
*
|
||||
* Use the returned class as an "import" when configuring the `TestBed`.
|
||||
*
|
||||
* In the following code snippet, we are configuring the TestBed with two imports.
|
||||
* The `Ng2AppModule` is the Angular part of our hybrid application and the `ng1AppModule` is the
|
||||
* AngularJS part.
|
||||
*
|
||||
* <code-example path="upgrade/static/ts/full/module.spec.ts" region="angular-setup"></code-example>
|
||||
*
|
||||
* Once this is done we can get hold of services via the Angular `Injector` as normal.
|
||||
* Services that are (or have dependencies on) an upgraded AngularJS service, will be instantiated
|
||||
* as needed by the AngularJS `$injector`.
|
||||
*
|
||||
* In the following code snippet, `HeroesService` is an Angular service that depends upon an
|
||||
* AngularJS service, `titleCase`.
|
||||
*
|
||||
* <code-example path="upgrade/static/ts/full/module.spec.ts" region="angular-spec"></code-example>
|
||||
*
|
||||
* <div class="alert is-important">
|
||||
*
|
||||
* This helper is for testing services not Components.
|
||||
* For Component testing you must still bootstrap a hybrid app. See `UpgradeModule` or
|
||||
* `downgradeModule` for more information.
|
||||
*
|
||||
* </div>
|
||||
*
|
||||
* <div class="alert is-important">
|
||||
*
|
||||
* The resulting configuration does not wire up AngularJS digests to Zone hooks. It is the
|
||||
* responsibility of the test writer to call `$rootScope.$apply`, as necessary, to trigger
|
||||
* AngularJS handlers of async events from Angular.
|
||||
*
|
||||
* </div>
|
||||
*
|
||||
* <div class="alert is-important">
|
||||
*
|
||||
* The helper sets up global variables to hold the shared Angular and AngularJS injectors.
|
||||
*
|
||||
* * Only call this helper once per spec.
|
||||
* * Do not use `createAngularTestingModule` in the same spec as `createAngularJSTestingModule`.
|
||||
*
|
||||
* </div>
|
||||
*
|
||||
* Here is the example application and its unit tests that use `createAngularTestingModule`
|
||||
* and `createAngularJSTestingModule`.
|
||||
*
|
||||
* <code-tabs>
|
||||
* <code-pane header="module.spec.ts" path="upgrade/static/ts/full/module.spec.ts"></code-pane>
|
||||
* <code-pane header="module.ts" path="upgrade/static/ts/full/module.ts"></code-pane>
|
||||
* </code-tabs>
|
||||
*
|
||||
*
|
||||
* @param angularJSModules a collection of the names of AngularJS modules to include in the
|
||||
* configuration.
|
||||
* @param [strictDi] whether the AngularJS injector should have `strictDI` enabled.
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export function createAngularTestingModule(
|
||||
angularJSModules: string[], strictDi?: boolean): Type<any> {
|
||||
angular.module_('$$angularJSTestingModule', angularJSModules)
|
||||
.constant(UPGRADE_APP_TYPE_KEY, UpgradeAppType.Static)
|
||||
.factory(INJECTOR_KEY, () => injector);
|
||||
$injector = angular.injector(['ng', '$$angularJSTestingModule'], strictDi);
|
||||
return AngularTestingModule;
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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 {Injector} from '@angular/core';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
|
||||
import * as ng from '../../../src/common/src/angular1';
|
||||
import {$INJECTOR, INJECTOR_KEY, UPGRADE_APP_TYPE_KEY} from '../../../src/common/src/constants';
|
||||
import {UpgradeAppType} from '../../../src/common/src/util';
|
||||
|
||||
|
||||
/**
|
||||
* A helper function to use when unit testing AngularJS services that depend upon downgraded Angular
|
||||
* services.
|
||||
*
|
||||
* This function returns an AngularJS module that is configured to wire up the AngularJS and Angular
|
||||
* injectors without the need to actually bootstrap a hybrid application.
|
||||
* This makes it simpler and faster to unit test services.
|
||||
*
|
||||
* Use the returned AngularJS module in a call to
|
||||
* [`angular.mocks.module`](https://docs.angularjs.org/api/ngMock/function/angular.mock.module) to
|
||||
* include this module in the unit test injector.
|
||||
*
|
||||
* In the following code snippet, we are configuring the `$injector` with two modules:
|
||||
* The AngularJS `ng1AppModule`, which is the AngularJS part of our hybrid application and the
|
||||
* `Ng2AppModule`, which is the Angular part.
|
||||
*
|
||||
* <code-example path="upgrade/static/ts/full/module.spec.ts"
|
||||
* region="angularjs-setup"></code-example>
|
||||
*
|
||||
* Once this is done we can get hold of services via the AngularJS `$injector` as normal.
|
||||
* Services that are (or have dependencies on) a downgraded Angular service, will be instantiated as
|
||||
* needed by the Angular root `Injector`.
|
||||
*
|
||||
* In the following code snippet, `heroesService` is a downgraded Angular service that we are
|
||||
* accessing from AngularJS.
|
||||
*
|
||||
* <code-example path="upgrade/static/ts/full/module.spec.ts"
|
||||
* region="angularjs-spec"></code-example>
|
||||
*
|
||||
* <div class="alert is-important">
|
||||
*
|
||||
* This helper is for testing services not components.
|
||||
* For Component testing you must still bootstrap a hybrid app. See `UpgradeModule` or
|
||||
* `downgradeModule` for more information.
|
||||
*
|
||||
* </div>
|
||||
*
|
||||
* <div class="alert is-important">
|
||||
*
|
||||
* The resulting configuration does not wire up AngularJS digests to Zone hooks. It is the
|
||||
* responsibility of the test writer to call `$rootScope.$apply`, as necessary, to trigger
|
||||
* AngularJS handlers of async events from Angular.
|
||||
*
|
||||
* </div>
|
||||
*
|
||||
* <div class="alert is-important">
|
||||
*
|
||||
* The helper sets up global variables to hold the shared Angular and AngularJS injectors.
|
||||
*
|
||||
* * Only call this helper once per spec.
|
||||
* * Do not use `createAngularJSTestingModule` in the same spec as `createAngularTestingModule`.
|
||||
*
|
||||
* </div>
|
||||
*
|
||||
* Here is the example application and its unit tests that use `createAngularTestingModule`
|
||||
* and `createAngularJSTestingModule`.
|
||||
*
|
||||
* <code-tabs>
|
||||
* <code-pane header="module.spec.ts" path="upgrade/static/ts/full/module.spec.ts"></code-pane>
|
||||
* <code-pane header="module.ts" path="upgrade/static/ts/full/module.ts"></code-pane>
|
||||
* </code-tabs>
|
||||
*
|
||||
*
|
||||
* @param angularModules a collection of Angular modules to include in the configuration.
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
export function createAngularJSTestingModule(angularModules: any[]): string {
|
||||
return ng.module_('$$angularJSTestingModule', [])
|
||||
.constant(UPGRADE_APP_TYPE_KEY, UpgradeAppType.Static)
|
||||
.factory(
|
||||
INJECTOR_KEY,
|
||||
[
|
||||
$INJECTOR,
|
||||
($injector: ng.IInjectorService) => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: angularModules,
|
||||
providers: [{provide: $INJECTOR, useValue: $injector}]
|
||||
});
|
||||
return TestBed.get(Injector);
|
||||
}
|
||||
])
|
||||
.name;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("//tools:defaults.bzl", "ts_library", "ts_web_test_suite")
|
||||
|
||||
ts_library(
|
||||
name = "test_lib",
|
||||
testonly = True,
|
||||
srcs = glob([
|
||||
"**/*.ts",
|
||||
]),
|
||||
deps = [
|
||||
"//packages/core",
|
||||
"//packages/core/testing",
|
||||
"//packages/upgrade/src/common",
|
||||
"//packages/upgrade/src/common/test/helpers",
|
||||
"//packages/upgrade/static",
|
||||
"//packages/upgrade/static/testing",
|
||||
],
|
||||
)
|
||||
|
||||
ts_web_test_suite(
|
||||
name = "test",
|
||||
static_files = [
|
||||
"//:angularjs_scripts",
|
||||
],
|
||||
deps = [
|
||||
":test_lib",
|
||||
],
|
||||
)
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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 {Injector} from '@angular/core';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
|
||||
import {$INJECTOR} from '../../../src/common/src/constants';
|
||||
import {withEachNg1Version} from '../../../src/common/test/helpers/common_test_helpers';
|
||||
import {createAngularTestingModule} from '../src/create_angular_testing_module';
|
||||
|
||||
import {AppModule, Inventory, defineAppModule, serverRequestInstance} from './mocks';
|
||||
|
||||
withEachNg1Version(() => {
|
||||
describe('Angular entry point', () => {
|
||||
it('should allow us to get an upgraded AngularJS service from an Angular service', () => {
|
||||
defineAppModule();
|
||||
// Configure an NgModule that has the Angular and AngularJS injectors wired up
|
||||
TestBed.configureTestingModule({imports: [createAngularTestingModule(['app']), AppModule]});
|
||||
const inventory = TestBed.get(Inventory) as Inventory;
|
||||
expect(inventory.serverRequest).toBe(serverRequestInstance);
|
||||
});
|
||||
|
||||
it('should create new injectors when we re-use the helper', () => {
|
||||
defineAppModule();
|
||||
TestBed.configureTestingModule({imports: [createAngularTestingModule(['app']), AppModule]});
|
||||
// Check that the injectors are wired up correctly
|
||||
TestBed.get(Inventory) as Inventory;
|
||||
|
||||
// Grab references to the current injectors
|
||||
const injector = TestBed.get(Injector);
|
||||
const $injector = TestBed.get($INJECTOR);
|
||||
|
||||
TestBed.resetTestingModule();
|
||||
TestBed.configureTestingModule({imports: [createAngularTestingModule(['app']), AppModule]});
|
||||
// Check that the injectors are wired up correctly
|
||||
TestBed.get(Inventory) as Inventory;
|
||||
|
||||
// Check that the new injectors are different to the previous ones.
|
||||
expect(TestBed.get(Injector)).not.toBe(injector);
|
||||
expect(TestBed.get($INJECTOR)).not.toBe($injector);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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 {getAngularJSGlobal} from '../../../src/common/src/angular1';
|
||||
import {withEachNg1Version} from '../../../src/common/test/helpers/common_test_helpers';
|
||||
import {createAngularJSTestingModule} from '../src/create_angularjs_testing_module';
|
||||
|
||||
import {AppModule, Inventory, defineAppModule} from './mocks';
|
||||
|
||||
|
||||
withEachNg1Version(() => {
|
||||
describe('AngularJS entry point', () => {
|
||||
it('should allow us to get a downgraded Angular service from an AngularJS service', () => {
|
||||
defineAppModule();
|
||||
// We have to get the `mock` object from the global `angular` variable, rather than trying to
|
||||
// import it from `@angular/upgrade/src/common/angular1`, because that file doesn't export
|
||||
// `ngMock` helpers.
|
||||
const {inject, module} = getAngularJSGlobal().mock;
|
||||
// Load the AngularJS bits of the application
|
||||
module('app');
|
||||
// Configure an AngularJS module that has the AngularJS and Angular injector wired up
|
||||
module(createAngularJSTestingModule([AppModule]));
|
||||
let inventory: any = undefined;
|
||||
inject(function(shoppingCart: any) { inventory = shoppingCart.inventory; });
|
||||
expect(inventory).toEqual(jasmine.any(Inventory));
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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 {Inject, Injectable, NgModule} from '@angular/core';
|
||||
import {downgradeInjectable} from '@angular/upgrade/static';
|
||||
import * as ng from '../../../src/common/src/angular1';
|
||||
/*
|
||||
* This mock application code contains the following services and their dependencies:
|
||||
*
|
||||
* shoppingCart (AngularJS)
|
||||
* -> Inventory (Angular - downgraded)
|
||||
* -> serverRequest (AngularJS - upgraded)
|
||||
* -> Logger (Angular - downgraded)
|
||||
*
|
||||
* This allows us to test two scenarios:
|
||||
* * AngularJS -> Angular -> AngularJS
|
||||
* * Angular -> AngularJS -> Angular
|
||||
*/
|
||||
|
||||
/* START: Angular bits */
|
||||
@Injectable()
|
||||
export class Logger {
|
||||
warn() {}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class Inventory {
|
||||
constructor(@Inject('serverRequest') public serverRequest: any) {}
|
||||
}
|
||||
|
||||
export function serverRequestFactory(i: ng.IInjectorService) {
|
||||
return i.get('serverRequest');
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
providers: [
|
||||
Logger,
|
||||
Inventory,
|
||||
{provide: 'serverRequest', useFactory: serverRequestFactory, deps: ['$injector']},
|
||||
]
|
||||
})
|
||||
export class AppModule {
|
||||
}
|
||||
/* END: Angular bits */
|
||||
|
||||
/* START: AngularJS bits */
|
||||
export const serverRequestInstance: {logger?: Logger} = {};
|
||||
export const shoppingCartInstance: {inventory?: Inventory} = {};
|
||||
|
||||
export function defineAppModule() {
|
||||
ng.module_('app', [])
|
||||
.factory('logger', downgradeInjectable(Logger))
|
||||
.factory('inventory', downgradeInjectable(Inventory))
|
||||
.factory(
|
||||
'serverRequest',
|
||||
[
|
||||
'logger',
|
||||
function(logger: Logger) {
|
||||
serverRequestInstance.logger = logger;
|
||||
return serverRequestInstance;
|
||||
}
|
||||
])
|
||||
.factory('shoppingCart', [
|
||||
'inventory',
|
||||
function(inventory: Inventory) {
|
||||
shoppingCartInstance.inventory = inventory;
|
||||
return shoppingCartInstance;
|
||||
}
|
||||
]);
|
||||
}
|
||||
/* END: AngularJS bits */
|
|
@ -51,6 +51,7 @@ System.config({
|
|||
'@angular/router': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/http/testing': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/http': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/upgrade/static/testing': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/upgrade/static': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/upgrade': {main: 'index.js', defaultExtension: 'js'},
|
||||
'@angular/platform-browser/animations/testing': {main: 'index.js', defaultExtension: 'js'},
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
export declare function createAngularJSTestingModule(angularModules: any[]): string;
|
||||
|
||||
export declare function createAngularTestingModule(angularJSModules: string[], strictDi?: boolean): Type<any>;
|
Loading…
Reference in New Issue