In order to support running "compiler-cli" tests that use the "test_support.ts" utilities on Windows with Bazel, we need to imporve the logic that resolves NPM packages and symlinks them into a temporary directory. A more Bazel idiomatic and windows compatible way of resolving Bazel runfiles is to use the "RUNFILES_MANIFEST" if present. This ensures that the NPM packages can be also symlinked on Windows, and tests can execute properly on Windows. Read more about why this is needed here: * https://github.com/bazelbuild/bazel/issues/3726#issue-257062364 PR Close #28352
		
			
				
	
	
		
			106 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			2.8 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 {existsSync, readFileSync, readdirSync, statSync} from 'fs';
 | 
						|
import * as mockFs from 'mock-fs';
 | 
						|
import {join} from 'path';
 | 
						|
const Module = require('module');
 | 
						|
 | 
						|
import {mainNgcc} from '../../src/ngcc/src/main';
 | 
						|
import {getAngularPackagesFromRunfiles} from '../runfile_helpers';
 | 
						|
 | 
						|
describe('ngcc main()', () => {
 | 
						|
  beforeEach(createMockFileSystem);
 | 
						|
  afterEach(restoreRealFileSystem);
 | 
						|
 | 
						|
  it('should run ngcc without errors for fesm2015', () => {
 | 
						|
    const format = 'fesm2015';
 | 
						|
    expect(mainNgcc(['-f', format, '-s', '/node_modules'])).toBe(0);
 | 
						|
  });
 | 
						|
 | 
						|
  it('should run ngcc without errors for fesm5', () => {
 | 
						|
    const format = 'fesm5';
 | 
						|
    expect(mainNgcc(['-f', format, '-s', '/node_modules'])).toBe(0);
 | 
						|
  });
 | 
						|
 | 
						|
  it('should run ngcc without errors for esm2015', () => {
 | 
						|
    const format = 'esm2015';
 | 
						|
    expect(mainNgcc(['-f', format, '-s', '/node_modules'])).toBe(0);
 | 
						|
  });
 | 
						|
 | 
						|
  it('should run ngcc without errors for esm5', () => {
 | 
						|
    const format = 'esm5';
 | 
						|
    expect(mainNgcc(['-f', format, '-s', '/node_modules'])).toBe(0);
 | 
						|
  });
 | 
						|
});
 | 
						|
 | 
						|
 | 
						|
function createMockFileSystem() {
 | 
						|
  mockFs({'/node_modules/@angular': loadAngularPackages()});
 | 
						|
  spyOn(Module, '_resolveFilename').and.callFake(mockResolve);
 | 
						|
}
 | 
						|
 | 
						|
function restoreRealFileSystem() {
 | 
						|
  mockFs.restore();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/** Load the built Angular packages into an in-memory structure. */
 | 
						|
function loadAngularPackages(): Directory {
 | 
						|
  const packagesDirectory: Directory = {};
 | 
						|
 | 
						|
  getAngularPackagesFromRunfiles().forEach(
 | 
						|
      ({name, pkgPath}) => { packagesDirectory[name] = loadDirectory(pkgPath); });
 | 
						|
 | 
						|
  return packagesDirectory;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Load real files from the filesystem into an "in-memory" structure,
 | 
						|
 * which can be used with `mock-fs`.
 | 
						|
 * @param directoryPath the path to the directory we want to load.
 | 
						|
 */
 | 
						|
function loadDirectory(directoryPath: string): Directory {
 | 
						|
  const directory: Directory = {};
 | 
						|
 | 
						|
  readdirSync(directoryPath).forEach(item => {
 | 
						|
    const itemPath = join(directoryPath, item);
 | 
						|
    if (statSync(itemPath).isDirectory()) {
 | 
						|
      directory[item] = loadDirectory(itemPath);
 | 
						|
    } else {
 | 
						|
      directory[item] = readFileSync(itemPath, 'utf-8');
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  return directory;
 | 
						|
}
 | 
						|
 | 
						|
interface Directory {
 | 
						|
  [pathSegment: string]: string|Directory;
 | 
						|
}
 | 
						|
 | 
						|
function mockResolve(p: string): string|null {
 | 
						|
  if (existsSync(p)) {
 | 
						|
    const stat = statSync(p);
 | 
						|
    if (stat.isFile()) {
 | 
						|
      return p;
 | 
						|
    } else if (stat.isDirectory()) {
 | 
						|
      const pIndex = mockResolve(p + '/index');
 | 
						|
      if (pIndex && existsSync(pIndex)) {
 | 
						|
        return pIndex;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  for (const ext of ['.js', '.d.ts']) {
 | 
						|
    if (existsSync(p + ext)) {
 | 
						|
      return p + ext;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return null;
 | 
						|
}
 |