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.
This commit is contained in:
Georgios Kalpakas 2017-01-13 16:20:28 +02:00 committed by Miško Hevery
parent 49fce37013
commit 1f90f29369
35 changed files with 169 additions and 181 deletions

View File

@ -9,7 +9,10 @@
/**
* @module
* @description
* Entry point for all public APIs of the upgrade package.
* Entry point for all public APIs of the upgrade/dynamic package, allowing
* Angular 1 and Angular 2+ to run side by side in the same application.
*/
export * from './src/upgrade';
// This file only reexports content of the `src` folder. Keep it that way.
export {VERSION} from './src/common/version';
export {UpgradeAdapter, UpgradeAdapterRef} from './src/dynamic/upgrade_adapter';
// This file only re-exports content of the `src` folder. Keep it that way.

View File

@ -8,6 +8,8 @@
export type Ng1Token = string;
export type Ng1Expression = string | Function;
export interface IAnnotatedFunction extends Function { $inject?: Ng1Token[]; }
export type IInjectable = (Ng1Token | Function)[] | IAnnotatedFunction;
@ -42,12 +44,10 @@ export interface IRootScopeService {
$id: string;
$parent: IScope;
$root: IScope;
$watch(expr: any, fn?: (a1?: any, a2?: any) => void): Function;
$watch(exp: Ng1Expression, fn?: (a1?: any, a2?: any) => void): Function;
$on(event: string, fn?: (event?: any, ...args: any[]) => void): Function;
$destroy(): any;
$apply(): any;
$apply(exp: string): any;
$apply(exp: Function): any;
$apply(exp?: Ng1Expression): any;
$digest(): any;
$evalAsync(): any;
$on(event: string, fn?: (event?: any, ...args: any[]) => void): Function;
@ -142,6 +142,10 @@ export interface ICacheObject {
get(key: string): any;
}
export interface ITemplateCacheService extends ICacheObject {}
export interface ITemplateRequestService {
(template: string|any /* TrustedResourceUrl */, ignoreRequestError?: boolean): Promise<string>;
totalPendingRequests: number;
}
export type IController = string | IInjectable;
export interface IControllerService {
(controllerConstructor: IController, locals?: any, later?: any, ident?: any): any;

View File

@ -6,19 +6,26 @@
* found in the LICENSE file at https://angular.io/license
*/
export const UPGRADE_MODULE_NAME = '$$UpgradeModule';
export const INJECTOR_KEY = '$$angularInjector';
export const REQUIRE_NG1_MODEL = '?ngModel';
export const $COMPILE = '$compile';
export const $CONTROLLER = '$controller';
export const $DELEGATE = '$delegate';
export const $HTTP_BACKEND = '$httpBackend';
export const $INJECTOR = '$injector';
export const $PARSE = '$parse';
export const $PROVIDE = '$provide';
export const $ROOT_SCOPE = '$rootScope';
export const $SCOPE = '$scope';
export const $PROVIDE = '$provide';
export const $DELEGATE = '$delegate';
export const $TEMPLATE_CACHE = '$templateCache';
export const $TEMPLATE_REQUEST = '$templateRequest';
export const $$TESTABILITY = '$$testability';
export const $COMPILE = '$compile';
export const $TEMPLATE_CACHE = '$templateCache';
export const $HTTP_BACKEND = '$httpBackend';
export const $CONTROLLER = '$controller';
export const COMPILER_KEY = '$$angularCompiler';
export const COMPONENT_FACTORY_REF_MAP_KEY = '$$angularComponentFactoryRefMap';
export const INJECTOR_KEY = '$$angularInjector';
export const NG_ZONE_KEY = '$$angularNgZone';
export const REQUIRE_INJECTOR = '?^^' + INJECTOR_KEY;
export const REQUIRE_NG_MODEL = '?ngModel';
export const UPGRADE_MODULE_NAME = '$$UpgradeModule';

View File

@ -51,6 +51,9 @@ import {INJECTOR_KEY} from './constants';
*
* @experimental
*/
export function downgradeInjectable(token: any) {
return [INJECTOR_KEY, (i: Injector) => i.get(token)];
}
export function downgradeInjectable(token: any): Function {
const factory = function(i: Injector) { return i.get(token); };
(factory as any).$inject = [INJECTOR_KEY];
return factory;
}

View File

@ -1,25 +0,0 @@
/**
* @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 const NG2_COMPILER = 'ng2.Compiler';
export const NG2_INJECTOR = 'ng2.Injector';
export const NG2_COMPONENT_FACTORY_REF_MAP = 'ng2.ComponentFactoryRefMap';
export const NG2_ZONE = 'ng2.NgZone';
export const NG1_PROVIDE = '$provide';
export const NG1_CONTROLLER = '$controller';
export const NG1_SCOPE = '$scope';
export const NG1_ROOT_SCOPE = '$rootScope';
export const NG1_COMPILE = '$compile';
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;
export const REQUIRE_NG1_MODEL = '?ngModel';

View File

@ -8,8 +8,9 @@
import {ChangeDetectorRef, ComponentFactory, ComponentRef, EventEmitter, Injector, OnChanges, ReflectiveInjector, SimpleChange, SimpleChanges} from '@angular/core';
import * as angular from './angular_js';
import {NG1_SCOPE} from './constants';
import * as angular from '../common/angular1';
import {$SCOPE} from '../common/constants';
import {ComponentInfo} from './metadata';
import {hookupNgModel} from './util';
@ -35,7 +36,7 @@ export class DowngradeNg2ComponentAdapter {
bootstrapNg2(projectableNodes: Node[][]) {
const childInjector = ReflectiveInjector.resolveAndCreate(
[{provide: NG1_SCOPE, useValue: this.componentScope}], this.parentInjector);
[{provide: $SCOPE, useValue: this.componentScope}], this.parentInjector);
this.componentRef =
this.componentFactory.create(childInjector, projectableNodes, this.element[0]);

View File

@ -10,12 +10,14 @@ import {CssSelector, SelectorMatcher, createElementCssSelector} from '@angular/c
import {Compiler, CompilerOptions, ComponentFactory, Injector, NgModule, NgModuleRef, NgZone, Provider, Testability, Type} from '@angular/core';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import * as angular from './angular_js';
import {NG1_COMPILE, NG1_INJECTOR, NG1_PARSE, NG1_ROOT_SCOPE, NG1_TESTABILITY, NG2_COMPILER, NG2_COMPONENT_FACTORY_REF_MAP, NG2_INJECTOR, NG2_ZONE, REQUIRE_INJECTOR, REQUIRE_NG1_MODEL} from './constants';
import * as angular from '../common/angular1';
import {$$TESTABILITY, $COMPILE, $INJECTOR, $PARSE, $ROOT_SCOPE, COMPILER_KEY, COMPONENT_FACTORY_REF_MAP_KEY, INJECTOR_KEY, NG_ZONE_KEY, REQUIRE_INJECTOR, REQUIRE_NG_MODEL} from '../common/constants';
import {downgradeInjectable} from '../common/downgrade_injectable';
import {Deferred, controllerKey, getAttributesAsArray, onError} from '../common/util';
import {DowngradeNg2ComponentAdapter} from './downgrade_ng2_adapter';
import {ComponentInfo, getComponentInfo} from './metadata';
import {UpgradeNg1ComponentAdapterBuilder} from './upgrade_ng1_adapter';
import {Deferred, controllerKey, getAttributesAsArray, onError} from './util';
let upgradeCount: number = 0;
@ -138,8 +140,8 @@ export class UpgradeAdapter {
* 2. Even thought the component is instantiated in AngularJS, it will be using Angular
* syntax. This has to be done, this way because we must follow Angular components do not
* declare how the attributes should be interpreted.
* 3. ng-model is controlled by AngularJS v1 and communicates with the downgraded Ng2 component
* by way of the ControlValueAccessor interface from @angular/forms. Only components that
* 3. `ng-model` is controlled by AngularJS and communicates with the downgraded Angular component
* by way of the `ControlValueAccessor` interface from @angular/forms. Only components that
* implement this interface are eligible.
*
* ## Supported Features
@ -397,7 +399,7 @@ export class UpgradeAdapter {
});
Promise.all([this.ng2BootstrapDeferred.promise, ng1BootstrapPromise]).then(([ng1Injector]) => {
angular.element(element).data(controllerKey(NG2_INJECTOR), this.moduleRef.injector);
angular.element(element).data(controllerKey(INJECTOR_KEY), this.moduleRef.injector);
this.moduleRef.injector.get(NgZone).run(
() => { (<any>upgrade)._bootstrapDone(this.moduleRef, ng1Injector); });
}, onError);
@ -440,7 +442,7 @@ export class UpgradeAdapter {
this.providers.push({
provide: token,
useFactory: (ng1Injector: angular.IInjectorService) => ng1Injector.get(name),
deps: [NG1_INJECTOR]
deps: [$INJECTOR]
});
}
@ -465,12 +467,7 @@ export class UpgradeAdapter {
*
* ```
*/
public downgradeNg2Provider(token: any): Function {
const factory = function(injector: Injector) { return injector.get(token); };
(<any>factory).$inject = [NG2_INJECTOR];
return factory;
}
downgradeNg2Provider(token: any): Function { return downgradeInjectable(token); }
/**
* Declare the AngularJS upgrade module for this adapter without bootstrapping the whole
@ -500,14 +497,14 @@ export class UpgradeAdapter {
this.ngZone = new NgZone({enableLongStackTrace: Zone.hasOwnProperty('longStackTraceZoneSpec')});
this.ng2BootstrapDeferred = new Deferred();
ng1Module.factory(NG2_INJECTOR, () => this.moduleRef.injector.get(Injector))
.constant(NG2_ZONE, this.ngZone)
.constant(NG2_COMPONENT_FACTORY_REF_MAP, componentFactoryRefMap)
.factory(NG2_COMPILER, () => this.moduleRef.injector.get(Compiler))
ng1Module.factory(INJECTOR_KEY, () => this.moduleRef.injector.get(Injector))
.constant(NG_ZONE_KEY, this.ngZone)
.constant(COMPONENT_FACTORY_REF_MAP_KEY, componentFactoryRefMap)
.factory(COMPILER_KEY, () => this.moduleRef.injector.get(Compiler))
.config([
'$provide', '$injector',
(provide: angular.IProvideService, ng1Injector: angular.IInjectorService) => {
provide.decorator(NG1_ROOT_SCOPE, [
provide.decorator($ROOT_SCOPE, [
'$delegate',
function(rootScopeDelegate: angular.IRootScopeService) {
// Capture the root apply so that we can delay first call to $apply until we
@ -522,8 +519,8 @@ export class UpgradeAdapter {
return rootScope = rootScopeDelegate;
}
]);
if (ng1Injector.has(NG1_TESTABILITY)) {
provide.decorator(NG1_TESTABILITY, [
if (ng1Injector.has($$TESTABILITY)) {
provide.decorator($$TESTABILITY, [
'$delegate',
function(testabilityDelegate: angular.ITestabilityService) {
const originalWhenStable: Function = testabilityDelegate.whenStable;
@ -558,8 +555,8 @@ export class UpgradeAdapter {
const DynamicNgUpgradeModule =
NgModule({
providers: [
{provide: NG1_INJECTOR, useFactory: () => ng1Injector},
{provide: NG1_COMPILE, useFactory: () => ng1Injector.get(NG1_COMPILE)},
{provide: $INJECTOR, useFactory: () => ng1Injector},
{provide: $COMPILE, useFactory: () => ng1Injector.get($COMPILE)},
this.providers
],
imports: [this.ng2AppModule]
@ -620,7 +617,7 @@ class ParentInjectorPromise {
constructor(private element: angular.IAugmentedJQuery) {
// store the promise on the element
element.data(controllerKey(NG2_INJECTOR), this);
element.data(controllerKey(INJECTOR_KEY), this);
}
then(callback: (injector: Injector) => any) {
@ -635,7 +632,7 @@ class ParentInjectorPromise {
this.injector = injector;
// reset the element data to point to the real injector
this.element.data(controllerKey(NG2_INJECTOR), injector);
this.element.data(controllerKey(INJECTOR_KEY), injector);
// clean out the element to prevent memory leaks
this.element = null;
@ -648,8 +645,7 @@ class ParentInjectorPromise {
function ng1ComponentDirective(info: ComponentInfo, idPrefix: string): Function {
(<any>directiveFactory).$inject =
[NG1_INJECTOR, NG1_COMPILE, NG2_COMPONENT_FACTORY_REF_MAP, NG1_PARSE];
(<any>directiveFactory).$inject = [$INJECTOR, $COMPILE, COMPONENT_FACTORY_REF_MAP_KEY, $PARSE];
function directiveFactory(
ng1Injector: angular.IInjectorService, ng1Compile: angular.ICompileService,
componentFactoryRefMap: ComponentFactoryRefMap,
@ -659,7 +655,7 @@ function ng1ComponentDirective(info: ComponentInfo, idPrefix: string): Function
return {
restrict: 'E',
terminal: true,
require: [REQUIRE_INJECTOR, REQUIRE_NG1_MODEL],
require: [REQUIRE_INJECTOR, REQUIRE_NG_MODEL],
compile: (templateElement: angular.IAugmentedJQuery, templateAttributes: angular.IAttributes,
transclude: angular.ITranscludeFunction) => {
// We might have compile the contents lazily, because this might have been triggered by the
@ -671,11 +667,12 @@ function ng1ComponentDirective(info: ComponentInfo, idPrefix: string): Function
let id = idPrefix + (idCount++);
(<any>element[0]).id = id;
let parentInjector: Injector|ParentInjectorPromise = required[0];
const ngModel: angular.INgModelController = required[1];
let parentInjector: Injector | ParentInjectorPromise = required[0];
let injectorPromise = new ParentInjectorPromise(element);
const ng2Compiler = ng1Injector.get(NG2_COMPILER) as Compiler;
const ngModel: angular.INgModelController = required[1];
const ng2Compiler = ng1Injector.get(COMPILER_KEY) as Compiler;
const ngContentSelectors = ng2Compiler.getNgContentSelectors(info.type);
const linkFns = compileProjectedNodes(templateElement, ngContentSelectors);
@ -693,7 +690,7 @@ function ng1ComponentDirective(info: ComponentInfo, idPrefix: string): Function
return projectedClone;
});
parentInjector = parentInjector || ng1Injector.get(NG2_INJECTOR);
parentInjector = parentInjector || ng1Injector.get(INJECTOR_KEY);
if (parentInjector instanceof ParentInjectorPromise) {
parentInjector.then((resolvedInjector: Injector) => downgrade(resolvedInjector));
@ -748,7 +745,7 @@ export class UpgradeAdapterRef {
this.ng2ModuleRef = ngModuleRef;
this.ng2Injector = ngModuleRef.injector;
this.ng1Injector = ng1Injector;
this.ng1RootScope = ng1Injector.get(NG1_ROOT_SCOPE);
this.ng1RootScope = ng1Injector.get($ROOT_SCOPE);
this._readyFn && this._readyFn(this);
}
@ -765,7 +762,7 @@ export class UpgradeAdapterRef {
* Dispose of running hybrid AngularJS / Angular application.
*/
public dispose() {
this.ng1Injector.get(NG1_ROOT_SCOPE).$destroy();
this.ng1Injector.get($ROOT_SCOPE).$destroy();
this.ng2ModuleRef.destroy();
}
}

View File

@ -8,9 +8,10 @@
import {Directive, DoCheck, ElementRef, EventEmitter, Inject, OnChanges, OnInit, SimpleChange, SimpleChanges, Type} from '@angular/core';
import * as angular from './angular_js';
import {NG1_COMPILE, NG1_CONTROLLER, NG1_HTTP_BACKEND, NG1_SCOPE, NG1_TEMPLATE_CACHE} from './constants';
import {controllerKey} from './util';
import * as angular from '../common/angular1';
import {$COMPILE, $CONTROLLER, $HTTP_BACKEND, $SCOPE, $TEMPLATE_CACHE} from '../common/constants';
import {controllerKey} from '../common/util';
interface IBindingDestination {
[key: string]: any;
@ -55,7 +56,7 @@ export class UpgradeNg1ComponentAdapterBuilder {
Directive({selector: selector, inputs: this.inputsRename, outputs: this.outputsRename})
.Class({
constructor: [
new Inject(NG1_SCOPE), ElementRef,
new Inject($SCOPE), ElementRef,
function(scope: angular.IScope, elementRef: ElementRef) {
return new UpgradeNg1ComponentAdapter(
self.linkFn, scope, self.directive, elementRef, self.$controller, self.inputs,
@ -188,10 +189,10 @@ export class UpgradeNg1ComponentAdapterBuilder {
exportedComponents: {[name: string]: UpgradeNg1ComponentAdapterBuilder},
injector: angular.IInjectorService): Promise<angular.ILinkFn[]> {
const promises: Promise<angular.ILinkFn>[] = [];
const compile: angular.ICompileService = injector.get(NG1_COMPILE);
const templateCache: angular.ITemplateCacheService = injector.get(NG1_TEMPLATE_CACHE);
const httpBackend: angular.IHttpBackendService = injector.get(NG1_HTTP_BACKEND);
const $controller: angular.IControllerService = injector.get(NG1_CONTROLLER);
const compile: angular.ICompileService = injector.get($COMPILE);
const templateCache: angular.ITemplateCacheService = injector.get($TEMPLATE_CACHE);
const httpBackend: angular.IHttpBackendService = injector.get($HTTP_BACKEND);
const $controller: angular.IControllerService = injector.get($CONTROLLER);
for (const name in exportedComponents) {
if ((<any>exportedComponents).hasOwnProperty(name)) {
const exportedComponent = exportedComponents[name];

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import * as angular from '../angular_js';
import * as angular from '../common/angular1';
// We have to do a little dance to get the ng1 injector into the module injector.
// We store the ng1 injector so that the provider in the module injector can access it

View File

@ -8,9 +8,9 @@
import {ComponentFactory, ComponentFactoryResolver, Injector, Type} from '@angular/core';
import * as angular from '../angular_js';
import * as angular from '../common/angular1';
import {$INJECTOR, $PARSE, INJECTOR_KEY, REQUIRE_NG_MODEL} from '../common/constants';
import {$INJECTOR, $PARSE, INJECTOR_KEY, REQUIRE_NG1_MODEL} from './constants';
import {DowngradeComponentAdapter} from './downgrade_component_adapter';
let downgradeCount = 0;
@ -77,7 +77,7 @@ export function downgradeComponent(info: /* ComponentInfo */ {
return {
restrict: 'E',
require: ['?^' + INJECTOR_KEY, REQUIRE_NG1_MODEL],
require: ['?^' + INJECTOR_KEY, REQUIRE_NG_MODEL],
link: (scope: angular.IScope, element: angular.IAugmentedJQuery, attrs: angular.IAttributes,
required: any[], transclude: angular.ITranscludeFunction) => {
@ -87,6 +87,7 @@ export function downgradeComponent(info: /* ComponentInfo */ {
}
const ngModel: angular.INgModelController = required[1];
const componentFactoryResolver: ComponentFactoryResolver =
parentInjector.get(ComponentFactoryResolver);
const componentFactory: ComponentFactory<any> =
@ -110,4 +111,4 @@ export function downgradeComponent(info: /* ComponentInfo */ {
directiveFactory.$inject = [$INJECTOR, $PARSE];
return directiveFactory;
}
}

View File

@ -8,11 +8,11 @@
import {ChangeDetectorRef, ComponentFactory, ComponentRef, EventEmitter, Injector, OnChanges, ReflectiveInjector, SimpleChange, SimpleChanges, Type} from '@angular/core';
import * as angular from '../angular_js';
import {hookupNgModel} from '../util';
import * as angular from '../common/angular1';
import {$SCOPE} from '../common/constants';
import {hookupNgModel} from '../common/util';
import {ComponentInfo, PropertyBinding} from './component_info';
import {$SCOPE} from './constants';
const INITIAL_VALUE = {
__UNINITIALIZED__: true

View File

@ -8,11 +8,10 @@
import {DoCheck, ElementRef, EventEmitter, Injector, OnChanges, OnDestroy, OnInit, SimpleChanges} from '@angular/core';
import * as angular from '../angular_js';
import * as angular from '../common/angular1';
import {$COMPILE, $CONTROLLER, $HTTP_BACKEND, $INJECTOR, $SCOPE, $TEMPLATE_CACHE} from '../common/constants';
import {controllerKey} from '../common/util';
import {looseIdentical} from '../facade/lang';
import {controllerKey} from '../util';
import {$COMPILE, $CONTROLLER, $HTTP_BACKEND, $INJECTOR, $SCOPE, $TEMPLATE_CACHE} from './constants';
const REQUIRE_PREFIX_RE = /^(\^\^?)?(\?)?(\^\^?)?/;
const NOT_SUPPORTED: any = 'NOT_SUPPORTED';

View File

@ -8,11 +8,11 @@
import {Injector, NgModule, NgZone, Testability} from '@angular/core';
import * as angular from '../angular_js';
import {controllerKey} from '../util';
import * as angular from '../common/angular1';
import {$$TESTABILITY, $DELEGATE, $INJECTOR, $PROVIDE, $ROOT_SCOPE, INJECTOR_KEY, UPGRADE_MODULE_NAME} from '../common/constants';
import {controllerKey} from '../common/util';
import {angular1Providers, setTempInjectorRef} from './angular1_providers';
import {$$TESTABILITY, $DELEGATE, $INJECTOR, $PROVIDE, $ROOT_SCOPE, INJECTOR_KEY, UPGRADE_MODULE_NAME} from './constants';

View File

@ -1,15 +0,0 @@
/**
* @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
*/
/**
* @module
* @description
* Adapter allowing AngularJS v1 and Angular v2 to run side by side in the same application.
*/
export {UpgradeAdapter, UpgradeAdapterRef} from './upgrade_adapter';
export {VERSION} from './version';

View File

@ -6,8 +6,15 @@
* found in the LICENSE file at https://angular.io/license
*/
export {downgradeComponent} from './src/aot/downgrade_component';
export {downgradeInjectable} from './src/aot/downgrade_injectable';
export {UpgradeComponent} from './src/aot/upgrade_component';
export {UpgradeModule} from './src/aot/upgrade_module';
// This file only reexports content of the `src` folder. Keep it that way.
/**
* @module
* @description
* Entry point for all public APIs of the upgrade/static package, allowing
* Angular 1 and Angular 2+ to run side by side in the same application.
*/
export {downgradeInjectable} from './src/common/downgrade_injectable';
export {downgradeComponent} from './src/static/downgrade_component';
export {UpgradeComponent} from './src/static/upgrade_component';
export {UpgradeModule} from './src/static/upgrade_module';
// This file only re-exports content of the `src` folder. Keep it that way.

View File

@ -6,17 +6,18 @@
* found in the LICENSE file at https://angular.io/license
*/
import {INJECTOR_KEY} from '@angular/upgrade/src/aot/constants';
import {downgradeInjectable} from '@angular/upgrade/src/aot/downgrade_injectable';
import {INJECTOR_KEY} from '@angular/upgrade/src/common/constants';
import {downgradeInjectable} from '@angular/upgrade/src/common/downgrade_injectable';
export function main() {
describe('downgradeInjectable', () => {
it('should return an AngularJS annotated factory for the token', () => {
const factory = downgradeInjectable('someToken');
expect(factory[0]).toEqual(INJECTOR_KEY);
expect(factory[1]).toEqual(jasmine.any(Function));
expect(factory).toEqual(jasmine.any(Function));
expect((factory as any).$inject).toEqual([INJECTOR_KEY]);
const injector = {get: jasmine.createSpy('get').and.returnValue('service value')};
const value = (factory as any)[1](injector);
const value = factory(injector);
expect(injector.get).toHaveBeenCalledWith('someToken');
expect(value).toEqual('service value');
});

View File

@ -0,0 +1,25 @@
/**
* @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 function html(html: string): Element {
// Don't return `body` itself, because using it as a `$rootElement` for ng1
// will attach `$injector` to it and that will affect subsequent tests.
const body = document.body;
body.innerHTML = `<div>${html.trim()}</div>`;
const div = document.body.firstChild as Element;
if (div.childNodes.length === 1 && div.firstChild instanceof HTMLElement) {
return div.firstChild;
}
return div;
}
export function multiTrim(text: string): string {
return text.replace(/\n/g, '').replace(/\s\s+/g, ' ').trim();
}

View File

@ -8,7 +8,7 @@
import {Component} from '@angular/core';
import {describe, expect, it} from '@angular/core/testing/testing_internal';
import {getComponentInfo, parseFields} from '@angular/upgrade/src/metadata';
import {getComponentInfo, parseFields} from '@angular/upgrade/src/dynamic/metadata';
export function main() {
describe('upgrade metadata', () => {

View File

@ -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 '../common/test_helpers';

View File

@ -10,8 +10,9 @@ import {ChangeDetectorRef, Class, Component, EventEmitter, Input, NO_ERRORS_SCHE
import {async, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import * as angular from '@angular/upgrade/src/angular_js';
import {UpgradeAdapter, UpgradeAdapterRef, sortProjectableNodes} from '@angular/upgrade/src/upgrade_adapter';
import * as angular from '@angular/upgrade/src/common/angular1';
import {UpgradeAdapter, UpgradeAdapterRef, sortProjectableNodes} from '@angular/upgrade/src/dynamic/upgrade_adapter';
import {html, multiTrim} from './test_helpers';
export function main() {
describe('adapter: ng1 to ng2', () => {
@ -1923,23 +1924,7 @@ export function main() {
});
}
function multiTrim(text: string): string {
return text.replace(/\n/g, '').replace(/\s{2,}/g, ' ').trim();
}
function html(html: string): Element {
const body = document.body;
body.innerHTML = html;
if (body.childNodes.length == 1 && body.firstChild instanceof HTMLElement) {
return <Element>body.firstChild;
}
return body;
}
function nodes(html: string) {
const element = document.createElement('div');
element.innerHTML = html;
return Array.prototype.slice.call(element.childNodes);
}
return Array.prototype.slice.call(element.childNodes);

View File

@ -6,8 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Ng1Token} from '@angular/upgrade/src/angular_js';
import {compileFactory, injectorFactory, parseFactory, rootScopeFactory, setTempInjectorRef} from '@angular/upgrade/src/aot/angular1_providers';
import {Ng1Token} from '@angular/upgrade/src/common/angular1';
import {compileFactory, injectorFactory, parseFactory, rootScopeFactory, setTempInjectorRef} from '@angular/upgrade/src/static/angular1_providers';
export function main() {
describe('upgrade angular1_providers', () => {
@ -55,4 +55,4 @@ export function main() {
});
});
});
}
}

View File

@ -10,7 +10,7 @@ import {Component, Directive, ElementRef, Injector, Input, NgModule, NgZone, Sim
import {async} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import * as angular from '@angular/upgrade/src/angular_js';
import * as angular from '@angular/upgrade/src/common/angular1';
import {UpgradeComponent, UpgradeModule, downgradeComponent} from '@angular/upgrade/static';
import {bootstrap, html} from '../test_helpers';

View File

@ -10,7 +10,7 @@ import {Component, Directive, ElementRef, Injector, NgModule, destroyPlatform} f
import {async} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import * as angular from '@angular/upgrade/src/angular_js';
import * as angular from '@angular/upgrade/src/common/angular1';
import {UpgradeComponent, UpgradeModule, downgradeComponent} from '@angular/upgrade/static';
import {bootstrap, html} from '../test_helpers';

View File

@ -10,7 +10,7 @@ import {Component, EventEmitter, NgModule, OnChanges, OnDestroy, SimpleChanges,
import {async} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import * as angular from '@angular/upgrade/src/angular_js';
import * as angular from '@angular/upgrade/src/common/angular1';
import {UpgradeModule, downgradeComponent} from '@angular/upgrade/static';
import {bootstrap, html, multiTrim} from '../test_helpers';

View File

@ -10,7 +10,7 @@ import {Component, Directive, ElementRef, Injector, Input, NgModule, destroyPlat
import {async} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import * as angular from '@angular/upgrade/src/angular_js';
import * as angular from '@angular/upgrade/src/common/angular1';
import {UpgradeComponent, UpgradeModule, downgradeComponent} from '@angular/upgrade/static';
import {bootstrap, html, multiTrim} from '../test_helpers';

View File

@ -10,8 +10,8 @@ import {InjectionToken, Injector, NgModule, destroyPlatform} from '@angular/core
import {async} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import * as angular from '@angular/upgrade/src/angular_js';
import {$INJECTOR, INJECTOR_KEY} from '@angular/upgrade/src/aot/constants';
import * as angular from '@angular/upgrade/src/common/angular1';
import {$INJECTOR, INJECTOR_KEY} from '@angular/upgrade/src/common/constants';
import {UpgradeModule, downgradeInjectable} from '@angular/upgrade/static';
import {bootstrap, html} from '../test_helpers';

View File

@ -11,7 +11,7 @@ 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';
import * as angular from '@angular/upgrade/src/angular_js';
import * as angular from '@angular/upgrade/src/common/angular1';
import {UpgradeModule} from '@angular/upgrade/static';
import {bootstrap, html} from '../test_helpers';

View File

@ -10,7 +10,7 @@ import {Component, Directive, ElementRef, EventEmitter, Injector, Input, NO_ERRO
import {async, fakeAsync, tick} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import * as angular from '@angular/upgrade/src/angular_js';
import * as angular from '@angular/upgrade/src/common/angular1';
import {UpgradeComponent, UpgradeModule, downgradeComponent} from '@angular/upgrade/static';
import {bootstrap, digest, html, multiTrim} from '../test_helpers';

View File

@ -5,11 +5,14 @@
* 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 {PlatformRef, Type} from '@angular/core';
import * as angular from '@angular/upgrade/src/angular_js';
import {$ROOT_SCOPE} from '@angular/upgrade/src/aot/constants';
import * as angular from '@angular/upgrade/src/common/angular1';
import {$ROOT_SCOPE} from '@angular/upgrade/src/common/constants';
import {UpgradeModule} from '@angular/upgrade/static';
export * from '../common/test_helpers';
export function bootstrap(
platform: PlatformRef, Ng2Module: Type<{}>, element: Element, ng1Module: angular.IModule) {
// We bootstrap the Angular module first; then when it is ready (async)
@ -25,21 +28,3 @@ export function digest(adapter: UpgradeModule) {
const $rootScope = adapter.$injector.get($ROOT_SCOPE) as angular.IRootScopeService;
$rootScope.$digest();
}
export function html(html: string): Element {
// Don't return `body` itself, because using it as a `$rootElement` for ng1
// will attach `$injector` to it and that will affect subsequent tests.
const body = document.body;
body.innerHTML = `<div>${html.trim()}</div>`;
const div = document.body.firstChild as Element;
if (div.childNodes.length === 1 && div.firstChild instanceof HTMLElement) {
return div.firstChild;
}
return div;
}
export function multiTrim(text: string): string {
return text.replace(/\n/g, '').replace(/\s\s+/g, ' ').trim();
}

View File

@ -6,7 +6,7 @@ export declare function downgradeComponent(info: {
}): any;
/** @experimental */
export declare function downgradeInjectable(token: any): (string | ((i: Injector) => any))[];
export declare function downgradeInjectable(token: any): Function;
/** @experimental */
export declare class UpgradeComponent implements OnInit, OnChanges, DoCheck, OnDestroy {