/**
 * @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 {Component, Directive, ElementRef, EventEmitter, Injector, Input, NO_ERRORS_SCHEMA, NgModule, Output, destroyPlatform} from '@angular/core';
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 {UpgradeComponent, UpgradeModule, downgradeComponent} from '@angular/upgrade/static';
import {bootstrap, html, multiTrim} from '../test_helpers';
export function main() {
  describe('upgrade ng1 component', () => {
    beforeEach(() => destroyPlatform());
    afterEach(() => destroyPlatform());
    describe('template/templateUrl', () => {
      it('should support `template` (string)', async(() => {
           // Define `ng1Component`
           const ng1Component: angular.IComponent = {template: 'Hello, Angular!'};
           // Define `Ng1ComponentFacade`
           @Directive({selector: 'ng1'})
           class Ng1ComponentFacade extends UpgradeComponent {
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({selector: 'ng2', template: ''})
           class Ng2Component {
           }
           // Define `ng1Module`
           const ng1Module = angular.module('ng1Module', [])
                                 .component('ng1', ng1Component)
                                 .directive('ng2', downgradeComponent({component: Ng2Component}));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then((upgrade) => {
             expect(multiTrim(element.textContent)).toBe('Hello, Angular!');
           });
         }));
      it('should support `template` (function)', async(() => {
           // Define `ng1Component`
           const ng1Component: angular.IComponent = {template: () => 'Hello, Angular!'};
           // Define `Ng1ComponentFacade`
           @Directive({selector: 'ng1'})
           class Ng1ComponentFacade extends UpgradeComponent {
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({selector: 'ng2', template: ''})
           class Ng2Component {
           }
           // Define `ng1Module`
           const ng1Module = angular.module('ng1Module', [])
                                 .component('ng1', ng1Component)
                                 .directive('ng2', downgradeComponent({component: Ng2Component}));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             expect(multiTrim(element.textContent)).toBe('Hello, Angular!');
           });
         }));
      it('should support not pass any arguments to `template` function', async(() => {
           // Define `ng1Component`
           const ng1Component: angular.IComponent = {
             template: ($attrs: angular.IAttributes, $element: angular.IAugmentedJQuery) => {
               expect($attrs).toBeUndefined();
               expect($element).toBeUndefined();
               return 'Hello, Angular!';
             }
           };
           // Define `Ng1ComponentFacade`
           @Directive({selector: 'ng1'})
           class Ng1ComponentFacade extends UpgradeComponent {
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({selector: 'ng2', template: ''})
           class Ng2Component {
           }
           // Define `ng1Module`
           const ng1Module = angular.module('ng1Module', [])
                                 .component('ng1', ng1Component)
                                 .directive('ng2', downgradeComponent({component: Ng2Component}));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             expect(multiTrim(element.textContent)).toBe('Hello, Angular!');
           });
         }));
      it('should support `templateUrl` (string) fetched from `$templateCache`', async(() => {
           // Define `ng1Component`
           const ng1Component: angular.IComponent = {templateUrl: 'ng1.component.html'};
           // Define `Ng1ComponentFacade`
           @Directive({selector: 'ng1'})
           class Ng1ComponentFacade extends UpgradeComponent {
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({selector: 'ng2', template: ''})
           class Ng2Component {
           }
           // Define `ng1Module`
           const ng1Module =
               angular.module('ng1Module', [])
                   .component('ng1', ng1Component)
                   .directive('ng2', downgradeComponent({component: Ng2Component}))
                   .run(
                       ($templateCache: angular.ITemplateCacheService) =>
                           $templateCache.put('ng1.component.html', 'Hello, Angular!'));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             expect(multiTrim(element.textContent)).toBe('Hello, Angular!');
           });
         }));
      it('should support `templateUrl` (function) fetched from `$templateCache`', async(() => {
           // Define `ng1Component`
           const ng1Component: angular.IComponent = {templateUrl: () => 'ng1.component.html'};
           // Define `Ng1ComponentFacade`
           @Directive({selector: 'ng1'})
           class Ng1ComponentFacade extends UpgradeComponent {
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({selector: 'ng2', template: ''})
           class Ng2Component {
           }
           // Define `ng1Module`
           const ng1Module =
               angular.module('ng1Module', [])
                   .component('ng1', ng1Component)
                   .directive('ng2', downgradeComponent({component: Ng2Component}))
                   .run(
                       ($templateCache: angular.ITemplateCacheService) =>
                           $templateCache.put('ng1.component.html', 'Hello, Angular!'));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             expect(multiTrim(element.textContent)).toBe('Hello, Angular!');
           });
         }));
      it('should support not pass any arguments to `templateUrl` function', async(() => {
           // Define `ng1Component`
           const ng1Component: angular.IComponent = {
             templateUrl: ($attrs: angular.IAttributes, $element: angular.IAugmentedJQuery) => {
               expect($attrs).toBeUndefined();
               expect($element).toBeUndefined();
               return 'ng1.component.html';
             }
           };
           // Define `Ng1ComponentFacade`
           @Directive({selector: 'ng1'})
           class Ng1ComponentFacade extends UpgradeComponent {
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({selector: 'ng2', template: ''})
           class Ng2Component {
           }
           // Define `ng1Module`
           const ng1Module =
               angular.module('ng1Module', [])
                   .component('ng1', ng1Component)
                   .directive('ng2', downgradeComponent({component: Ng2Component}))
                   .run(
                       ($templateCache: angular.ITemplateCacheService) =>
                           $templateCache.put('ng1.component.html', 'Hello, Angular!'));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             expect(multiTrim(element.textContent)).toBe('Hello, Angular!');
           });
         }));
      // NOT SUPPORTED YET
      xit('should support `templateUrl` (string) fetched from the server', fakeAsync(() => {
            // Define `ng1Component`
            const ng1Component: angular.IComponent = {templateUrl: 'ng1.component.html'};
            // Define `Ng1ComponentFacade`
            @Directive({selector: 'ng1'})
            class Ng1ComponentFacade extends UpgradeComponent {
              constructor(elementRef: ElementRef, injector: Injector) {
                super('ng1', elementRef, injector);
              }
            }
            // Define `Ng2Component`
            @Component({selector: 'ng2', template: ''})
            class Ng2Component {
            }
            // Define `ng1Module`
            const ng1Module =
                angular.module('ng1Module', [])
                    .component('ng1', ng1Component)
                    .directive('ng2', downgradeComponent({component: Ng2Component}))
                    .value(
                        '$httpBackend',
                        (method: string, url: string, post?: any, callback?: Function) =>
                            setTimeout(
                                () => callback(200, `${method}:${url}`.toLowerCase()), 1000));
            // Define `Ng2Module`
            @NgModule({
              declarations: [Ng1ComponentFacade, Ng2Component],
              entryComponents: [Ng2Component],
              imports: [BrowserModule, UpgradeModule]
            })
            class Ng2Module {
              ngDoBootstrap() {}
            }
            // Bootstrap
            const element = html(``);
            platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
              var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
              adapter.bootstrap(element, [ng1Module.name]);
              tick(500);
              expect(multiTrim(element.textContent)).toBe('');
              tick(500);
              expect(multiTrim(element.textContent)).toBe('get:ng1.component.html');
            });
          }));
      // NOT SUPPORTED YET
      xit('should support `templateUrl` (function) fetched from the server', fakeAsync(() => {
            // Define `ng1Component`
            const ng1Component: angular.IComponent = {templateUrl: () => 'ng1.component.html'};
            // Define `Ng1ComponentFacade`
            @Directive({selector: 'ng1'})
            class Ng1ComponentFacade extends UpgradeComponent {
              constructor(elementRef: ElementRef, injector: Injector) {
                super('ng1', elementRef, injector);
              }
            }
            // Define `Ng2Component`
            @Component({selector: 'ng2', template: ''})
            class Ng2Component {
            }
            // Define `ng1Module`
            const ng1Module =
                angular.module('ng1Module', [])
                    .component('ng1', ng1Component)
                    .directive('ng2', downgradeComponent({component: Ng2Component}))
                    .value(
                        '$httpBackend',
                        (method: string, url: string, post?: any, callback?: Function) =>
                            setTimeout(
                                () => callback(200, `${method}:${url}`.toLowerCase()), 1000));
            // Define `Ng2Module`
            @NgModule({
              declarations: [Ng1ComponentFacade, Ng2Component],
              entryComponents: [Ng2Component],
              imports: [BrowserModule, UpgradeModule]
            })
            class Ng2Module {
              ngDoBootstrap() {}
            }
            // Bootstrap
            const element = html(``);
            platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
              var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
              adapter.bootstrap(element, [ng1Module.name]);
              tick(500);
              expect(multiTrim(element.textContent)).toBe('');
              tick(500);
              expect(multiTrim(element.textContent)).toBe('get:ng1.component.html');
            });
          }));
      it('should support empty templates', async(() => {
           // Define `ng1Component`s
           const ng1ComponentA: angular.IComponent = {template: ''};
           const ng1ComponentB: angular.IComponent = {template: () => ''};
           const ng1ComponentC: angular.IComponent = {templateUrl: 'ng1.component.html'};
           const ng1ComponentD: angular.IComponent = {templateUrl: () => 'ng1.component.html'};
           // Define `Ng1ComponentFacade`s
           @Directive({selector: 'ng1A'})
           class Ng1ComponentAFacade extends UpgradeComponent {
             constructor(e: ElementRef, i: Injector) { super('ng1A', e, i); }
           }
           @Directive({selector: 'ng1B'})
           class Ng1ComponentBFacade extends UpgradeComponent {
             constructor(e: ElementRef, i: Injector) { super('ng1B', e, i); }
           }
           @Directive({selector: 'ng1C'})
           class Ng1ComponentCFacade extends UpgradeComponent {
             constructor(e: ElementRef, i: Injector) { super('ng1C', e, i); }
           }
           @Directive({selector: 'ng1D'})
           class Ng1ComponentDFacade extends UpgradeComponent {
             constructor(e: ElementRef, i: Injector) { super('ng1D', e, i); }
           }
           // Define `Ng2Component`
           @Component({
             selector: 'ng2',
             template: `
               Ignore this
               Ignore this
               Ignore this
               Ignore this
             `
           })
           class Ng2Component {
           }
           // Define `ng1Module`
           const ng1Module = angular.module('ng1Module', [])
                                 .component('ng1A', ng1ComponentA)
                                 .component('ng1B', ng1ComponentB)
                                 .component('ng1C', ng1ComponentC)
                                 .component('ng1D', ng1ComponentD)
                                 .directive('ng2', downgradeComponent({component: Ng2Component}))
                                 .run(
                                     ($templateCache: angular.ITemplateCacheService) =>
                                         $templateCache.put('ng1.component.html', ''));
           // Define `Ng2Module`
           @NgModule({
             declarations: [
               Ng1ComponentAFacade, Ng1ComponentBFacade, Ng1ComponentCFacade, Ng1ComponentDFacade,
               Ng2Component
             ],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule],
             schemas: [NO_ERRORS_SCHEMA]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             expect(multiTrim(element.textContent)).toBe('');
           });
         }));
    });
    describe('bindings', () => {
      it('should support `@` bindings', fakeAsync(() => {
           // Define `ng1Component`
           const ng1Component: angular.IComponent = {
             template: 'Inside: {{ $ctrl.inputA }}, {{ $ctrl.inputB }}',
             bindings: {inputA: '@inputAttrA', inputB: '@'}
           };
           // Define `Ng1ComponentFacade`
           @Directive({selector: 'ng1'})
           class Ng1ComponentFacade extends UpgradeComponent {
             @Input('inputAttrA') inputA: string;
             @Input() inputB: string;
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({
             selector: 'ng2',
             template: `
               
               | Outside: {{ dataA }}, {{ dataB }}
             `
           })
           class Ng2Component {
             dataA = 'foo';
             dataB = 'bar';
           }
           // Define `ng1Module`
           const ng1Module = angular.module('ng1Module', [])
                                 .component('ng1', ng1Component)
                                 .directive('ng2', downgradeComponent({component: Ng2Component}));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             var ng1 = element.querySelector('ng1');
             var ng1Controller = angular.element(ng1).controller('ng1');
             expect(multiTrim(element.textContent)).toBe('Inside: foo, bar | Outside: foo, bar');
             ng1Controller.inputA = 'baz';
             ng1Controller.inputB = 'qux';
             tick();
             expect(multiTrim(element.textContent)).toBe('Inside: baz, qux | Outside: foo, bar');
             // TODO: Verify that changes in `` propagate to ``.
           });
         }));
      it('should support `<` bindings', fakeAsync(() => {
           // Define `ng1Component`
           const ng1Component: angular.IComponent = {
             template: 'Inside: {{ $ctrl.inputA.value }}, {{ $ctrl.inputB.value }}',
             bindings: {inputA: '
               | Outside: {{ dataA.value }}, {{ dataB.value }}
             `
           })
           class Ng2Component {
             dataA = {value: 'foo'};
             dataB = {value: 'bar'};
           }
           // Define `ng1Module`
           const ng1Module = angular.module('ng1Module', [])
                                 .component('ng1', ng1Component)
                                 .directive('ng2', downgradeComponent({component: Ng2Component}));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             var ng1 = element.querySelector('ng1');
             var ng1Controller = angular.element(ng1).controller('ng1');
             expect(multiTrim(element.textContent)).toBe('Inside: foo, bar | Outside: foo, bar');
             ng1Controller.inputA = {value: 'baz'};
             ng1Controller.inputB = {value: 'qux'};
             tick();
             expect(multiTrim(element.textContent)).toBe('Inside: baz, qux | Outside: foo, bar');
             // TODO: Verify that changes in `` propagate to ``.
           });
         }));
      it('should support `=` bindings', fakeAsync(() => {
           // Define `ng1Component`
           const ng1Component: angular.IComponent = {
             template: 'Inside: {{ $ctrl.inputA.value }}, {{ $ctrl.inputB.value }}',
             bindings: {inputA: '=inputAttrA', inputB: '='}
           };
           // Define `Ng1ComponentFacade`
           @Directive({selector: 'ng1'})
           class Ng1ComponentFacade extends UpgradeComponent {
             @Input('inputAttrA') inputA: string;
             @Output('inputAttrAChange') inputAChange: EventEmitter;
             @Input() inputB: string;
             @Output() inputBChange: EventEmitter;
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({
             selector: 'ng2',
             template: `
               
               | Outside: {{ dataA.value }}, {{ dataB.value }}
             `
           })
           class Ng2Component {
             dataA = {value: 'foo'};
             dataB = {value: 'bar'};
           }
           // Define `ng1Module`
           const ng1Module = angular.module('ng1Module', [])
                                 .component('ng1', ng1Component)
                                 .directive('ng2', downgradeComponent({component: Ng2Component}));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             var ng1 = element.querySelector('ng1');
             var ng1Controller = angular.element(ng1).controller('ng1');
             expect(multiTrim(element.textContent)).toBe('Inside: foo, bar | Outside: foo, bar');
             ng1Controller.inputA = {value: 'baz'};
             ng1Controller.inputB = {value: 'qux'};
             tick();
             expect(multiTrim(element.textContent)).toBe('Inside: baz, qux | Outside: baz, qux');
             // TODO: Verify that changes in `` propagate to ``.
           });
         }));
      it('should support `&` bindings', fakeAsync(() => {
           // Define `ng1Component`
           const ng1Component: angular.IComponent = {
             template: 'Inside: -',
             bindings: {outputA: '&outputAttrA', outputB: '&'}
           };
           // Define `Ng1ComponentFacade`
           @Directive({selector: 'ng1'})
           class Ng1ComponentFacade extends UpgradeComponent {
             @Output('outputAttrA') outputA: EventEmitter;
             @Output() outputB: EventEmitter;
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({
             selector: 'ng2',
             template: `
               
               | Outside: {{ dataA }}, {{ dataB }}
             `
           })
           class Ng2Component {
             dataA = 'foo';
             dataB = 'bar';
           }
           // Define `ng1Module`
           const ng1Module = angular.module('ng1Module', [])
                                 .component('ng1', ng1Component)
                                 .directive('ng2', downgradeComponent({component: Ng2Component}));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             var ng1 = element.querySelector('ng1');
             var ng1Controller = angular.element(ng1).controller('ng1');
             expect(multiTrim(element.textContent)).toBe('Inside: - | Outside: foo, bar');
             ng1Controller.outputA('baz');
             ng1Controller.outputB('qux');
             tick();
             expect(multiTrim(element.textContent)).toBe('Inside: - | Outside: baz, qux');
           });
         }));
      it('should bind properties, events', fakeAsync(() => {
           // Define `ng1Component`
           const ng1Component: angular.IComponent = {
             template: `
               Hello {{ $ctrl.fullName }};
               A: {{ $ctrl.modelA }};
               B: {{ $ctrl.modelB }};
               C: {{ $ctrl.modelC }}
             `,
             bindings: {fullName: '@', modelA: ' {
                 if (v === 'Savkin') {
                   this.modelB = 'SAVKIN';
                   this.event('WORKS');
                   // Should not update because `modelA: ';
             @Input() modelC: any;
             @Output() modelCChange: EventEmitter;
             @Output() event: EventEmitter;
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({
             selector: 'ng2',
             template: `
               
                |
                |
               {{ event }} - {{ last }}, {{ first }}, {{ city }}
             `
           })
           class Ng2Component {
             first = 'Victor';
             last = 'Savkin';
             city = 'SF';
             event = '?';
           }
           // Define `ng1Module`
           const ng1Module = angular.module('ng1Module', [])
                                 .component('ng1', ng1Component)
                                 .directive('ng2', downgradeComponent({component: Ng2Component}));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             expect(multiTrim(element.textContent))
                 .toBe(
                     'Hello Savkin, Victor, SF; A: VICTOR; B: SAVKIN; C: sf | ' +
                     'Hello TEST; A: First; B: Last; C: City | ' +
                     'WORKS - SAVKIN, Victor, SF');
             // Detect changes
             tick();
             expect(multiTrim(element.textContent))
                 .toBe(
                     'Hello SAVKIN, Victor, SF; A: VICTOR; B: SAVKIN; C: sf | ' +
                     'Hello TEST; A: First; B: Last; C: City | ' +
                     'WORKS - SAVKIN, Victor, SF');
           });
         }));
      it('should bind optional properties', fakeAsync(() => {
           // Define `ng1Component`
           const ng1Component: angular.IComponent = {
             template: 'Inside: {{ $ctrl.inputA.value }}, {{ $ctrl.inputB }}',
             bindings:
                 {inputA: '=?inputAttrA', inputB: '=?', outputA: '&?outputAttrA', outputB: '&?'}
           };
           // Define `Ng1ComponentFacade`
           @Directive({selector: 'ng1'})
           class Ng1ComponentFacade extends UpgradeComponent {
             @Input('inputAttrA') inputA: string;
             @Output('inputAttrAChange') inputAChange: EventEmitter;
             @Input() inputB: string;
             @Output() inputBChange: EventEmitter;
             @Output('outputAttrA') outputA: EventEmitter;
             @Output() outputB: EventEmitter;
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({
             selector: 'ng2',
             template: `
                |
                |
                |
                |
               Outside: {{ dataA.value }}, {{ dataB.value }}
             `
           })
           class Ng2Component {
             dataA = {value: 'foo'};
             dataB = {value: 'bar'};
             updateDataB(value: any) { this.dataB.value = value; }
           }
           // Define `ng1Module`
           const ng1Module = angular.module('ng1Module', [])
                                 .component('ng1', ng1Component)
                                 .directive('ng2', downgradeComponent({component: Ng2Component}));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             const $rootScope = adapter.$injector.get('$rootScope') as angular.IRootScopeService;
             var ng1s = element.querySelectorAll('ng1');
             var ng1Controller0 = angular.element(ng1s[0]).controller('ng1');
             var ng1Controller1 = angular.element(ng1s[1]).controller('ng1');
             var ng1Controller2 = angular.element(ng1s[2]).controller('ng1');
             expect(multiTrim(element.textContent))
                 .toBe(
                     'Inside: foo, bar | Inside: , Bar | Inside: , | Inside: , | Outside: foo, bar');
             ng1Controller0.inputA.value = 'baz';
             ng1Controller0.inputB = 'qux';
             tick();
             expect(multiTrim(element.textContent))
                 .toBe(
                     'Inside: baz, qux | Inside: , Bar | Inside: , | Inside: , | Outside: baz, qux');
             ng1Controller1.outputA({value: 'foo again'});
             ng1Controller2.outputB('bar again');
             $rootScope.$apply();
             tick();
             expect(ng1Controller0.inputA).toEqual({value: 'foo again'});
             expect(ng1Controller0.inputB).toEqual('bar again');
             expect(multiTrim(element.textContent))
                 .toBe(
                     'Inside: foo again, bar again | Inside: , Bar | Inside: , | Inside: , | ' +
                     'Outside: foo again, bar again');
           });
         }));
      it('should bind properties, events to scope when bindToController is not used',
         fakeAsync(() => {
           // Define `ng1Directive`
           const ng1Directive: angular.IDirective = {
             template: '{{ someText }} - Data: {{ inputA }} - Length: {{ inputA.length }}',
             scope: {inputA: '=', outputA: '&'},
             controller: function($scope: angular.IScope) {
               $scope['someText'] = 'ng1';
               this.$scope = $scope;
             }
           };
           // Define `Ng1ComponentFacade`
           @Directive({selector: '[ng1]'})
           class Ng1ComponentFacade extends UpgradeComponent {
             @Input() inputA: string;
             @Output() inputAChange: EventEmitter;
             @Output() outputA: EventEmitter;
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({
             selector: 'ng2',
             template: `
                 |
                {{ someText }} - Data: {{ dataA }} - Length: {{ dataA.length }}
              `
           })
           class Ng2Component {
             someText = 'ng2';
             dataA = [1, 2, 3];
           }
           // Define `ng1Module`
           const ng1Module = angular.module('ng1Module', [])
                                 .directive('ng1', () => ng1Directive)
                                 .directive('ng2', downgradeComponent({component: Ng2Component}));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             const $rootScope = adapter.$injector.get('$rootScope') as angular.IRootScopeService;
             var ng1 = element.querySelector('[ng1]');
             var ng1Controller = angular.element(ng1).controller('ng1');
             expect(multiTrim(element.textContent))
                 .toBe('ng1 - Data: [1,2,3] - Length: 3 | ng2 - Data: 1,2,3 - Length: 3');
             ng1Controller.$scope.inputA = [4, 5];
             tick();
             expect(multiTrim(element.textContent))
                 .toBe('ng1 - Data: [4,5] - Length: 2 | ng2 - Data: 4,5 - Length: 2');
             ng1Controller.$scope.outputA(6);
             tick();
             $rootScope.$apply();
             expect(ng1Controller.$scope.inputA).toEqual([4, 5, 6]);
             expect(multiTrim(element.textContent))
                 .toBe('ng1 - Data: [4,5,6] - Length: 3 | ng2 - Data: 4,5,6 - Length: 3');
           });
         }));
    });
    describe('controller', () => {
      it('should support `controllerAs`', async(() => {
           // Define `ng1Directive`
           const ng1Directive: angular.IDirective = {
             template:
                 '{{ vm.scope }}; {{ vm.isClass }}; {{ vm.hasElement }}; {{ vm.isPublished() }}',
             scope: true,
             controllerAs: 'vm',
             controller: class {
               hasElement: string; isClass: string; scope: string;
               constructor(public $element: angular.IAugmentedJQuery, $scope: angular.IScope) {
                 this.hasElement = $element[0].nodeName;
                 this.scope = $scope.$parent.$parent === $scope.$root ? 'scope' : 'wrong-scope';
                 this.verifyIAmAClass();
               }
               isPublished() {
                 return this.$element.controller('ng1') === this ? 'published' : 'not-published';
               }
               verifyIAmAClass() { this.isClass = 'isClass'; }
             }
           };
           // Define `Ng1ComponentFacade`
           @Directive({selector: 'ng1'})
           class Ng1ComponentFacade extends UpgradeComponent {
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({selector: 'ng2', template: ''})
           class Ng2Component {
           }
           // Define `ng1Module`
           const ng1Module = angular.module('ng1Module', [])
                                 .directive('ng1', () => ng1Directive)
                                 .directive('ng2', downgradeComponent({component: Ng2Component}));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             expect(multiTrim(document.body.textContent)).toBe('scope; isClass; NG1; published');
           });
         }));
      it('should support `bindToController` (boolean)', async(() => {
           // Define `ng1Directive`
           const ng1DirectiveA: angular.IDirective = {
             template: 'Scope: {{ title }}; Controller: {{ $ctrl.title }}',
             scope: {title: '@'},
             bindToController: false,
             controllerAs: '$ctrl',
             controller: class {}
           };
           const ng1DirectiveB: angular.IDirective = {
             template: 'Scope: {{ title }}; Controller: {{ $ctrl.title }}',
             scope: {title: '@'},
             bindToController: true,
             controllerAs: '$ctrl',
             controller: class {}
           };
           // Define `Ng1ComponentFacade`
           @Directive({selector: 'ng1A'})
           class Ng1ComponentAFacade extends UpgradeComponent {
             @Input() title: string;
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1A', elementRef, injector);
             }
           }
           @Directive({selector: 'ng1B'})
           class Ng1ComponentBFacade extends UpgradeComponent {
             @Input() title: string;
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1B', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({
             selector: 'ng2',
             template: `
             |
            
          `
           })
           class Ng2Component {
           }
           // Define `ng1Module`
           const ng1Module = angular.module('ng1Module', [])
                                 .directive('ng1A', () => ng1DirectiveA)
                                 .directive('ng1B', () => ng1DirectiveB)
                                 .directive('ng2', downgradeComponent({component: Ng2Component}));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentAFacade, Ng1ComponentBFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule],
             schemas: [NO_ERRORS_SCHEMA]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             expect(multiTrim(document.body.textContent))
                 .toBe('Scope: WORKS; Controller: | Scope: ; Controller: WORKS');
           });
         }));
      it('should support `bindToController` (object)', async(() => {
           // Define `ng1Directive`
           const ng1Directive: angular.IDirective = {
             template: '{{ $ctrl.title }}',
             scope: {},
             bindToController: {title: '@'},
             controllerAs: '$ctrl',
             controller: class {}
           };
           // Define `Ng1ComponentFacade`
           @Directive({selector: 'ng1'})
           class Ng1ComponentFacade extends UpgradeComponent {
             @Input() title: string;
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({selector: 'ng2', template: ''})
           class Ng2Component {
             dataA = 'foo';
             dataB = 'bar';
           }
           // Define `ng1Module`
           const ng1Module = angular.module('ng1Module', [])
                                 .directive('ng1', () => ng1Directive)
                                 .directive('ng2', downgradeComponent({component: Ng2Component}));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             expect(multiTrim(document.body.textContent)).toBe('WORKS');
           });
         }));
      it('should support `controller` as string', async(() => {
           // Define `ng1Directive`
           const ng1Directive: angular.IDirective = {
             template: '{{ $ctrl.title }} {{ $ctrl.text }}',
             scope: {title: '@'},
             bindToController: true,
             controller: 'Ng1Controller as $ctrl'
           };
           // Define `Ng1ComponentFacade`
           @Directive({selector: 'ng1'})
           class Ng1ComponentFacade extends UpgradeComponent {
             @Input() title: string;
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({selector: 'ng2', template: ''})
           class Ng2Component {
           }
           // Define `ng1Module`
           const ng1Module = angular.module('ng1Module', [])
                                 .controller('Ng1Controller', class { text = 'GREAT'; })
                                 .directive('ng1', () => ng1Directive)
                                 .directive('ng2', downgradeComponent({component: Ng2Component}));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             expect(multiTrim(document.body.textContent)).toBe('WORKS GREAT');
           });
         }));
    });
    // NOT YET SUPPORTED
    xdescribe(
        'require',
        () => {
            // it('should support single require in linking fn', async(() => {
            //   const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
            //   const ng1Module = angular.module('ng1', []);
            //   const ng1 = ($rootScope: any /** TODO #9100 */) => {
            //     return {
            //       scope: {title: '@'},
            //       bindToController: true,
            //       template: '{{ctl.status}}',
            //       require: 'ng1',
            //       controllerAs: 'ctrl',
            //       controller: Class({constructor: function() { this.status = 'WORKS'; }}),
            //       link: function(
            //           scope: any /** TODO #9100 */, element: any /** TODO #9100 */,
            //           attrs: any /** TODO #9100 */, linkController: any /** TODO #9100 */) {
            //         expect(scope.$root).toEqual($rootScope);
            //         expect(element[0].nodeName).toEqual('NG1');
            //         expect(linkController.status).toEqual('WORKS');
            //         scope.ctl = linkController;
            //       }
            //     };
            //   };
            //   ng1Module.directive('ng1', ng1);
            //   const Ng2 = Component({selector: 'ng2', template: ''}).Class({
            //     constructor: function() {}
            //   });
            //   const Ng2Module = NgModule({
            //                       declarations: [adapter.upgradeNg1Component('ng1'), Ng2],
            //                       imports: [BrowserModule],
            //                       schemas: [NO_ERRORS_SCHEMA],
            //                     }).Class({constructor: function() {}});
            //   ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2));
            //   const element = html(`
`);
            //   adapter.bootstrap(element, ['ng1']).ready((ref) => {
            //     expect(multiTrim(document.body.textContent)).toEqual('WORKS');
            //     ref.dispose();
            //   });
            // }));
            // it('should support array require in linking fn', async(() => {
            //   const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
            //   const ng1Module = angular.module('ng1', []);
            //   const parent = () => {
            //     return {controller: Class({constructor: function() { this.parent = 'PARENT';
            //     }})};
            //   };
            //   const ng1 = () => {
            //     return {
            //       scope: {title: '@'},
            //       bindToController: true,
            //       template: '{{parent.parent}}:{{ng1.status}}',
            //       require: ['ng1', '^parent', '?^^notFound'],
            //       controllerAs: 'ctrl',
            //       controller: Class({constructor: function() { this.status = 'WORKS'; }}),
            //       link: function(
            //           scope: any /** TODO #9100 */, element: any /** TODO #9100 */,
            //           attrs: any /** TODO #9100 */, linkControllers: any /** TODO #9100 */) {
            //         expect(linkControllers[0].status).toEqual('WORKS');
            //         expect(linkControllers[1].parent).toEqual('PARENT');
            //         expect(linkControllers[2]).toBe(undefined);
            //         scope.ng1 = linkControllers[0];
            //         scope.parent = linkControllers[1];
            //       }
            //     };
            //   };
            //   ng1Module.directive('parent', parent);
            //   ng1Module.directive('ng1', ng1);
            //   const Ng2 = Component({selector: 'ng2', template: ''}).Class({
            //     constructor: function() {}
            //   });
            //   const Ng2Module = NgModule({
            //                       declarations: [adapter.upgradeNg1Component('ng1'), Ng2],
            //                       imports: [BrowserModule],
            //                       schemas: [NO_ERRORS_SCHEMA],
            //                     }).Class({constructor: function() {}});
            //   ng1Module.directive('ng2', adapter.downgradeNg2Component(Ng2));
            //   const element = html(``);
            //   adapter.bootstrap(element, ['ng1']).ready((ref) => {
            //     expect(multiTrim(document.body.textContent)).toEqual('PARENT:WORKS');
            //     ref.dispose();
            //   });
            // }));
        });
    describe('lifecycle hooks', () => {
      xit('should call `$onChanges()` on controller', () => {});
      xit('should call `$onChanges()` on scope', () => {});
      it('should call `$onInit()` on controller', async(() => {
           // Define `ng1Directive`
           const ng1DirectiveA: angular.IDirective = {
             template: 'Called: {{ called }}',
             bindToController: false,
             controller: class {
               constructor(private $scope: angular.IScope) { $scope['called'] = 'no'; }
               $onInit() { this.$scope['called'] = 'yes'; }
             }
           };
           const ng1DirectiveB: angular.IDirective = {
             template: 'Called: {{ called }}',
             bindToController: true,
             controller: class {
               constructor(private $scope: angular.IScope) { $scope['called'] = 'no'; }
               $onInit() { this.$scope['called'] = 'yes'; }
             }
           };
           // Define `Ng1ComponentFacade`
           @Directive({selector: 'ng1A'})
           class Ng1ComponentAFacade extends UpgradeComponent {
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1A', elementRef, injector);
             }
           }
           @Directive({selector: 'ng1B'})
           class Ng1ComponentBFacade extends UpgradeComponent {
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1B', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({selector: 'ng2', template: ' | '})
           class Ng2Component {
           }
           // Define `ng1Module`
           const ng1Module = angular.module('ng1Module', [])
                                 .directive('ng1A', () => ng1DirectiveA)
                                 .directive('ng1B', () => ng1DirectiveB)
                                 .directive('ng2', downgradeComponent({component: Ng2Component}));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentAFacade, Ng1ComponentBFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             expect(multiTrim(document.body.textContent)).toBe('Called: yes | Called: yes');
           });
         }));
      it('should not call `$onInit()` on scope', async(() => {
           // Define `ng1Directive`
           const ng1DirectiveA: angular.IDirective = {
             template: 'Called: {{ called }}',
             bindToController: false,
             controller: class {
               constructor($scope: angular.IScope) {
                 $scope['called'] = 'no';
                 $scope['$onInit'] = () => $scope['called'] = 'yes';
               }
             }
           };
           const ng1DirectiveB: angular.IDirective = {
             template: 'Called: {{ called }}',
             bindToController: true,
             controller: class {
               constructor($scope: angular.IScope) {
                 $scope['called'] = 'no';
                 $scope['$onInit'] = () => $scope['called'] = 'yes';
               }
             }
           };
           // Define `Ng1ComponentFacade`
           @Directive({selector: 'ng1A'})
           class Ng1ComponentAFacade extends UpgradeComponent {
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1A', elementRef, injector);
             }
           }
           @Directive({selector: 'ng1B'})
           class Ng1ComponentBFacade extends UpgradeComponent {
             constructor(elementRef: ElementRef, injector: Injector) {
               super('ng1B', elementRef, injector);
             }
           }
           // Define `Ng2Component`
           @Component({selector: 'ng2', template: ' | '})
           class Ng2Component {
           }
           // Define `ng1Module`
           const ng1Module = angular.module('ng1Module', [])
                                 .directive('ng1A', () => ng1DirectiveA)
                                 .directive('ng1B', () => ng1DirectiveB)
                                 .directive('ng2', downgradeComponent({component: Ng2Component}));
           // Define `Ng2Module`
           @NgModule({
             declarations: [Ng1ComponentAFacade, Ng1ComponentBFacade, Ng2Component],
             entryComponents: [Ng2Component],
             imports: [BrowserModule, UpgradeModule]
           })
           class Ng2Module {
             ngDoBootstrap() {}
           }
           // Bootstrap
           const element = html(``);
           platformBrowserDynamic().bootstrapModule(Ng2Module).then(ref => {
             var adapter = ref.injector.get(UpgradeModule) as UpgradeModule;
             adapter.bootstrap(element, [ng1Module.name]);
             expect(multiTrim(document.body.textContent)).toBe('Called: no | Called: no');
           });
         }));
      xit('should call `$onPostDigest()` on controller', () => {});
      xit('should not call `$onPostDigest()` on scope', () => {});
      xit('should call `$onDestroy()` on controller', () => {});
      xit('should not call `$onDestroy()` on scope', () => {});
    });
    // it('should support ng2 > ng1 > ng2', async(() => {
    //   const adapter: UpgradeAdapter = new UpgradeAdapter(forwardRef(() => Ng2Module));
    //   const ng1Module = angular.module('ng1', []);
    //   const ng1 = {
    //     template: 'ng1()',
    //   };
    //   ng1Module.component('ng1', ng1);
    //   const Ng2a = Component({selector: 'ng2a', template: 'ng2a()'}).Class({
    //     constructor: function() {}
    //   });
    //   ng1Module.directive('ng2a', adapter.downgradeNg2Component(Ng2a));
    //   const Ng2b =
    //       Component({selector: 'ng2b', template: 'ng2b'}).Class({constructor: function() {}});
    //   ng1Module.directive('ng2b', adapter.downgradeNg2Component(Ng2b));
    //   const Ng2Module = NgModule({
    //                       declarations: [adapter.upgradeNg1Component('ng1'), Ng2a, Ng2b],
    //                       imports: [BrowserModule],
    //                       schemas: [NO_ERRORS_SCHEMA],
    //                     }).Class({constructor: function() {}});
    //   const element = html(`
`);
    //   adapter.bootstrap(element, ['ng1']).ready((ref) => {
    //     expect(multiTrim(document.body.textContent)).toEqual('ng2a(ng1(ng2b))');
    //   });
    // }));
  });
}