Usages of `NgTools_InternalApi_NG_2` from `@angular/compiler-cli` will now throw an error. Adds `listLazyRoutes` to `@angular/compiler-cli/ngtools2.ts` for getting the lazy routes of a `ng.Program`. PR Close #19836
		
			
				
	
	
		
			178 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			178 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
/**
 | 
						|
 * @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 * as ts from 'typescript';
 | 
						|
 | 
						|
import {METADATA_VERSION, MetadataCollector, ModuleMetadata} from '../../src/metadata';
 | 
						|
import {MetadataReaderHost, readMetadata} from '../../src/transformers/metadata_reader';
 | 
						|
import {Directory, Entry, MockAotContext} from '../mocks';
 | 
						|
 | 
						|
describe('metadata reader', () => {
 | 
						|
  let host: MetadataReaderHost;
 | 
						|
 | 
						|
  beforeEach(() => {
 | 
						|
    const context = new MockAotContext('/tmp/src', clone(FILES));
 | 
						|
    const metadataCollector = new MetadataCollector();
 | 
						|
    host = {
 | 
						|
      fileExists: (fileName) => context.fileExists(fileName),
 | 
						|
      readFile: (fileName) => context.readFile(fileName),
 | 
						|
      getSourceFileMetadata: (fileName) => {
 | 
						|
        const sourceText = context.readFile(fileName);
 | 
						|
        return sourceText != null ?
 | 
						|
            metadataCollector.getMetadata(
 | 
						|
                ts.createSourceFile(fileName, sourceText, ts.ScriptTarget.Latest)) :
 | 
						|
            undefined;
 | 
						|
      },
 | 
						|
    };
 | 
						|
  });
 | 
						|
 | 
						|
 | 
						|
  it('should be able to read a metadata file', () => {
 | 
						|
    expect(readMetadata('node_modules/@angular/core.d.ts', host)).toEqual([
 | 
						|
      {__symbolic: 'module', version: METADATA_VERSION, metadata: {foo: {__symbolic: 'class'}}}
 | 
						|
    ]);
 | 
						|
  });
 | 
						|
 | 
						|
  it('should be able to read metadata from an otherwise unused .d.ts file ', () => {
 | 
						|
    expect(readMetadata('node_modules/@angular/unused.d.ts', host)).toEqual([dummyMetadata]);
 | 
						|
  });
 | 
						|
 | 
						|
  it('should be able to read empty metadata ',
 | 
						|
     () => { expect(readMetadata('node_modules/@angular/empty.d.ts', host)).toEqual([]); });
 | 
						|
 | 
						|
  it('should return undefined for missing modules',
 | 
						|
     () => { expect(readMetadata('node_modules/@angular/missing.d.ts', host)).toBeUndefined(); });
 | 
						|
 | 
						|
  it(`should add missing v${METADATA_VERSION} metadata from v1 metadata and .d.ts files`, () => {
 | 
						|
    expect(readMetadata('metadata_versions/v1.d.ts', host)).toEqual([
 | 
						|
      {__symbolic: 'module', version: 1, metadata: {foo: {__symbolic: 'class'}}}, {
 | 
						|
        __symbolic: 'module',
 | 
						|
        version: METADATA_VERSION,
 | 
						|
        metadata: {
 | 
						|
          foo: {__symbolic: 'class'},
 | 
						|
          aType: {__symbolic: 'interface'},
 | 
						|
          Bar: {__symbolic: 'class', members: {ngOnInit: [{__symbolic: 'method'}]}},
 | 
						|
          BarChild: {__symbolic: 'class', extends: {__symbolic: 'reference', name: 'Bar'}},
 | 
						|
          ReExport: {__symbolic: 'reference', module: './lib/utils2', name: 'ReExport'},
 | 
						|
        },
 | 
						|
        exports: [{from: './lib/utils2', export: ['Export']}],
 | 
						|
      }
 | 
						|
    ]);
 | 
						|
  });
 | 
						|
 | 
						|
  it(`should upgrade a missing metadata file into v${METADATA_VERSION}`, () => {
 | 
						|
    expect(readMetadata('metadata_versions/v1_empty.d.ts', host)).toEqual([{
 | 
						|
      __symbolic: 'module',
 | 
						|
      version: METADATA_VERSION,
 | 
						|
      metadata: {},
 | 
						|
      exports: [{from: './lib/utils'}]
 | 
						|
    }]);
 | 
						|
  });
 | 
						|
 | 
						|
  it(`should upgrade v3 metadata into v${METADATA_VERSION}`, () => {
 | 
						|
    expect(readMetadata('metadata_versions/v3.d.ts', host)).toEqual([
 | 
						|
      {__symbolic: 'module', version: 3, metadata: {foo: {__symbolic: 'class'}}}, {
 | 
						|
        __symbolic: 'module',
 | 
						|
        version: METADATA_VERSION,
 | 
						|
        metadata: {
 | 
						|
          foo: {__symbolic: 'class'},
 | 
						|
          aType: {__symbolic: 'interface'},
 | 
						|
          Bar: {__symbolic: 'class', members: {ngOnInit: [{__symbolic: 'method'}]}},
 | 
						|
          BarChild: {__symbolic: 'class', extends: {__symbolic: 'reference', name: 'Bar'}},
 | 
						|
          ReExport: {__symbolic: 'reference', module: './lib/utils2', name: 'ReExport'},
 | 
						|
        }
 | 
						|
        // Note: exports is missing because it was elided in the original.
 | 
						|
      }
 | 
						|
    ]);
 | 
						|
  });
 | 
						|
});
 | 
						|
 | 
						|
const dummyModule = 'export let foo: any[];';
 | 
						|
const dummyMetadata: ModuleMetadata = {
 | 
						|
  __symbolic: 'module',
 | 
						|
  version: METADATA_VERSION,
 | 
						|
  metadata:
 | 
						|
      {foo: {__symbolic: 'error', message: 'Variable not initialized', line: 0, character: 11}}
 | 
						|
};
 | 
						|
const FILES: Entry = {
 | 
						|
  'tmp': {
 | 
						|
    'src': {
 | 
						|
      'main.ts': `
 | 
						|
        import * as c from '@angular/core';
 | 
						|
        import * as r from '@angular/router';
 | 
						|
        import * as u from './lib/utils';
 | 
						|
        import * as cs from './lib/collections';
 | 
						|
        import * as u2 from './lib2/utils2';
 | 
						|
      `,
 | 
						|
      'lib': {
 | 
						|
        'utils.ts': dummyModule,
 | 
						|
        'collections.ts': dummyModule,
 | 
						|
      },
 | 
						|
      'lib2': {'utils2.ts': dummyModule},
 | 
						|
      'node_modules': {
 | 
						|
        '@angular': {
 | 
						|
          'core.d.ts': dummyModule,
 | 
						|
          'core.metadata.json':
 | 
						|
              `{"__symbolic":"module", "version": ${METADATA_VERSION}, "metadata": {"foo": {"__symbolic": "class"}}}`,
 | 
						|
          'router': {'index.d.ts': dummyModule, 'src': {'providers.d.ts': dummyModule}},
 | 
						|
          'unused.d.ts': dummyModule,
 | 
						|
          'empty.d.ts': 'export declare var a: string;',
 | 
						|
          'empty.metadata.json': '[]',
 | 
						|
        }
 | 
						|
      },
 | 
						|
      'metadata_versions': {
 | 
						|
        'v1.d.ts': `
 | 
						|
          import {ReExport} from './lib/utils2';
 | 
						|
          export {ReExport};
 | 
						|
 | 
						|
          export {Export} from './lib/utils2';
 | 
						|
 | 
						|
          export type aType = number;
 | 
						|
 | 
						|
          export declare class Bar {
 | 
						|
            ngOnInit() {}
 | 
						|
          }
 | 
						|
          export declare class BarChild extends Bar {}
 | 
						|
        `,
 | 
						|
        'v1.metadata.json':
 | 
						|
            `{"__symbolic":"module", "version": 1, "metadata": {"foo": {"__symbolic": "class"}}}`,
 | 
						|
        'v1_empty.d.ts': `
 | 
						|
          export * from './lib/utils';
 | 
						|
        `,
 | 
						|
        'v3.d.ts': `
 | 
						|
          import {ReExport} from './lib/utils2';
 | 
						|
          export {ReExport};
 | 
						|
 | 
						|
          export {Export} from './lib/utils2';
 | 
						|
 | 
						|
          export type aType = number;
 | 
						|
 | 
						|
          export declare class Bar {
 | 
						|
            ngOnInit() {}
 | 
						|
          }
 | 
						|
          export declare class BarChild extends Bar {}
 | 
						|
        `,
 | 
						|
        'v3.metadata.json':
 | 
						|
            `{"__symbolic":"module", "version": 3, "metadata": {"foo": {"__symbolic": "class"}}}`,
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
function clone(entry: Entry): Entry {
 | 
						|
  if (typeof entry === 'string') {
 | 
						|
    return entry;
 | 
						|
  } else {
 | 
						|
    const result: Directory = {};
 | 
						|
    for (const name in entry) {
 | 
						|
      result[name] = clone(entry[name]);
 | 
						|
    }
 | 
						|
    return result;
 | 
						|
  }
 | 
						|
}
 |