parent
130ae158c4
commit
145121a75d
|
@ -7,7 +7,6 @@
|
||||||
*/
|
*/
|
||||||
import {Compiler, Component, ComponentFactory, Injector, NgModule, TestabilityRegistry} from '@angular/core';
|
import {Compiler, Component, ComponentFactory, Injector, NgModule, TestabilityRegistry} from '@angular/core';
|
||||||
import {TestBed} from '@angular/core/testing';
|
import {TestBed} from '@angular/core/testing';
|
||||||
import {fixmeIvy} from '@angular/private/testing';
|
|
||||||
import * as angular from '@angular/upgrade/src/common/angular1';
|
import * as angular from '@angular/upgrade/src/common/angular1';
|
||||||
import {DowngradeComponentAdapter, groupNodesBySelector} from '@angular/upgrade/src/common/downgrade_component_adapter';
|
import {DowngradeComponentAdapter, groupNodesBySelector} from '@angular/upgrade/src/common/downgrade_component_adapter';
|
||||||
|
|
||||||
|
|
|
@ -1681,52 +1681,51 @@ withEachNg1Version(() => {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
fixmeIvy('unknown') &&
|
it('should not call `$onInit()` on scope', async(() => {
|
||||||
it('should not call `$onInit()` on scope', async(() => {
|
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
|
||||||
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
|
const $onInitSpy = jasmine.createSpy('$onInit');
|
||||||
const $onInitSpy = jasmine.createSpy('$onInit');
|
|
||||||
|
|
||||||
@Component({selector: 'ng2', template: '<ng1-a></ng1-a> | <ng1-b></ng1-b>'})
|
@Component({selector: 'ng2', template: '<ng1-a></ng1-a> | <ng1-b></ng1-b>'})
|
||||||
class Ng2Component {
|
class Ng2Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
angular.module('ng1', [])
|
angular.module('ng1', [])
|
||||||
.directive('ng1A', () => ({
|
.directive('ng1A', () => ({
|
||||||
template: '',
|
template: '',
|
||||||
scope: {},
|
scope: {},
|
||||||
bindToController: true,
|
bindToController: true,
|
||||||
controllerAs: '$ctrl',
|
controllerAs: '$ctrl',
|
||||||
controller: function($scope: angular.IScope) {
|
controller: function($scope: angular.IScope) {
|
||||||
Object.getPrototypeOf($scope).$onInit = $onInitSpy;
|
Object.getPrototypeOf($scope).$onInit = $onInitSpy;
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.directive('ng1B', () => ({
|
.directive('ng1B', () => ({
|
||||||
template: '',
|
template: '',
|
||||||
scope: {},
|
scope: {},
|
||||||
bindToController: false,
|
bindToController: false,
|
||||||
controllerAs: '$ctrl',
|
controllerAs: '$ctrl',
|
||||||
controller: function($scope: angular.IScope) {
|
controller: function($scope: angular.IScope) {
|
||||||
$scope['$onInit'] = $onInitSpy;
|
$scope['$onInit'] = $onInitSpy;
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.directive('ng2', adapter.downgradeNg2Component(Ng2Component));
|
.directive('ng2', adapter.downgradeNg2Component(Ng2Component));
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'),
|
adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'),
|
||||||
Ng2Component
|
Ng2Component
|
||||||
],
|
],
|
||||||
imports: [BrowserModule],
|
imports: [BrowserModule],
|
||||||
})
|
})
|
||||||
class Ng2Module {
|
class Ng2Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
const element = html(`<div><ng2></ng2></div>`);
|
const element = html(`<div><ng2></ng2></div>`);
|
||||||
adapter.bootstrap(element, ['ng1']).ready((ref) => {
|
adapter.bootstrap(element, ['ng1']).ready((ref) => {
|
||||||
expect($onInitSpy).not.toHaveBeenCalled();
|
expect($onInitSpy).not.toHaveBeenCalled();
|
||||||
ref.dispose();
|
ref.dispose();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
fixmeIvy('unknown') &&
|
fixmeIvy('unknown') &&
|
||||||
it('should call `$doCheck()` on controller', async(() => {
|
it('should call `$doCheck()` on controller', async(() => {
|
||||||
|
@ -1783,61 +1782,60 @@ withEachNg1Version(() => {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
fixmeIvy('unknown') &&
|
it('should not call `$doCheck()` on scope', async(() => {
|
||||||
it('should not call `$doCheck()` on scope', async(() => {
|
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
|
||||||
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
|
const $doCheckSpyA = jasmine.createSpy('$doCheckA');
|
||||||
const $doCheckSpyA = jasmine.createSpy('$doCheckA');
|
const $doCheckSpyB = jasmine.createSpy('$doCheckB');
|
||||||
const $doCheckSpyB = jasmine.createSpy('$doCheckB');
|
let changeDetector: ChangeDetectorRef;
|
||||||
let changeDetector: ChangeDetectorRef;
|
|
||||||
|
|
||||||
@Component({selector: 'ng2', template: '<ng1-a></ng1-a> | <ng1-b></ng1-b>'})
|
@Component({selector: 'ng2', template: '<ng1-a></ng1-a> | <ng1-b></ng1-b>'})
|
||||||
class Ng2Component {
|
class Ng2Component {
|
||||||
constructor(cd: ChangeDetectorRef) { changeDetector = cd; }
|
constructor(cd: ChangeDetectorRef) { changeDetector = cd; }
|
||||||
}
|
}
|
||||||
|
|
||||||
angular.module('ng1', [])
|
angular.module('ng1', [])
|
||||||
.directive('ng1A', () => ({
|
.directive('ng1A', () => ({
|
||||||
template: '',
|
template: '',
|
||||||
scope: {},
|
scope: {},
|
||||||
bindToController: true,
|
bindToController: true,
|
||||||
controllerAs: '$ctrl',
|
controllerAs: '$ctrl',
|
||||||
controller: function($scope: angular.IScope) {
|
controller: function($scope: angular.IScope) {
|
||||||
Object.getPrototypeOf($scope).$doCheck = $doCheckSpyA;
|
Object.getPrototypeOf($scope).$doCheck = $doCheckSpyA;
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.directive('ng1B', () => ({
|
.directive('ng1B', () => ({
|
||||||
template: '',
|
template: '',
|
||||||
scope: {},
|
scope: {},
|
||||||
bindToController: false,
|
bindToController: false,
|
||||||
controllerAs: '$ctrl',
|
controllerAs: '$ctrl',
|
||||||
controller: function($scope: angular.IScope) {
|
controller: function($scope: angular.IScope) {
|
||||||
$scope['$doCheck'] = $doCheckSpyB;
|
$scope['$doCheck'] = $doCheckSpyB;
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.directive('ng2', adapter.downgradeNg2Component(Ng2Component));
|
.directive('ng2', adapter.downgradeNg2Component(Ng2Component));
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'),
|
adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'),
|
||||||
Ng2Component
|
Ng2Component
|
||||||
],
|
],
|
||||||
imports: [BrowserModule],
|
imports: [BrowserModule],
|
||||||
})
|
})
|
||||||
class Ng2Module {
|
class Ng2Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
const element = html(`<div><ng2></ng2></div>`);
|
const element = html(`<div><ng2></ng2></div>`);
|
||||||
adapter.bootstrap(element, ['ng1']).ready((ref) => {
|
adapter.bootstrap(element, ['ng1']).ready((ref) => {
|
||||||
$doCheckSpyA.calls.reset();
|
$doCheckSpyA.calls.reset();
|
||||||
$doCheckSpyB.calls.reset();
|
$doCheckSpyB.calls.reset();
|
||||||
changeDetector.detectChanges();
|
changeDetector.detectChanges();
|
||||||
|
|
||||||
expect($doCheckSpyA).not.toHaveBeenCalled();
|
expect($doCheckSpyA).not.toHaveBeenCalled();
|
||||||
expect($doCheckSpyB).not.toHaveBeenCalled();
|
expect($doCheckSpyB).not.toHaveBeenCalled();
|
||||||
|
|
||||||
ref.dispose();
|
ref.dispose();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
fixmeIvy('unknown') &&
|
fixmeIvy('unknown') &&
|
||||||
it('should call `$postLink()` on controller', async(() => {
|
it('should call `$postLink()` on controller', async(() => {
|
||||||
|
@ -1885,52 +1883,51 @@ withEachNg1Version(() => {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
fixmeIvy('unknown') &&
|
it('should not call `$postLink()` on scope', async(() => {
|
||||||
it('should not call `$postLink()` on scope', async(() => {
|
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
|
||||||
const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
|
const $postLinkSpy = jasmine.createSpy('$postLink');
|
||||||
const $postLinkSpy = jasmine.createSpy('$postLink');
|
|
||||||
|
|
||||||
@Component({selector: 'ng2', template: '<ng1-a></ng1-a> | <ng1-b></ng1-b>'})
|
@Component({selector: 'ng2', template: '<ng1-a></ng1-a> | <ng1-b></ng1-b>'})
|
||||||
class Ng2Component {
|
class Ng2Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
angular.module('ng1', [])
|
angular.module('ng1', [])
|
||||||
.directive('ng1A', () => ({
|
.directive('ng1A', () => ({
|
||||||
template: '',
|
template: '',
|
||||||
scope: {},
|
scope: {},
|
||||||
bindToController: true,
|
bindToController: true,
|
||||||
controllerAs: '$ctrl',
|
controllerAs: '$ctrl',
|
||||||
controller: function($scope: angular.IScope) {
|
controller: function($scope: angular.IScope) {
|
||||||
Object.getPrototypeOf($scope).$postLink = $postLinkSpy;
|
Object.getPrototypeOf($scope).$postLink = $postLinkSpy;
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.directive('ng1B', () => ({
|
.directive('ng1B', () => ({
|
||||||
template: '',
|
template: '',
|
||||||
scope: {},
|
scope: {},
|
||||||
bindToController: false,
|
bindToController: false,
|
||||||
controllerAs: '$ctrl',
|
controllerAs: '$ctrl',
|
||||||
controller: function($scope: angular.IScope) {
|
controller: function($scope: angular.IScope) {
|
||||||
$scope['$postLink'] = $postLinkSpy;
|
$scope['$postLink'] = $postLinkSpy;
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.directive('ng2', adapter.downgradeNg2Component(Ng2Component));
|
.directive('ng2', adapter.downgradeNg2Component(Ng2Component));
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'),
|
adapter.upgradeNg1Component('ng1A'), adapter.upgradeNg1Component('ng1B'),
|
||||||
Ng2Component
|
Ng2Component
|
||||||
],
|
],
|
||||||
imports: [BrowserModule],
|
imports: [BrowserModule],
|
||||||
})
|
})
|
||||||
class Ng2Module {
|
class Ng2Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
const element = html(`<div><ng2></ng2></div>`);
|
const element = html(`<div><ng2></ng2></div>`);
|
||||||
adapter.bootstrap(element, ['ng1']).ready((ref) => {
|
adapter.bootstrap(element, ['ng1']).ready((ref) => {
|
||||||
expect($postLinkSpy).not.toHaveBeenCalled();
|
expect($postLinkSpy).not.toHaveBeenCalled();
|
||||||
ref.dispose();
|
ref.dispose();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
fixmeIvy('unknown') &&
|
fixmeIvy('unknown') &&
|
||||||
it('should call `$onChanges()` on binding destination', fakeAsync(() => {
|
it('should call `$onChanges()` on binding destination', fakeAsync(() => {
|
||||||
|
|
|
@ -520,96 +520,94 @@ withEachNg1Version(() => {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') &&
|
it('should properly run cleanup when ng1 directive is destroyed', async(() => {
|
||||||
it('should properly run cleanup when ng1 directive is destroyed', async(() => {
|
|
||||||
|
|
||||||
let destroyed = false;
|
let destroyed = false;
|
||||||
@Component({selector: 'ng2', template: 'test'})
|
@Component({selector: 'ng2', template: 'test'})
|
||||||
class Ng2Component implements OnDestroy {
|
class Ng2Component implements OnDestroy {
|
||||||
ngOnDestroy() { destroyed = true; }
|
ngOnDestroy() { destroyed = true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [Ng2Component],
|
declarations: [Ng2Component],
|
||||||
entryComponents: [Ng2Component],
|
entryComponents: [Ng2Component],
|
||||||
imports: [BrowserModule, UpgradeModule]
|
imports: [BrowserModule, UpgradeModule]
|
||||||
})
|
})
|
||||||
class Ng2Module {
|
class Ng2Module {
|
||||||
ngDoBootstrap() {}
|
ngDoBootstrap() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ng1Module =
|
const ng1Module =
|
||||||
angular.module('ng1', [])
|
angular.module('ng1', [])
|
||||||
.directive(
|
.directive(
|
||||||
'ng1',
|
'ng1',
|
||||||
() => { return {template: '<div ng-if="!destroyIt"><ng2></ng2></div>'}; })
|
() => { return {template: '<div ng-if="!destroyIt"><ng2></ng2></div>'}; })
|
||||||
.directive('ng2', downgradeComponent({component: Ng2Component}));
|
.directive('ng2', downgradeComponent({component: Ng2Component}));
|
||||||
const element = html('<ng1></ng1>');
|
const element = html('<ng1></ng1>');
|
||||||
platformBrowserDynamic().bootstrapModule(Ng2Module).then((ref) => {
|
platformBrowserDynamic().bootstrapModule(Ng2Module).then((ref) => {
|
||||||
const adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
|
const adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
|
||||||
adapter.bootstrap(element, [ng1Module.name]);
|
adapter.bootstrap(element, [ng1Module.name]);
|
||||||
expect(element.textContent).toContain('test');
|
expect(element.textContent).toContain('test');
|
||||||
expect(destroyed).toBe(false);
|
expect(destroyed).toBe(false);
|
||||||
|
|
||||||
const $rootScope = adapter.$injector.get('$rootScope');
|
const $rootScope = adapter.$injector.get('$rootScope');
|
||||||
$rootScope.$apply('destroyIt = true');
|
$rootScope.$apply('destroyIt = true');
|
||||||
|
|
||||||
expect(element.textContent).not.toContain('test');
|
expect(element.textContent).not.toContain('test');
|
||||||
expect(destroyed).toBe(true);
|
expect(destroyed).toBe(true);
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
fixmeIvy('FW-642: ASSERTION ERROR: Slot should have been initialized to NO_CHANGE') &&
|
it('should properly run cleanup with multiple levels of nesting', async(() => {
|
||||||
it('should properly run cleanup with multiple levels of nesting', async(() => {
|
let destroyed = false;
|
||||||
let destroyed = false;
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ng2-outer',
|
selector: 'ng2-outer',
|
||||||
template: '<div *ngIf="!destroyIt"><ng1></ng1></div>',
|
template: '<div *ngIf="!destroyIt"><ng1></ng1></div>',
|
||||||
})
|
})
|
||||||
class Ng2OuterComponent {
|
class Ng2OuterComponent {
|
||||||
@Input() destroyIt = false;
|
@Input() destroyIt = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({selector: 'ng2-inner', template: 'test'})
|
@Component({selector: 'ng2-inner', template: 'test'})
|
||||||
class Ng2InnerComponent implements OnDestroy {
|
class Ng2InnerComponent implements OnDestroy {
|
||||||
ngOnDestroy() { destroyed = true; }
|
ngOnDestroy() { destroyed = true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Directive({selector: 'ng1'})
|
@Directive({selector: 'ng1'})
|
||||||
class Ng1ComponentFacade extends UpgradeComponent {
|
class Ng1ComponentFacade extends UpgradeComponent {
|
||||||
constructor(elementRef: ElementRef, injector: Injector) {
|
constructor(elementRef: ElementRef, injector: Injector) {
|
||||||
super('ng1', elementRef, injector);
|
super('ng1', elementRef, injector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [BrowserModule, UpgradeModule],
|
imports: [BrowserModule, UpgradeModule],
|
||||||
declarations: [Ng1ComponentFacade, Ng2InnerComponent, Ng2OuterComponent],
|
declarations: [Ng1ComponentFacade, Ng2InnerComponent, Ng2OuterComponent],
|
||||||
entryComponents: [Ng2InnerComponent, Ng2OuterComponent],
|
entryComponents: [Ng2InnerComponent, Ng2OuterComponent],
|
||||||
})
|
})
|
||||||
class Ng2Module {
|
class Ng2Module {
|
||||||
ngDoBootstrap() {}
|
ngDoBootstrap() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ng1Module =
|
const ng1Module =
|
||||||
angular.module('ng1', [])
|
angular.module('ng1', [])
|
||||||
.directive('ng1', () => ({template: '<ng2-inner></ng2-inner>'}))
|
.directive('ng1', () => ({template: '<ng2-inner></ng2-inner>'}))
|
||||||
.directive('ng2Inner', downgradeComponent({component: Ng2InnerComponent}))
|
.directive('ng2Inner', downgradeComponent({component: Ng2InnerComponent}))
|
||||||
.directive('ng2Outer', downgradeComponent({component: Ng2OuterComponent}));
|
.directive('ng2Outer', downgradeComponent({component: Ng2OuterComponent}));
|
||||||
|
|
||||||
const element = html('<ng2-outer [destroy-it]="destroyIt"></ng2-outer>');
|
const element = html('<ng2-outer [destroy-it]="destroyIt"></ng2-outer>');
|
||||||
|
|
||||||
bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(upgrade => {
|
bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(upgrade => {
|
||||||
expect(element.textContent).toBe('test');
|
expect(element.textContent).toBe('test');
|
||||||
expect(destroyed).toBe(false);
|
expect(destroyed).toBe(false);
|
||||||
|
|
||||||
$apply(upgrade, 'destroyIt = true');
|
$apply(upgrade, 'destroyIt = true');
|
||||||
|
|
||||||
expect(element.textContent).toBe('');
|
expect(element.textContent).toBe('');
|
||||||
expect(destroyed).toBe(true);
|
expect(destroyed).toBe(true);
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should work when compiled outside the dom (by fallback to the root ng2.injector)',
|
it('should work when compiled outside the dom (by fallback to the root ng2.injector)',
|
||||||
async(() => {
|
async(() => {
|
||||||
|
@ -743,7 +741,7 @@ withEachNg1Version(() => {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
fixmeIvy('FW-561: Runtime compiler is not loaded') &&
|
fixmeIvy('FW-717: Browser locks up and disconnects') &&
|
||||||
it('should work with ng2 lazy loaded components', async(() => {
|
it('should work with ng2 lazy loaded components', async(() => {
|
||||||
|
|
||||||
let componentInjector: Injector;
|
let componentInjector: Injector;
|
||||||
|
|
|
@ -225,42 +225,41 @@ withEachNg1Version(() => {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
fixmeIvy('FW-713: ngDestroy not being called when downgraded ng2 component is destroyed') &&
|
it('should destroy components inside the Angular zone', async(() => {
|
||||||
it('should destroy components inside the Angular zone', async(() => {
|
let destroyedInTheZone = false;
|
||||||
let destroyedInTheZone = false;
|
|
||||||
|
|
||||||
@Component({selector: 'ng2', template: ''})
|
@Component({selector: 'ng2', template: ''})
|
||||||
class Ng2Component implements OnDestroy {
|
class Ng2Component implements OnDestroy {
|
||||||
ngOnDestroy() { destroyedInTheZone = NgZone.isInAngularZone(); }
|
ngOnDestroy() { destroyedInTheZone = NgZone.isInAngularZone(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [Ng2Component],
|
declarations: [Ng2Component],
|
||||||
entryComponents: [Ng2Component],
|
entryComponents: [Ng2Component],
|
||||||
imports: [BrowserModule],
|
imports: [BrowserModule],
|
||||||
})
|
})
|
||||||
class Ng2Module {
|
class Ng2Module {
|
||||||
ngDoBootstrap() {}
|
ngDoBootstrap() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bootstrapFn = (extraProviders: StaticProvider[]) =>
|
const bootstrapFn = (extraProviders: StaticProvider[]) =>
|
||||||
platformBrowserDynamic(extraProviders).bootstrapModule(Ng2Module);
|
platformBrowserDynamic(extraProviders).bootstrapModule(Ng2Module);
|
||||||
const lazyModuleName = downgradeModule<Ng2Module>(bootstrapFn);
|
const lazyModuleName = downgradeModule<Ng2Module>(bootstrapFn);
|
||||||
const ng1Module =
|
const ng1Module =
|
||||||
angular.module('ng1', [lazyModuleName])
|
angular.module('ng1', [lazyModuleName])
|
||||||
.directive(
|
.directive(
|
||||||
'ng2', downgradeComponent({component: Ng2Component, propagateDigest}));
|
'ng2', downgradeComponent({component: Ng2Component, propagateDigest}));
|
||||||
|
|
||||||
const element = html('<ng2 ng-if="!hideNg2"></ng2>');
|
const element = html('<ng2 ng-if="!hideNg2"></ng2>');
|
||||||
const $injector = angular.bootstrap(element, [ng1Module.name]);
|
const $injector = angular.bootstrap(element, [ng1Module.name]);
|
||||||
const $rootScope = $injector.get($ROOT_SCOPE) as angular.IRootScopeService;
|
const $rootScope = $injector.get($ROOT_SCOPE) as angular.IRootScopeService;
|
||||||
|
|
||||||
// Wait for the module to be bootstrapped.
|
// Wait for the module to be bootstrapped.
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$rootScope.$apply('hideNg2 = true');
|
$rootScope.$apply('hideNg2 = true');
|
||||||
expect(destroyedInTheZone).toBe(true);
|
expect(destroyedInTheZone).toBe(true);
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') &&
|
fixmeIvy('FW-715: ngOnChanges being called a second time unexpectedly') &&
|
||||||
it('should propagate input changes inside the Angular zone', async(() => {
|
it('should propagate input changes inside the Angular zone', async(() => {
|
||||||
|
@ -526,54 +525,53 @@ withEachNg1Version(() => {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
fixmeIvy('FW-717: Browser locks up and disconnects') &&
|
it('should detach hostViews from the ApplicationRef once destroyed', async(() => {
|
||||||
it('should detach hostViews from the ApplicationRef once destroyed', async(() => {
|
let ng2Component: Ng2Component;
|
||||||
let ng2Component: Ng2Component;
|
|
||||||
|
|
||||||
@Component({selector: 'ng2', template: ''})
|
@Component({selector: 'ng2', template: ''})
|
||||||
class Ng2Component {
|
class Ng2Component {
|
||||||
constructor(public appRef: ApplicationRef) {
|
constructor(public appRef: ApplicationRef) {
|
||||||
ng2Component = this;
|
ng2Component = this;
|
||||||
spyOn(appRef, 'attachView').and.callThrough();
|
spyOn(appRef, 'attachView').and.callThrough();
|
||||||
spyOn(appRef, 'detachView').and.callThrough();
|
spyOn(appRef, 'detachView').and.callThrough();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [Ng2Component],
|
declarations: [Ng2Component],
|
||||||
entryComponents: [Ng2Component],
|
entryComponents: [Ng2Component],
|
||||||
imports: [BrowserModule],
|
imports: [BrowserModule],
|
||||||
})
|
})
|
||||||
class Ng2Module {
|
class Ng2Module {
|
||||||
ngDoBootstrap() {}
|
ngDoBootstrap() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bootstrapFn = (extraProviders: StaticProvider[]) =>
|
const bootstrapFn = (extraProviders: StaticProvider[]) =>
|
||||||
platformBrowserDynamic(extraProviders).bootstrapModule(Ng2Module);
|
platformBrowserDynamic(extraProviders).bootstrapModule(Ng2Module);
|
||||||
const lazyModuleName = downgradeModule<Ng2Module>(bootstrapFn);
|
const lazyModuleName = downgradeModule<Ng2Module>(bootstrapFn);
|
||||||
const ng1Module =
|
const ng1Module =
|
||||||
angular.module('ng1', [lazyModuleName])
|
angular.module('ng1', [lazyModuleName])
|
||||||
.directive(
|
.directive(
|
||||||
'ng2', downgradeComponent({component: Ng2Component, propagateDigest}));
|
'ng2', downgradeComponent({component: Ng2Component, propagateDigest}));
|
||||||
|
|
||||||
const element = html('<ng2 ng-if="!hideNg2"></ng2>');
|
const element = html('<ng2 ng-if="!hideNg2"></ng2>');
|
||||||
const $injector = angular.bootstrap(element, [ng1Module.name]);
|
const $injector = angular.bootstrap(element, [ng1Module.name]);
|
||||||
const $rootScope = $injector.get($ROOT_SCOPE) as angular.IRootScopeService;
|
const $rootScope = $injector.get($ROOT_SCOPE) as angular.IRootScopeService;
|
||||||
|
|
||||||
setTimeout(() => { // Wait for the module to be bootstrapped.
|
setTimeout(() => { // Wait for the module to be bootstrapped.
|
||||||
setTimeout(() => { // Wait for the hostView to be attached (during the `$digest`).
|
setTimeout(() => { // Wait for the hostView to be attached (during the `$digest`).
|
||||||
const hostView: ViewRef =
|
const hostView: ViewRef =
|
||||||
(ng2Component.appRef.attachView as jasmine.Spy).calls.mostRecent().args[0];
|
(ng2Component.appRef.attachView as jasmine.Spy).calls.mostRecent().args[0];
|
||||||
|
|
||||||
expect(hostView.destroyed).toBe(false);
|
expect(hostView.destroyed).toBe(false);
|
||||||
|
|
||||||
$rootScope.$apply('hideNg2 = true');
|
$rootScope.$apply('hideNg2 = true');
|
||||||
|
|
||||||
expect(hostView.destroyed).toBe(true);
|
expect(hostView.destroyed).toBe(true);
|
||||||
expect(ng2Component.appRef.detachView).toHaveBeenCalledWith(hostView);
|
expect(ng2Component.appRef.detachView).toHaveBeenCalledWith(hostView);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should only retrieve the Angular zone once (and cache it for later use)',
|
it('should only retrieve the Angular zone once (and cache it for later use)',
|
||||||
fakeAsync(() => {
|
fakeAsync(() => {
|
||||||
|
|
|
@ -3965,23 +3965,22 @@ withEachNg1Version(() => {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
fixmeIvy('FW-642: ASSERTION ERROR: Slot should have been initialized to NO_CHANGE') &&
|
it('should support ng2 > ng1 > ng2 (with inputs/outputs)', fakeAsync(() => {
|
||||||
it('should support ng2 > ng1 > ng2 (with inputs/outputs)', fakeAsync(() => {
|
let ng2ComponentAInstance: Ng2ComponentA;
|
||||||
let ng2ComponentAInstance: Ng2ComponentA;
|
let ng2ComponentBInstance: Ng2ComponentB;
|
||||||
let ng2ComponentBInstance: Ng2ComponentB;
|
let ng1ControllerXInstance: Ng1ControllerX;
|
||||||
let ng1ControllerXInstance: Ng1ControllerX;
|
|
||||||
|
|
||||||
// Define `ng1Component`
|
// Define `ng1Component`
|
||||||
class Ng1ControllerX {
|
class Ng1ControllerX {
|
||||||
// TODO(issue/24571): remove '!'.
|
// TODO(issue/24571): remove '!'.
|
||||||
ng1XInputA !: string;
|
ng1XInputA !: string;
|
||||||
ng1XInputB: any;
|
ng1XInputB: any;
|
||||||
ng1XInputC: any;
|
ng1XInputC: any;
|
||||||
|
|
||||||
constructor() { ng1ControllerXInstance = this; }
|
constructor() { ng1ControllerXInstance = this; }
|
||||||
}
|
}
|
||||||
const ng1Component: angular.IComponent = {
|
const ng1Component: angular.IComponent = {
|
||||||
template: `
|
template: `
|
||||||
ng1X({{ $ctrl.ng1XInputA }}, {{ $ctrl.ng1XInputB.value }}, {{ $ctrl.ng1XInputC.value }}) |
|
ng1X({{ $ctrl.ng1XInputA }}, {{ $ctrl.ng1XInputB.value }}, {{ $ctrl.ng1XInputC.value }}) |
|
||||||
<ng2-b
|
<ng2-b
|
||||||
[ng2-b-input1]="$ctrl.ng1XInputA"
|
[ng2-b-input1]="$ctrl.ng1XInputA"
|
||||||
|
@ -3989,39 +3988,39 @@ withEachNg1Version(() => {
|
||||||
(ng2-b-output-c)="$ctrl.ng1XInputC = {value: $event}">
|
(ng2-b-output-c)="$ctrl.ng1XInputC = {value: $event}">
|
||||||
</ng2-b>
|
</ng2-b>
|
||||||
`,
|
`,
|
||||||
bindings: {
|
bindings: {
|
||||||
ng1XInputA: '@',
|
ng1XInputA: '@',
|
||||||
ng1XInputB: '<',
|
ng1XInputB: '<',
|
||||||
ng1XInputC: '=',
|
ng1XInputC: '=',
|
||||||
ng1XOutputA: '&',
|
ng1XOutputA: '&',
|
||||||
ng1XOutputB: '&'
|
ng1XOutputB: '&'
|
||||||
},
|
},
|
||||||
controller: Ng1ControllerX
|
controller: Ng1ControllerX
|
||||||
};
|
};
|
||||||
|
|
||||||
// Define `Ng1ComponentFacade`
|
// Define `Ng1ComponentFacade`
|
||||||
@Directive({selector: 'ng1X'})
|
@Directive({selector: 'ng1X'})
|
||||||
class Ng1ComponentXFacade extends UpgradeComponent {
|
class Ng1ComponentXFacade extends UpgradeComponent {
|
||||||
// TODO(issue/24571): remove '!'.
|
// TODO(issue/24571): remove '!'.
|
||||||
@Input() ng1XInputA !: string;
|
@Input() ng1XInputA !: string;
|
||||||
@Input() ng1XInputB: any;
|
@Input() ng1XInputB: any;
|
||||||
@Input() ng1XInputC: any;
|
@Input() ng1XInputC: any;
|
||||||
// TODO(issue/24571): remove '!'.
|
// TODO(issue/24571): remove '!'.
|
||||||
@Output() ng1XInputCChange !: EventEmitter<any>;
|
@Output() ng1XInputCChange !: EventEmitter<any>;
|
||||||
// TODO(issue/24571): remove '!'.
|
// TODO(issue/24571): remove '!'.
|
||||||
@Output() ng1XOutputA !: EventEmitter<any>;
|
@Output() ng1XOutputA !: EventEmitter<any>;
|
||||||
// TODO(issue/24571): remove '!'.
|
// TODO(issue/24571): remove '!'.
|
||||||
@Output() ng1XOutputB !: EventEmitter<any>;
|
@Output() ng1XOutputB !: EventEmitter<any>;
|
||||||
|
|
||||||
constructor(elementRef: ElementRef, injector: Injector) {
|
constructor(elementRef: ElementRef, injector: Injector) {
|
||||||
super('ng1X', elementRef, injector);
|
super('ng1X', elementRef, injector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define `Ng2Component`
|
// Define `Ng2Component`
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ng2-a',
|
selector: 'ng2-a',
|
||||||
template: `
|
template: `
|
||||||
ng2A({{ ng2ADataA.value }}, {{ ng2ADataB.value }}, {{ ng2ADataC.value }}) |
|
ng2A({{ ng2ADataA.value }}, {{ ng2ADataB.value }}, {{ ng2ADataC.value }}) |
|
||||||
<ng1X
|
<ng1X
|
||||||
ng1XInputA="{{ ng2ADataA.value }}"
|
ng1XInputA="{{ ng2ADataA.value }}"
|
||||||
|
@ -4031,131 +4030,130 @@ withEachNg1Version(() => {
|
||||||
on-ng1XOutputB="ng2ADataB.value = $event">
|
on-ng1XOutputB="ng2ADataB.value = $event">
|
||||||
</ng1X>
|
</ng1X>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
class Ng2ComponentA {
|
class Ng2ComponentA {
|
||||||
ng2ADataA = {value: 'foo'};
|
ng2ADataA = {value: 'foo'};
|
||||||
ng2ADataB = {value: 'bar'};
|
ng2ADataB = {value: 'bar'};
|
||||||
ng2ADataC = {value: 'baz'};
|
ng2ADataC = {value: 'baz'};
|
||||||
|
|
||||||
constructor() { ng2ComponentAInstance = this; }
|
constructor() { ng2ComponentAInstance = this; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({selector: 'ng2-b', template: 'ng2B({{ ng2BInputA }}, {{ ng2BInputC }})'})
|
@Component({selector: 'ng2-b', template: 'ng2B({{ ng2BInputA }}, {{ ng2BInputC }})'})
|
||||||
class Ng2ComponentB {
|
class Ng2ComponentB {
|
||||||
@Input('ng2BInput1') ng2BInputA: any;
|
@Input('ng2BInput1') ng2BInputA: any;
|
||||||
@Input() ng2BInputC: any;
|
@Input() ng2BInputC: any;
|
||||||
@Output() ng2BOutputC = new EventEmitter();
|
@Output() ng2BOutputC = new EventEmitter();
|
||||||
|
|
||||||
constructor() { ng2ComponentBInstance = this; }
|
constructor() { ng2ComponentBInstance = this; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define `ng1Module`
|
// Define `ng1Module`
|
||||||
const ng1Module =
|
const ng1Module = angular.module('ng1', [])
|
||||||
angular.module('ng1', [])
|
.component('ng1X', ng1Component)
|
||||||
.component('ng1X', ng1Component)
|
.directive('ng2A', downgradeComponent({component: Ng2ComponentA}))
|
||||||
.directive('ng2A', downgradeComponent({component: Ng2ComponentA}))
|
.directive('ng2B', downgradeComponent({component: Ng2ComponentB}));
|
||||||
.directive('ng2B', downgradeComponent({component: Ng2ComponentB}));
|
|
||||||
|
|
||||||
// Define `Ng2Module`
|
// Define `Ng2Module`
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [Ng1ComponentXFacade, Ng2ComponentA, Ng2ComponentB],
|
declarations: [Ng1ComponentXFacade, Ng2ComponentA, Ng2ComponentB],
|
||||||
entryComponents: [Ng2ComponentA, Ng2ComponentB],
|
entryComponents: [Ng2ComponentA, Ng2ComponentB],
|
||||||
imports: [BrowserModule, UpgradeModule],
|
imports: [BrowserModule, UpgradeModule],
|
||||||
schemas: [NO_ERRORS_SCHEMA],
|
schemas: [NO_ERRORS_SCHEMA],
|
||||||
})
|
})
|
||||||
class Ng2Module {
|
class Ng2Module {
|
||||||
ngDoBootstrap() {}
|
ngDoBootstrap() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bootstrap
|
// Bootstrap
|
||||||
const element = html(`<ng2-a></ng2-a>`);
|
const element = html(`<ng2-a></ng2-a>`);
|
||||||
|
|
||||||
bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(adapter => {
|
bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then(adapter => {
|
||||||
// Initial value propagation.
|
// Initial value propagation.
|
||||||
// (ng2A > ng1X > ng2B)
|
// (ng2A > ng1X > ng2B)
|
||||||
expect(multiTrim(document.body.textContent))
|
expect(multiTrim(document.body.textContent))
|
||||||
.toBe('ng2A(foo, bar, baz) | ng1X(foo, bar, baz) | ng2B(foo, baz)');
|
.toBe('ng2A(foo, bar, baz) | ng1X(foo, bar, baz) | ng2B(foo, baz)');
|
||||||
|
|
||||||
// Update `ng2BInputA`/`ng2BInputC`.
|
// Update `ng2BInputA`/`ng2BInputC`.
|
||||||
// (Should not propagate upwards.)
|
// (Should not propagate upwards.)
|
||||||
ng2ComponentBInstance.ng2BInputA = 'foo2';
|
ng2ComponentBInstance.ng2BInputA = 'foo2';
|
||||||
ng2ComponentBInstance.ng2BInputC = 'baz2';
|
ng2ComponentBInstance.ng2BInputC = 'baz2';
|
||||||
$digest(adapter);
|
$digest(adapter);
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(multiTrim(document.body.textContent))
|
expect(multiTrim(document.body.textContent))
|
||||||
.toBe('ng2A(foo, bar, baz) | ng1X(foo, bar, baz) | ng2B(foo2, baz2)');
|
.toBe('ng2A(foo, bar, baz) | ng1X(foo, bar, baz) | ng2B(foo2, baz2)');
|
||||||
|
|
||||||
// Emit from `ng2BOutputC`.
|
// Emit from `ng2BOutputC`.
|
||||||
// (Should propagate all the way up to `ng1ADataC` and back all the way down to
|
// (Should propagate all the way up to `ng1ADataC` and back all the way down to
|
||||||
// `ng2BInputC`.)
|
// `ng2BInputC`.)
|
||||||
ng2ComponentBInstance.ng2BOutputC.emit('baz3');
|
ng2ComponentBInstance.ng2BOutputC.emit('baz3');
|
||||||
$digest(adapter);
|
$digest(adapter);
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(multiTrim(document.body.textContent))
|
expect(multiTrim(document.body.textContent))
|
||||||
.toBe('ng2A(foo, bar, baz3) | ng1X(foo, bar, baz3) | ng2B(foo2, baz3)');
|
.toBe('ng2A(foo, bar, baz3) | ng1X(foo, bar, baz3) | ng2B(foo2, baz3)');
|
||||||
|
|
||||||
// Update `ng1XInputA`/`ng1XInputB`.
|
// Update `ng1XInputA`/`ng1XInputB`.
|
||||||
// (Should not propagate upwards, only downwards.)
|
// (Should not propagate upwards, only downwards.)
|
||||||
ng1ControllerXInstance.ng1XInputA = 'foo4';
|
ng1ControllerXInstance.ng1XInputA = 'foo4';
|
||||||
ng1ControllerXInstance.ng1XInputB = {value: 'bar4'};
|
ng1ControllerXInstance.ng1XInputB = {value: 'bar4'};
|
||||||
$digest(adapter);
|
$digest(adapter);
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(multiTrim(document.body.textContent))
|
expect(multiTrim(document.body.textContent))
|
||||||
.toBe('ng2A(foo, bar, baz3) | ng1X(foo4, bar4, baz3) | ng2B(foo4, baz3)');
|
.toBe('ng2A(foo, bar, baz3) | ng1X(foo4, bar4, baz3) | ng2B(foo4, baz3)');
|
||||||
|
|
||||||
// Update `ng1XInputC`.
|
// Update `ng1XInputC`.
|
||||||
// (Should propagate upwards and downwards.)
|
// (Should propagate upwards and downwards.)
|
||||||
ng1ControllerXInstance.ng1XInputC = {value: 'baz5'};
|
ng1ControllerXInstance.ng1XInputC = {value: 'baz5'};
|
||||||
$digest(adapter);
|
$digest(adapter);
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(multiTrim(document.body.textContent))
|
expect(multiTrim(document.body.textContent))
|
||||||
.toBe('ng2A(foo, bar, baz5) | ng1X(foo4, bar4, baz5) | ng2B(foo4, baz5)');
|
.toBe('ng2A(foo, bar, baz5) | ng1X(foo4, bar4, baz5) | ng2B(foo4, baz5)');
|
||||||
|
|
||||||
// Update a property on `ng1XInputC`.
|
// Update a property on `ng1XInputC`.
|
||||||
// (Should propagate upwards and downwards.)
|
// (Should propagate upwards and downwards.)
|
||||||
ng1ControllerXInstance.ng1XInputC.value = 'baz6';
|
ng1ControllerXInstance.ng1XInputC.value = 'baz6';
|
||||||
$digest(adapter);
|
$digest(adapter);
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(multiTrim(document.body.textContent))
|
expect(multiTrim(document.body.textContent))
|
||||||
.toBe('ng2A(foo, bar, baz6) | ng1X(foo4, bar4, baz6) | ng2B(foo4, baz6)');
|
.toBe('ng2A(foo, bar, baz6) | ng1X(foo4, bar4, baz6) | ng2B(foo4, baz6)');
|
||||||
|
|
||||||
// Emit from `ng1XOutputA`.
|
// Emit from `ng1XOutputA`.
|
||||||
// (Should propagate upwards to `ng1ADataA` and back all the way down to
|
// (Should propagate upwards to `ng1ADataA` and back all the way down to
|
||||||
// `ng2BInputA`.)
|
// `ng2BInputA`.)
|
||||||
(ng1ControllerXInstance as any).ng1XOutputA({value: 'foo7'});
|
(ng1ControllerXInstance as any).ng1XOutputA({value: 'foo7'});
|
||||||
$digest(adapter);
|
$digest(adapter);
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(multiTrim(document.body.textContent))
|
expect(multiTrim(document.body.textContent))
|
||||||
.toBe('ng2A(foo7, bar, baz6) | ng1X(foo7, bar4, baz6) | ng2B(foo7, baz6)');
|
.toBe('ng2A(foo7, bar, baz6) | ng1X(foo7, bar4, baz6) | ng2B(foo7, baz6)');
|
||||||
|
|
||||||
// Emit from `ng1XOutputB`.
|
// Emit from `ng1XOutputB`.
|
||||||
// (Should propagate upwards to `ng1ADataB`, but not downwards,
|
// (Should propagate upwards to `ng1ADataB`, but not downwards,
|
||||||
// since `ng1XInputB` has been re-assigned (i.e. `ng2ADataB !== ng1XInputB`).)
|
// since `ng1XInputB` has been re-assigned (i.e. `ng2ADataB !== ng1XInputB`).)
|
||||||
(ng1ControllerXInstance as any).ng1XOutputB('bar8');
|
(ng1ControllerXInstance as any).ng1XOutputB('bar8');
|
||||||
$digest(adapter);
|
$digest(adapter);
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(multiTrim(document.body.textContent))
|
expect(multiTrim(document.body.textContent))
|
||||||
.toBe('ng2A(foo7, bar8, baz6) | ng1X(foo7, bar4, baz6) | ng2B(foo7, baz6)');
|
.toBe('ng2A(foo7, bar8, baz6) | ng1X(foo7, bar4, baz6) | ng2B(foo7, baz6)');
|
||||||
|
|
||||||
// Update `ng2ADataA`/`ng2ADataB`/`ng2ADataC`.
|
// Update `ng2ADataA`/`ng2ADataB`/`ng2ADataC`.
|
||||||
// (Should propagate everywhere.)
|
// (Should propagate everywhere.)
|
||||||
ng2ComponentAInstance.ng2ADataA = {value: 'foo9'};
|
ng2ComponentAInstance.ng2ADataA = {value: 'foo9'};
|
||||||
ng2ComponentAInstance.ng2ADataB = {value: 'bar9'};
|
ng2ComponentAInstance.ng2ADataB = {value: 'bar9'};
|
||||||
ng2ComponentAInstance.ng2ADataC = {value: 'baz9'};
|
ng2ComponentAInstance.ng2ADataC = {value: 'baz9'};
|
||||||
$digest(adapter);
|
$digest(adapter);
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
expect(multiTrim(document.body.textContent))
|
expect(multiTrim(document.body.textContent))
|
||||||
.toBe('ng2A(foo9, bar9, baz9) | ng1X(foo9, bar9, baz9) | ng2B(foo9, baz9)');
|
.toBe('ng2A(foo9, bar9, baz9) | ng1X(foo9, bar9, baz9) | ng2B(foo9, baz9)');
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should support ng2 > ng1 > ng2 > ng1 (with `require`)', async(() => {
|
it('should support ng2 > ng1 > ng2 > ng1 (with `require`)', async(() => {
|
||||||
// Define `ng1Component`
|
// Define `ng1Component`
|
||||||
|
|
Loading…
Reference in New Issue