<!DOCTYPE html>
<html>

  <head>
    <script src="https://code.angularjs.org/1.5.5/angular.js"></script>
    <script src="https://code.angularjs.org/tools/traceur-runtime.js"></script>
    <script src="https://code.angularjs.org/tools/system.js"></script>
    <script src="https://code.angularjs.org/tools/typescript.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.2/jasmine.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.2/jasmine-html.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.2/boot.js"></script>

    <script src="config.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.17/angular2-polyfills.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.17/Rx.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.17/angular2.dev.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.17/testing.dev.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.17/upgrade.js"></script>
    <script>
      System.import('angular2/src/platform/browser/browser_adapter')
        .then(function(browser_adapter) {
          browser_adapter.BrowserDomAdapter.makeCurrent();
          System.import('app').then(function() {
            window.onload();
          });
        });
    </script>
  </head>

  <body>
    <div><ng1 value="'NG1_VALUE'"></ng1></div>
    <div><ng2></ng2></div>
  </body>

</html>
System.config({
  //use typescript for compilation
  transpiler: 'typescript',
  //typescript compiler options
  typescriptOptions: {
    emitDecoratorMetadata: true
  },
  //map tells the System loader where to look for things
  map: {
    app: "./src"
  },
  //packages defines our app package
  packages: {
    app: {
      main: './main.ts',
      defaultExtension: 'ts'
    }
  }
});
import {bootstrap, View} from 'angular2/platform/browser';
import {Component} from 'angular2/core';
import {UpgradeAdapter} from 'angular2/upgrade';

const upgradeAdapter = new UpgradeAdapter();

/*
 * NG1 
 */
let ng1App = angular.module('ng1App', []);
ng1App.component('ng1', {
    bindings: {
      value: '='
    },
    template: `<span>NG1 => </span><span ng-bind="$ctrl.value"></span>`
  });

/*
 * NG2
 */

@Component({
  directives: [upgradeAdapter.upgradeNg1Component('ng1')],
  selector: 'ng2',
  template: '<span>NG2 => </span><ng1 [value]="\'NG2_VALUE\'"></ng1>'
})
export class Ng2 {
  
  value:string = 'VALUE';
  
  constructor() {
    this.value = 'VALUE';
  }
}

ng1App.directive('ng2', upgradeAdapter.downgradeNg2Component(Ng2));


import {
  async,
  beforeEach,
  describe,
  it,
  inject,
  injectAsync,
  setBaseTestProviders,
  ComponentFixture,
  TestComponentBuilder
} from 'angular2/testing';

import {
  TEST_BROWSER_PLATFORM_PROVIDERS,
  TEST_BROWSER_APPLICATION_PROVIDERS
} from 'angular2/platform/testing/browser';

setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS, TEST_BROWSER_APPLICATION_PROVIDERS);

describe('angular2 upgrade', () => {

  it('should load ng1 components into ng2 components',
    inject([TestComponentBuilder], (tcb) => {
      
      let ng1Style = true;
      let playgroundElement;
      let resolve;
      let reject;
      let promise = new Promise((_resolve, _reject) => {
          resolve = _resolve;
          reject = _reject;
      });
      
      /* Testing in the angular 1 style works.
       * It probably works with $compile etc...*/
      if (ng1Style === true) {
        
        playgroundElement = document.createElement('div');
        document.body.appendChild(playgroundElement);
        
        playgroundElement.innerHTML = '<ng2></ng2>';
        
        upgradeAdapter.bootstrap(playgroundElement, ['ng1App'])
          .ready(() => {
            
            expect(playgroundElement.innerText)
              .toEqual('NG2 => NG1 => NG2_VALUE');
              
              resolve();
              
          });
      }
      
      /* But this doesn't work.
       * It fails with "No provider for $scope" error.
       * It seems for me that if an ng2 component is using an ng1 component
       * then the only way to use it is to downgrade it to ng1. */
      else {
        upgradeAdapter.bootstrap(playgroundElement, ['ng1App'])
          .ready(() => {
            tcb.createAsync(Ng2)
              .then((componentFixture) => {
                const element = componentFixture.nativeElement;
                componentFixture.detectChanges();
                console.log(element.html());
                resolve();
              })
              .catch(reject);
          });
      }
      
      return promise;
      
    });
  );
  
});

/*
 * Bootstrap.
 */
// upgradeAdapter.bootstrap(document.body, ['ng1App']);

// bootstrap(Ng2)
//   .catch(err => console.error(err));