From d96e962da352e69afa5f9c60d433a905cf7c8290 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Tue, 28 Aug 2018 11:32:01 +0100 Subject: [PATCH] test(ivy): mock the filesystem in ngcc main() integration tests (#25557) Bazel does not like the filesystem being modified. This commit a temporary mock filesystem that can be modified as needed. PR Close #25557 --- packages/compiler-cli/test/ngcc/ngcc_spec.ts | 119 ++++++++++++------- 1 file changed, 73 insertions(+), 46 deletions(-) diff --git a/packages/compiler-cli/test/ngcc/ngcc_spec.ts b/packages/compiler-cli/test/ngcc/ngcc_spec.ts index 1247930b87..d8e80225c8 100644 --- a/packages/compiler-cli/test/ngcc/ngcc_spec.ts +++ b/packages/compiler-cli/test/ngcc/ngcc_spec.ts @@ -6,75 +6,102 @@ * 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'; import {mainNgcc} from '../../src/ngcc/src/main'; -import {TestSupport, isInBazel, setup} from '../test_support'; - -const OUTPUT_PATH = 'node_modules_ngtsc'; - -describe('ngcc behavioral tests', () => { +describe('ngcc main()', () => { if (!isInBazel()) { // These tests should be excluded from the non-Bazel build. return; } - // Temporary local debugging aid. Set to `true` to turn on. - const preserveOutput = false; - const onSpecCompleted = (format: string) => { - if (preserveOutput) { - const {tmpdir} = require('os'); - const {cp, mkdir, rm, set} = require('shelljs'); - - const tempRootDir = join(tmpdir(), 'ngcc-spec', format); - const outputDir = OUTPUT_PATH; - - set('-e'); - rm('-rf', tempRootDir); - mkdir('-p', tempRootDir); - cp('-R', join(support.basePath, outputDir), tempRootDir); - - global.console.log(`Copied '${outputDir}' to '${tempRootDir}'.`); - } - }; - - let support: TestSupport; - beforeEach(() => support = setup()); + beforeEach(createMockFileSystem); + afterEach(restoreRealFileSystem); it('should run ngcc without errors for fesm2015', () => { - const commonPath = join(support.basePath, 'node_modules/@angular/common'); + const commonPath = join('/node_modules/@angular/common'); const format = 'fesm2015'; - - expect(mainNgcc([format, commonPath, OUTPUT_PATH])).toBe(0); - - onSpecCompleted(format); + expect(mainNgcc([format, commonPath])).toBe(0); }); it('should run ngcc without errors for fesm5', () => { - const commonPath = join(support.basePath, 'node_modules/@angular/common'); + const commonPath = join('/node_modules/@angular/common'); const format = 'fesm5'; - - expect(mainNgcc([format, commonPath, OUTPUT_PATH])).toBe(0); - - onSpecCompleted(format); + expect(mainNgcc([format, commonPath])).toBe(0); }); it('should run ngcc without errors for esm2015', () => { - const commonPath = join(support.basePath, 'node_modules/@angular/common'); + const commonPath = join('/node_modules/@angular/common'); const format = 'esm2015'; - - expect(mainNgcc([format, commonPath, OUTPUT_PATH])).toBe(0); - - onSpecCompleted(format); + expect(mainNgcc([format, commonPath])).toBe(0); }); it('should run ngcc without errors for esm5', () => { - const commonPath = join(support.basePath, 'node_modules/@angular/common'); + const commonPath = join('/node_modules/@angular/common'); const format = 'esm5'; - - expect(mainNgcc([format, commonPath, OUTPUT_PATH])).toBe(0); - - onSpecCompleted(format); + expect(mainNgcc([format, commonPath])).toBe(0); }); }); + + +function createMockFileSystem() { + const packagesPath = join(process.env.TEST_SRCDIR, 'angular/packages'); + mockFs({'/node_modules/@angular': loadPackages(packagesPath)}); +} + +function restoreRealFileSystem() { + mockFs.restore(); +} + + +/** + * Load the built Angular packages into an in-memory structure. + * @param packagesPath the path to the folder containing the built packages. + */ +function loadPackages(packagesPath: string): Directory { + const packagesDirectory: Directory = {}; + readdirSync(packagesPath).forEach(name => { + const packagePath = join(packagesPath, name); + if (!statSync(packagePath).isDirectory()) { + return; + } + const npmPackagePath = join(packagePath, 'npm_package'); + if (!existsSync(npmPackagePath)) { + return; + } + packagesDirectory[name] = loadDirectory(npmPackagePath); + }); + 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 isInBazel() { + return process.env.TEST_SRCDIR != null; +} \ No newline at end of file