2016-10-19 16:41:04 -04:00
|
|
|
/**
|
|
|
|
* @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
|
|
|
|
*/
|
|
|
|
|
2017-01-24 17:48:03 -05:00
|
|
|
import {InjectionToken, Injector, NgModule, destroyPlatform} from '@angular/core';
|
2016-10-19 16:41:04 -04:00
|
|
|
import {async} from '@angular/core/testing';
|
|
|
|
import {BrowserModule} from '@angular/platform-browser';
|
|
|
|
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
feat(upgrade): return a function (instead of array) from `downgradeInjectable()` (#14037)
This makes it more consistent with the dynamic version of `upgrade` and makes it
possible to share code between the dynamic and static versions.
This commit also refactors the file layout, moving common and dynamic-specific
files to `common/` and `dynamic/` directories respectively and renaming `aot/`
to `static/`.
Some private keys, used as AngularJS DI tokens, have also been renamed, but this
should not affect apps, since these keys are undocumented and not supposed to
be used externally.
BREAKING CHANGE:
Previously, `upgrade/static/downgradeInjectable` returned an array of the form:
```js
['dep1', 'dep2', ..., function factory(dep1, dep2, ...) { ... }]
```
Now it returns a function with an `$inject` property:
```js
factory.$inject = ['dep1', 'dep2', ...];
function factory(dep1, dep2, ...) { ... }
```
It shouldn't affect the behavior of apps, since both forms are equally suitable
to be used for registering AngularJS injectable services, but it is possible
that type-checking might fail or that current code breaks if it relies on the
returned value being an array.
2017-01-13 09:20:28 -05:00
|
|
|
import * as angular from '@angular/upgrade/src/common/angular1';
|
|
|
|
import {$INJECTOR, INJECTOR_KEY} from '@angular/upgrade/src/common/constants';
|
2017-05-09 13:55:38 -04:00
|
|
|
import {UpgradeModule, downgradeInjectable, getAngularJSGlobal, setAngularJSGlobal} from '@angular/upgrade/static';
|
2016-10-19 16:41:04 -04:00
|
|
|
|
|
|
|
import {bootstrap, html} from '../test_helpers';
|
|
|
|
|
2017-12-16 17:42:55 -05:00
|
|
|
{
|
2016-10-19 16:41:04 -04:00
|
|
|
describe('injection', () => {
|
|
|
|
|
|
|
|
beforeEach(() => destroyPlatform());
|
|
|
|
afterEach(() => destroyPlatform());
|
|
|
|
|
|
|
|
it('should downgrade ng2 service to ng1', async(() => {
|
|
|
|
// Tokens used in ng2 to identify services
|
2017-01-03 19:54:46 -05:00
|
|
|
const Ng2Service = new InjectionToken('ng2-service');
|
2016-10-19 16:41:04 -04:00
|
|
|
|
|
|
|
// Sample ng1 NgModule for tests
|
|
|
|
@NgModule({
|
|
|
|
imports: [BrowserModule, UpgradeModule],
|
|
|
|
providers: [
|
|
|
|
{provide: Ng2Service, useValue: 'ng2 service value'},
|
|
|
|
]
|
|
|
|
})
|
|
|
|
class Ng2Module {
|
|
|
|
ngDoBootstrap() {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// create the ng1 module that will import an ng2 service
|
|
|
|
const ng1Module =
|
|
|
|
angular.module('ng1Module', []).factory('ng2Service', downgradeInjectable(Ng2Service));
|
|
|
|
|
|
|
|
bootstrap(platformBrowserDynamic(), Ng2Module, html('<div>'), ng1Module)
|
|
|
|
.then((upgrade) => {
|
|
|
|
const ng1Injector = upgrade.$injector;
|
|
|
|
expect(ng1Injector.get('ng2Service')).toBe('ng2 service value');
|
|
|
|
});
|
|
|
|
}));
|
|
|
|
|
|
|
|
it('should upgrade ng1 service to ng2', async(() => {
|
|
|
|
// Tokens used in ng2 to identify services
|
2017-01-03 19:54:46 -05:00
|
|
|
const Ng1Service = new InjectionToken('ng1-service');
|
2016-10-19 16:41:04 -04:00
|
|
|
|
|
|
|
// Sample ng1 NgModule for tests
|
|
|
|
@NgModule({
|
|
|
|
imports: [BrowserModule, UpgradeModule],
|
|
|
|
providers: [
|
2017-01-27 01:30:42 -05:00
|
|
|
// the following line is the "upgrade" of an AngularJS service
|
2016-10-19 16:41:04 -04:00
|
|
|
{
|
|
|
|
provide: Ng1Service,
|
|
|
|
useFactory: (i: angular.IInjectorService) => i.get('ng1Service'),
|
|
|
|
deps: ['$injector']
|
|
|
|
}
|
|
|
|
]
|
|
|
|
})
|
|
|
|
class Ng2Module {
|
|
|
|
ngDoBootstrap() {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// create the ng1 module that will import an ng2 service
|
|
|
|
const ng1Module = angular.module('ng1Module', []).value('ng1Service', 'ng1 service value');
|
|
|
|
|
|
|
|
bootstrap(platformBrowserDynamic(), Ng2Module, html('<div>'), ng1Module)
|
|
|
|
.then((upgrade) => {
|
2016-11-12 08:08:58 -05:00
|
|
|
const ng2Injector = upgrade.injector;
|
2016-10-19 16:41:04 -04:00
|
|
|
expect(ng2Injector.get(Ng1Service)).toBe('ng1 service value');
|
|
|
|
});
|
|
|
|
}));
|
2017-01-24 17:48:03 -05:00
|
|
|
|
|
|
|
it('should initialize the upgraded injector before application run blocks are executed',
|
|
|
|
async(() => {
|
|
|
|
let runBlockTriggered = false;
|
|
|
|
|
|
|
|
const ng1Module = angular.module('ng1Module', []).run([
|
|
|
|
INJECTOR_KEY,
|
|
|
|
function(injector: Injector) {
|
|
|
|
runBlockTriggered = true;
|
|
|
|
expect(injector.get($INJECTOR)).toBeDefined();
|
|
|
|
}
|
|
|
|
]);
|
|
|
|
|
|
|
|
@NgModule({imports: [BrowserModule, UpgradeModule]})
|
|
|
|
class Ng2Module {
|
|
|
|
ngDoBootstrap() {}
|
|
|
|
}
|
|
|
|
|
|
|
|
bootstrap(platformBrowserDynamic(), Ng2Module, html('<div>'), ng1Module).then(() => {
|
|
|
|
expect(runBlockTriggered).toBeTruthy();
|
|
|
|
});
|
|
|
|
}));
|
2017-04-14 14:25:56 -04:00
|
|
|
|
|
|
|
it('should allow resetting angular at runtime', async(() => {
|
|
|
|
let wrappedBootstrapepedCalled = false;
|
|
|
|
|
2017-05-09 13:55:38 -04:00
|
|
|
const n: any = getAngularJSGlobal();
|
2017-04-14 14:25:56 -04:00
|
|
|
|
2017-05-09 13:55:38 -04:00
|
|
|
setAngularJSGlobal({
|
2017-04-14 14:25:56 -04:00
|
|
|
bootstrap: (...args: any[]) => {
|
|
|
|
wrappedBootstrapepedCalled = true;
|
|
|
|
n.bootstrap(...args);
|
|
|
|
},
|
|
|
|
module: n.module,
|
|
|
|
element: n.element,
|
|
|
|
version: n.version,
|
|
|
|
resumeBootstrap: n.resumeBootstrap,
|
|
|
|
getTestability: n.getTestability
|
|
|
|
});
|
|
|
|
|
|
|
|
@NgModule({imports: [BrowserModule, UpgradeModule]})
|
|
|
|
class Ng2Module {
|
|
|
|
ngDoBootstrap() {}
|
|
|
|
}
|
|
|
|
|
|
|
|
const ng1Module = angular.module('ng1Module', []);
|
|
|
|
|
|
|
|
bootstrap(platformBrowserDynamic(), Ng2Module, html('<div>'), ng1Module)
|
|
|
|
.then((upgrade) => { expect(wrappedBootstrapepedCalled).toEqual(true); });
|
|
|
|
}));
|
2016-10-19 16:41:04 -04:00
|
|
|
});
|
2016-10-20 22:35:35 -04:00
|
|
|
}
|