refactor(ivy): ngcc - add MockFileSystem (#29643)

PR Close #29643
This commit is contained in:
Pete Bacon Darwin
2019-04-28 20:47:57 +01:00
committed by Andrew Kushnir
parent 16d7dde2ad
commit ef861958a9
14 changed files with 408 additions and 304 deletions

View File

@ -5,16 +5,12 @@
* 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 {readFileSync} from 'fs';
import * as mockFs from 'mock-fs';
import {AbsoluteFsPath} from '../../../src/ngtsc/path';
import {NodeJSFileSystem} from '../../src/file_system/node_js_file_system';
import {hasBeenProcessed, markAsProcessed} from '../../src/packages/build_marker';
import {MockFileSystem} from '../helpers/mock_file_system';
function createMockFileSystem() {
mockFs({
return new MockFileSystem({
'/node_modules/@angular/common': {
'package.json': `{
"fesm2015": "./fesm2015/common.js",
@ -90,38 +86,31 @@ function createMockFileSystem() {
});
}
function restoreRealFileSystem() {
mockFs.restore();
}
describe('Marker files', () => {
beforeEach(createMockFileSystem);
afterEach(restoreRealFileSystem);
const COMMON_PACKAGE_PATH = AbsoluteFsPath.from('/node_modules/@angular/common/package.json');
describe('markAsProcessed', () => {
it('should write a property in the package.json containing the version placeholder', () => {
let pkg = JSON.parse(readFileSync(COMMON_PACKAGE_PATH, 'utf8'));
expect(pkg.__processed_by_ivy_ngcc__).toBeUndefined();
expect(pkg.__processed_by_ivy_ngcc__).toBeUndefined();
const fs = createMockFileSystem();
const fs = new NodeJSFileSystem();
let pkg = JSON.parse(fs.readFile(COMMON_PACKAGE_PATH));
expect(pkg.__processed_by_ivy_ngcc__).toBeUndefined();
expect(pkg.__processed_by_ivy_ngcc__).toBeUndefined();
markAsProcessed(fs, pkg, COMMON_PACKAGE_PATH, 'fesm2015');
pkg = JSON.parse(readFileSync(COMMON_PACKAGE_PATH, 'utf8'));
pkg = JSON.parse(fs.readFile(COMMON_PACKAGE_PATH));
expect(pkg.__processed_by_ivy_ngcc__.fesm2015).toEqual('0.0.0-PLACEHOLDER');
expect(pkg.__processed_by_ivy_ngcc__.esm5).toBeUndefined();
markAsProcessed(fs, pkg, COMMON_PACKAGE_PATH, 'esm5');
pkg = JSON.parse(readFileSync(COMMON_PACKAGE_PATH, 'utf8'));
pkg = JSON.parse(fs.readFile(COMMON_PACKAGE_PATH));
expect(pkg.__processed_by_ivy_ngcc__.fesm2015).toEqual('0.0.0-PLACEHOLDER');
expect(pkg.__processed_by_ivy_ngcc__.esm5).toEqual('0.0.0-PLACEHOLDER');
});
it('should update the packageJson object in-place', () => {
const fs = new NodeJSFileSystem();
let pkg = JSON.parse(readFileSync(COMMON_PACKAGE_PATH, 'utf8'));
const fs = createMockFileSystem();
let pkg = JSON.parse(fs.readFile(COMMON_PACKAGE_PATH));
expect(pkg.__processed_by_ivy_ngcc__).toBeUndefined();
markAsProcessed(fs, pkg, COMMON_PACKAGE_PATH, 'fesm2015');
expect(pkg.__processed_by_ivy_ngcc__.fesm2015).toEqual('0.0.0-PLACEHOLDER');

View File

@ -6,15 +6,13 @@
* found in the LICENSE file at https://angular.io/license
*/
import * as mockFs from 'mock-fs';
import {AbsoluteFsPath} from '../../../src/ngtsc/path';
import {DependencyResolver} from '../../src/dependencies/dependency_resolver';
import {EsmDependencyHost} from '../../src/dependencies/esm_dependency_host';
import {ModuleResolver} from '../../src/dependencies/module_resolver';
import {NodeJSFileSystem} from '../../src/file_system/node_js_file_system';
import {EntryPoint} from '../../src/packages/entry_point';
import {EntryPointFinder} from '../../src/packages/entry_point_finder';
import {MockFileSystem, SymLink} from '../helpers/mock_file_system';
import {MockLogger} from '../helpers/mock_logger';
const _ = AbsoluteFsPath.from;
@ -23,7 +21,7 @@ describe('findEntryPoints()', () => {
let resolver: DependencyResolver;
let finder: EntryPointFinder;
beforeEach(() => {
const fs = new NodeJSFileSystem();
const fs = createMockFileSystem();
resolver =
new DependencyResolver(new MockLogger(), new EsmDependencyHost(fs, new ModuleResolver(fs)));
spyOn(resolver, 'sortEntryPointsByDependency').and.callFake((entryPoints: EntryPoint[]) => {
@ -31,8 +29,6 @@ describe('findEntryPoints()', () => {
});
finder = new EntryPointFinder(fs, new MockLogger(), resolver);
});
beforeEach(createMockFileSystem);
afterEach(restoreRealFileSystem);
it('should find sub-entry-points within a package', () => {
const {entryPoints} = finder.findEntryPoints(_('/sub_entry_points'));
@ -90,7 +86,7 @@ describe('findEntryPoints()', () => {
});
function createMockFileSystem() {
mockFs({
return new MockFileSystem({
'/sub_entry_points': {
'common': {
'package.json': createPackageJson('common'),
@ -142,7 +138,7 @@ describe('findEntryPoints()', () => {
},
},
'/symlinked_folders': {
'common': mockFs.symlink({path: '/sub_entry_points/common'}),
'common': new SymLink(_('/sub_entry_points/common')),
},
'/nested_node_modules': {
'outer': {
@ -158,7 +154,6 @@ describe('findEntryPoints()', () => {
},
});
}
function restoreRealFileSystem() { mockFs.restore(); }
});
function createPackageJson(packageName: string): string {

View File

@ -6,25 +6,20 @@
* found in the LICENSE file at https://angular.io/license
*/
import {readFileSync} from 'fs';
import * as mockFs from 'mock-fs';
import {AbsoluteFsPath} from '../../../src/ngtsc/path';
import {NodeJSFileSystem} from '../../src/file_system/node_js_file_system';
import {FileSystem} from '../../src/file_system/file_system';
import {getEntryPointInfo} from '../../src/packages/entry_point';
import {MockFileSystem} from '../helpers/mock_file_system';
import {MockLogger} from '../helpers/mock_logger';
const _ = AbsoluteFsPath.fromUnchecked;
describe('getEntryPointInfo()', () => {
beforeEach(createMockFileSystem);
afterEach(restoreRealFileSystem);
const SOME_PACKAGE = _('/some_package');
it('should return an object containing absolute paths to the formats of the specified entry-point',
() => {
const fs = new NodeJSFileSystem();
const fs = createMockFileSystem();
const entryPoint = getEntryPointInfo(
fs, new MockLogger(), SOME_PACKAGE, _('/some_package/valid_entry_point'));
expect(entryPoint).toEqual({
@ -32,20 +27,20 @@ describe('getEntryPointInfo()', () => {
package: SOME_PACKAGE,
path: _('/some_package/valid_entry_point'),
typings: _(`/some_package/valid_entry_point/valid_entry_point.d.ts`),
packageJson: loadPackageJson('/some_package/valid_entry_point'),
packageJson: loadPackageJson(fs, '/some_package/valid_entry_point'),
compiledByAngular: true,
});
});
it('should return null if there is no package.json at the entry-point path', () => {
const fs = new NodeJSFileSystem();
const fs = createMockFileSystem();
const entryPoint = getEntryPointInfo(
fs, new MockLogger(), SOME_PACKAGE, _('/some_package/missing_package_json'));
expect(entryPoint).toBe(null);
});
it('should return null if there is no typings or types field in the package.json', () => {
const fs = new NodeJSFileSystem();
const fs = createMockFileSystem();
const entryPoint =
getEntryPointInfo(fs, new MockLogger(), SOME_PACKAGE, _('/some_package/missing_typings'));
expect(entryPoint).toBe(null);
@ -53,7 +48,7 @@ describe('getEntryPointInfo()', () => {
it('should return an object with `compiledByAngular` set to false if there is no metadata.json file next to the typing file',
() => {
const fs = new NodeJSFileSystem();
const fs = createMockFileSystem();
const entryPoint = getEntryPointInfo(
fs, new MockLogger(), SOME_PACKAGE, _('/some_package/missing_metadata'));
expect(entryPoint).toEqual({
@ -61,13 +56,13 @@ describe('getEntryPointInfo()', () => {
package: SOME_PACKAGE,
path: _('/some_package/missing_metadata'),
typings: _(`/some_package/missing_metadata/missing_metadata.d.ts`),
packageJson: loadPackageJson('/some_package/missing_metadata'),
packageJson: loadPackageJson(fs, '/some_package/missing_metadata'),
compiledByAngular: false,
});
});
it('should work if the typings field is named `types', () => {
const fs = new NodeJSFileSystem();
const fs = createMockFileSystem();
const entryPoint = getEntryPointInfo(
fs, new MockLogger(), SOME_PACKAGE, _('/some_package/types_rather_than_typings'));
expect(entryPoint).toEqual({
@ -75,13 +70,13 @@ describe('getEntryPointInfo()', () => {
package: SOME_PACKAGE,
path: _('/some_package/types_rather_than_typings'),
typings: _(`/some_package/types_rather_than_typings/types_rather_than_typings.d.ts`),
packageJson: loadPackageJson('/some_package/types_rather_than_typings'),
packageJson: loadPackageJson(fs, '/some_package/types_rather_than_typings'),
compiledByAngular: true,
});
});
it('should work with Angular Material style package.json', () => {
const fs = new NodeJSFileSystem();
const fs = createMockFileSystem();
const entryPoint =
getEntryPointInfo(fs, new MockLogger(), SOME_PACKAGE, _('/some_package/material_style'));
expect(entryPoint).toEqual({
@ -89,13 +84,13 @@ describe('getEntryPointInfo()', () => {
package: SOME_PACKAGE,
path: _('/some_package/material_style'),
typings: _(`/some_package/material_style/material_style.d.ts`),
packageJson: JSON.parse(readFileSync('/some_package/material_style/package.json', 'utf8')),
packageJson: loadPackageJson(fs, '/some_package/material_style'),
compiledByAngular: true,
});
});
it('should return null if the package.json is not valid JSON', () => {
const fs = new NodeJSFileSystem();
const fs = createMockFileSystem();
const entryPoint = getEntryPointInfo(
fs, new MockLogger(), SOME_PACKAGE, _('/some_package/unexpected_symbols'));
expect(entryPoint).toBe(null);
@ -103,7 +98,7 @@ describe('getEntryPointInfo()', () => {
});
function createMockFileSystem() {
mockFs({
return new MockFileSystem({
'/some_package': {
'valid_entry_point': {
'package.json': createPackageJson('valid_entry_point'),
@ -150,10 +145,6 @@ function createMockFileSystem() {
});
}
function restoreRealFileSystem() {
mockFs.restore();
}
function createPackageJson(
packageName: string, {excludes}: {excludes?: string[]} = {},
typingsProp: string = 'typings'): string {
@ -172,6 +163,6 @@ function createPackageJson(
return JSON.stringify(packageJson);
}
export function loadPackageJson(packagePath: string) {
return JSON.parse(readFileSync(packagePath + '/package.json', 'utf8'));
export function loadPackageJson(fs: FileSystem, packagePath: string) {
return JSON.parse(fs.readFile(_(packagePath + '/package.json')));
}