parent
16d7dde2ad
commit
ef861958a9
|
@ -12,14 +12,16 @@ import {Decorator} from '../../../src/ngtsc/reflection';
|
|||
import {DecoratorHandler, DetectResult} from '../../../src/ngtsc/transform';
|
||||
import {CompiledClass, DecorationAnalyses, DecorationAnalyzer} from '../../src/analysis/decoration_analyzer';
|
||||
import {NgccReferencesRegistry} from '../../src/analysis/ngcc_references_registry';
|
||||
import {NodeJSFileSystem} from '../../src/file_system/node_js_file_system';
|
||||
import {Esm2015ReflectionHost} from '../../src/host/esm2015_host';
|
||||
import {Folder, MockFileSystem} from '../helpers/mock_file_system';
|
||||
import {MockLogger} from '../helpers/mock_logger';
|
||||
import {makeTestBundleProgram} from '../helpers/utils';
|
||||
import {createFileSystemFromProgramFiles, makeTestBundleProgram} from '../helpers/utils';
|
||||
|
||||
const _ = AbsoluteFsPath.fromUnchecked;
|
||||
|
||||
const TEST_PROGRAM = [
|
||||
{
|
||||
name: 'test.js',
|
||||
name: _('/test.js'),
|
||||
contents: `
|
||||
import {Component, Directive, Injectable} from '@angular/core';
|
||||
|
||||
|
@ -34,7 +36,7 @@ const TEST_PROGRAM = [
|
|||
`,
|
||||
},
|
||||
{
|
||||
name: 'other.js',
|
||||
name: _('/other.js'),
|
||||
contents: `
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
|
@ -46,7 +48,7 @@ const TEST_PROGRAM = [
|
|||
|
||||
const INTERNAL_COMPONENT_PROGRAM = [
|
||||
{
|
||||
name: 'entrypoint.js',
|
||||
name: _('/entrypoint.js'),
|
||||
contents: `
|
||||
import {Component, NgModule} from '@angular/core';
|
||||
import {ImportedComponent} from './component';
|
||||
|
@ -62,7 +64,7 @@ const INTERNAL_COMPONENT_PROGRAM = [
|
|||
`
|
||||
},
|
||||
{
|
||||
name: 'component.js',
|
||||
name: _('/component.js'),
|
||||
contents: `
|
||||
import {Component} from '@angular/core';
|
||||
export class ImportedComponent {}
|
||||
|
@ -137,7 +139,7 @@ describe('DecorationAnalyzer', () => {
|
|||
const reflectionHost =
|
||||
new Esm2015ReflectionHost(new MockLogger(), false, program.getTypeChecker());
|
||||
const referencesRegistry = new NgccReferencesRegistry(reflectionHost);
|
||||
const fs = new NodeJSFileSystem();
|
||||
const fs = new MockFileSystem(createFileSystemFromProgramFiles(...progArgs));
|
||||
const analyzer = new DecorationAnalyzer(
|
||||
fs, program, options, host, program.getTypeChecker(), reflectionHost, referencesRegistry,
|
||||
[AbsoluteFsPath.fromUnchecked('/')], false);
|
||||
|
|
|
@ -9,8 +9,8 @@ import {AbsoluteFsPath} from '../../../src/ngtsc/path';
|
|||
import {DependencyResolver, SortedEntryPointsInfo} 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 {MockFileSystem} from '../helpers/mock_file_system';
|
||||
import {MockLogger} from '../helpers/mock_logger';
|
||||
|
||||
const _ = AbsoluteFsPath.from;
|
||||
|
@ -19,7 +19,7 @@ describe('DependencyResolver', () => {
|
|||
let host: EsmDependencyHost;
|
||||
let resolver: DependencyResolver;
|
||||
beforeEach(() => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const fs = new MockFileSystem();
|
||||
host = new EsmDependencyHost(fs, new ModuleResolver(fs));
|
||||
resolver = new DependencyResolver(new MockLogger(), host);
|
||||
});
|
||||
|
|
|
@ -5,27 +5,23 @@
|
|||
* 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 mockFs from 'mock-fs';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {AbsoluteFsPath} from '../../../src/ngtsc/path';
|
||||
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 {MockFileSystem} from '../helpers/mock_file_system';
|
||||
|
||||
const _ = AbsoluteFsPath.from;
|
||||
|
||||
describe('DependencyHost', () => {
|
||||
let host: EsmDependencyHost;
|
||||
beforeEach(() => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const fs = createMockFileSystem();
|
||||
host = new EsmDependencyHost(fs, new ModuleResolver(fs));
|
||||
});
|
||||
|
||||
describe('getDependencies()', () => {
|
||||
beforeEach(createMockFileSystem);
|
||||
afterEach(restoreRealFileSystem);
|
||||
|
||||
it('should not generate a TS AST if the source does not contain any imports or re-exports',
|
||||
() => {
|
||||
spyOn(ts, 'createSourceFile');
|
||||
|
@ -98,7 +94,7 @@ describe('DependencyHost', () => {
|
|||
});
|
||||
|
||||
it('should support `paths` alias mappings when resolving modules', () => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const fs = createMockFileSystem();
|
||||
host = new EsmDependencyHost(fs, new ModuleResolver(fs, {
|
||||
baseUrl: '/dist',
|
||||
paths: {
|
||||
|
@ -115,9 +111,10 @@ describe('DependencyHost', () => {
|
|||
expect(missing.size).toBe(0);
|
||||
expect(deepImports.size).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
function createMockFileSystem() {
|
||||
mockFs({
|
||||
return new MockFileSystem({
|
||||
'/no/imports/or/re-exports/index.js': '// some text but no import-like statements',
|
||||
'/no/imports/or/re-exports/package.json': '{"esm2015": "./index.js"}',
|
||||
'/no/imports/or/re-exports/index.metadata.json': 'MOCK METADATA',
|
||||
|
@ -127,8 +124,7 @@ describe('DependencyHost', () => {
|
|||
'/external/re-exports/index.js': `export {X} from 'lib-1';\nexport {Y} from 'lib-1/sub-1';`,
|
||||
'/external/re-exports/package.json': '{"esm2015": "./index.js"}',
|
||||
'/external/re-exports/index.metadata.json': 'MOCK METADATA',
|
||||
'/external/imports-missing/index.js':
|
||||
`import {X} from 'lib-1';\nimport {Y} from 'missing';`,
|
||||
'/external/imports-missing/index.js': `import {X} from 'lib-1';\nimport {Y} from 'missing';`,
|
||||
'/external/imports-missing/package.json': '{"esm2015": "./index.js"}',
|
||||
'/external/imports-missing/index.metadata.json': 'MOCK METADATA',
|
||||
'/external/deep-import/index.js': `import {Y} from 'lib-1/deep/import';`,
|
||||
|
@ -174,9 +170,6 @@ describe('DependencyHost', () => {
|
|||
});
|
||||
}
|
||||
|
||||
function restoreRealFileSystem() { mockFs.restore(); }
|
||||
});
|
||||
|
||||
describe('isStringImportOrReexport', () => {
|
||||
it('should return true if the statement is an import', () => {
|
||||
expect(host.isStringImportOrReexport(createStatement('import {X} from "some/x";')))
|
||||
|
|
|
@ -5,17 +5,14 @@
|
|||
* 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 mockFs from 'mock-fs';
|
||||
|
||||
import {AbsoluteFsPath} from '../../../src/ngtsc/path';
|
||||
import {ModuleResolver, ResolvedDeepImport, ResolvedExternalModule, ResolvedRelativeModule} from '../../src/dependencies/module_resolver';
|
||||
import {NodeJSFileSystem} from '../../src/file_system/node_js_file_system';
|
||||
import {MockFileSystem} from '../helpers/mock_file_system';
|
||||
|
||||
const _ = AbsoluteFsPath.from;
|
||||
|
||||
function createMockFileSystem() {
|
||||
mockFs({
|
||||
return new MockFileSystem({
|
||||
'/libs': {
|
||||
'local-package': {
|
||||
'package.json': 'PACKAGE.JSON for local-package',
|
||||
|
@ -68,19 +65,12 @@ function createMockFileSystem() {
|
|||
});
|
||||
}
|
||||
|
||||
function restoreRealFileSystem() {
|
||||
mockFs.restore();
|
||||
}
|
||||
|
||||
describe('ModuleResolver', () => {
|
||||
beforeEach(createMockFileSystem);
|
||||
afterEach(restoreRealFileSystem);
|
||||
|
||||
describe('resolveModule()', () => {
|
||||
describe('with relative paths', () => {
|
||||
it('should resolve sibling, child and aunt modules', () => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const resolver = new ModuleResolver(fs);
|
||||
const resolver = new ModuleResolver(createMockFileSystem());
|
||||
expect(resolver.resolveModuleImport('./x', _('/libs/local-package/index.js')))
|
||||
.toEqual(new ResolvedRelativeModule(_('/libs/local-package/x.js')));
|
||||
expect(resolver.resolveModuleImport('./sub-folder', _('/libs/local-package/index.js')))
|
||||
|
@ -90,16 +80,14 @@ describe('ModuleResolver', () => {
|
|||
});
|
||||
|
||||
it('should return `null` if the resolved module relative module does not exist', () => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const resolver = new ModuleResolver(fs);
|
||||
const resolver = new ModuleResolver(createMockFileSystem());
|
||||
expect(resolver.resolveModuleImport('./y', _('/libs/local-package/index.js'))).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with non-mapped external paths', () => {
|
||||
it('should resolve to the package.json of a local node_modules package', () => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const resolver = new ModuleResolver(fs);
|
||||
const resolver = new ModuleResolver(createMockFileSystem());
|
||||
expect(resolver.resolveModuleImport('package-1', _('/libs/local-package/index.js')))
|
||||
.toEqual(new ResolvedExternalModule(_('/libs/local-package/node_modules/package-1')));
|
||||
expect(
|
||||
|
@ -110,8 +98,7 @@ describe('ModuleResolver', () => {
|
|||
});
|
||||
|
||||
it('should resolve to the package.json of a higher node_modules package', () => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const resolver = new ModuleResolver(fs);
|
||||
const resolver = new ModuleResolver(createMockFileSystem());
|
||||
expect(resolver.resolveModuleImport('package-2', _('/libs/local-package/index.js')))
|
||||
.toEqual(new ResolvedExternalModule(_('/libs/node_modules/package-2')));
|
||||
expect(resolver.resolveModuleImport('top-package', _('/libs/local-package/index.js')))
|
||||
|
@ -119,23 +106,20 @@ describe('ModuleResolver', () => {
|
|||
});
|
||||
|
||||
it('should return `null` if the package cannot be found', () => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const resolver = new ModuleResolver(fs);
|
||||
const resolver = new ModuleResolver(createMockFileSystem());
|
||||
expect(resolver.resolveModuleImport('missing-2', _('/libs/local-package/index.js')))
|
||||
.toBe(null);
|
||||
});
|
||||
|
||||
it('should return `null` if the package is not accessible because it is in a inner node_modules package',
|
||||
() => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const resolver = new ModuleResolver(fs);
|
||||
const resolver = new ModuleResolver(createMockFileSystem());
|
||||
expect(resolver.resolveModuleImport('package-3', _('/libs/local-package/index.js')))
|
||||
.toBe(null);
|
||||
});
|
||||
|
||||
it('should identify deep imports into an external module', () => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const resolver = new ModuleResolver(fs);
|
||||
const resolver = new ModuleResolver(createMockFileSystem());
|
||||
expect(
|
||||
resolver.resolveModuleImport('package-1/sub-folder', _('/libs/local-package/index.js')))
|
||||
.toEqual(
|
||||
|
@ -145,9 +129,8 @@ describe('ModuleResolver', () => {
|
|||
|
||||
describe('with mapped path external modules', () => {
|
||||
it('should resolve to the package.json of simple mapped packages', () => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const resolver =
|
||||
new ModuleResolver(fs, {baseUrl: '/dist', paths: {'*': ['*', 'sub-folder/*']}});
|
||||
const resolver = new ModuleResolver(
|
||||
createMockFileSystem(), {baseUrl: '/dist', paths: {'*': ['*', 'sub-folder/*']}});
|
||||
|
||||
expect(resolver.resolveModuleImport('package-4', _('/libs/local-package/index.js')))
|
||||
.toEqual(new ResolvedExternalModule(_('/dist/package-4')));
|
||||
|
@ -157,8 +140,7 @@ describe('ModuleResolver', () => {
|
|||
});
|
||||
|
||||
it('should select the best match by the length of prefix before the *', () => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const resolver = new ModuleResolver(fs, {
|
||||
const resolver = new ModuleResolver(createMockFileSystem(), {
|
||||
baseUrl: '/dist',
|
||||
paths: {
|
||||
'@lib/*': ['*'],
|
||||
|
@ -176,7 +158,7 @@ describe('ModuleResolver', () => {
|
|||
it('should follow the ordering of `paths` when matching mapped packages', () => {
|
||||
let resolver: ModuleResolver;
|
||||
|
||||
const fs = new NodeJSFileSystem();
|
||||
const fs = createMockFileSystem();
|
||||
resolver = new ModuleResolver(fs, {baseUrl: '/dist', paths: {'*': ['*', 'sub-folder/*']}});
|
||||
expect(resolver.resolveModuleImport('package-4', _('/libs/local-package/index.js')))
|
||||
.toEqual(new ResolvedExternalModule(_('/dist/package-4')));
|
||||
|
@ -187,17 +169,15 @@ describe('ModuleResolver', () => {
|
|||
});
|
||||
|
||||
it('should resolve packages when the path mappings have post-fixes', () => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const resolver =
|
||||
new ModuleResolver(fs, {baseUrl: '/dist', paths: {'*': ['sub-folder/*/post-fix']}});
|
||||
const resolver = new ModuleResolver(
|
||||
createMockFileSystem(), {baseUrl: '/dist', paths: {'*': ['sub-folder/*/post-fix']}});
|
||||
expect(resolver.resolveModuleImport('package-5', _('/libs/local-package/index.js')))
|
||||
.toEqual(new ResolvedExternalModule(_('/dist/sub-folder/package-5/post-fix')));
|
||||
});
|
||||
|
||||
it('should match paths against complex path matchers', () => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const resolver =
|
||||
new ModuleResolver(fs, {baseUrl: '/dist', paths: {'@shared/*': ['sub-folder/*']}});
|
||||
const resolver = new ModuleResolver(
|
||||
createMockFileSystem(), {baseUrl: '/dist', paths: {'@shared/*': ['sub-folder/*']}});
|
||||
expect(resolver.resolveModuleImport('@shared/package-4', _('/libs/local-package/index.js')))
|
||||
.toEqual(new ResolvedExternalModule(_('/dist/sub-folder/package-4')));
|
||||
expect(resolver.resolveModuleImport('package-5', _('/libs/local-package/index.js')))
|
||||
|
@ -206,17 +186,17 @@ describe('ModuleResolver', () => {
|
|||
|
||||
it('should resolve path as "relative" if the mapped path is inside the current package',
|
||||
() => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const resolver = new ModuleResolver(fs, {baseUrl: '/dist', paths: {'@shared/*': ['*']}});
|
||||
const resolver = new ModuleResolver(
|
||||
createMockFileSystem(), {baseUrl: '/dist', paths: {'@shared/*': ['*']}});
|
||||
expect(resolver.resolveModuleImport(
|
||||
'@shared/package-4/x', _('/dist/package-4/sub-folder/index.js')))
|
||||
.toEqual(new ResolvedRelativeModule(_('/dist/package-4/x.js')));
|
||||
});
|
||||
|
||||
it('should resolve paths where the wildcard matches more than one path segment', () => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const resolver = new ModuleResolver(
|
||||
fs, {baseUrl: '/dist', paths: {'@shared/*/post-fix': ['*/post-fix']}});
|
||||
createMockFileSystem(),
|
||||
{baseUrl: '/dist', paths: {'@shared/*/post-fix': ['*/post-fix']}});
|
||||
expect(
|
||||
resolver.resolveModuleImport(
|
||||
'@shared/sub-folder/package-5/post-fix', _('/dist/package-4/sub-folder/index.js')))
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
/**
|
||||
* @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 {AbsoluteFsPath, PathSegment} from '../../../src/ngtsc/path';
|
||||
import {FileStats, FileSystem} from '../../src/file_system/file_system';
|
||||
|
||||
/**
|
||||
* An in-memory file system that can be used in unit tests.
|
||||
*/
|
||||
export class MockFileSystem implements FileSystem {
|
||||
files: Folder = {};
|
||||
constructor(...folders: Folder[]) {
|
||||
folders.forEach(files => this.processFiles(this.files, files));
|
||||
}
|
||||
|
||||
exists(path: AbsoluteFsPath): boolean { return this.findFromPath(path) !== null; }
|
||||
|
||||
readFile(path: AbsoluteFsPath): string {
|
||||
const file = this.findFromPath(path);
|
||||
if (isFile(file)) {
|
||||
return file;
|
||||
} else {
|
||||
throw new MockFileSystemError('ENOENT', path, `File "${path}" does not exist.`);
|
||||
}
|
||||
}
|
||||
|
||||
writeFile(path: AbsoluteFsPath, data: string): void {
|
||||
const [folderPath, basename] = this.splitIntoFolderAndFile(path);
|
||||
const folder = this.findFromPath(folderPath);
|
||||
if (!isFolder(folder)) {
|
||||
throw new MockFileSystemError(
|
||||
'ENOENT', path, `Unable to write file "${path}". The containing folder does not exist.`);
|
||||
}
|
||||
folder[basename] = data;
|
||||
}
|
||||
|
||||
readdir(path: AbsoluteFsPath): PathSegment[] {
|
||||
const folder = this.findFromPath(path);
|
||||
if (folder === null) {
|
||||
throw new MockFileSystemError(
|
||||
'ENOENT', path, `Unable to read directory "${path}". It does not exist.`);
|
||||
}
|
||||
if (isFile(folder)) {
|
||||
throw new MockFileSystemError(
|
||||
'ENOTDIR', path, `Unable to read directory "${path}". It is a file.`);
|
||||
}
|
||||
return Object.keys(folder) as PathSegment[];
|
||||
}
|
||||
|
||||
lstat(path: AbsoluteFsPath): FileStats {
|
||||
const fileOrFolder = this.findFromPath(path);
|
||||
if (fileOrFolder === null) {
|
||||
throw new MockFileSystemError('ENOENT', path, `File "${path}" does not exist.`);
|
||||
}
|
||||
return new MockFileStats(fileOrFolder);
|
||||
}
|
||||
|
||||
stat(path: AbsoluteFsPath): FileStats {
|
||||
const fileOrFolder = this.findFromPath(path, {followSymLinks: true});
|
||||
if (fileOrFolder === null) {
|
||||
throw new MockFileSystemError('ENOENT', path, `File "${path}" does not exist.`);
|
||||
}
|
||||
return new MockFileStats(fileOrFolder);
|
||||
}
|
||||
|
||||
pwd(): AbsoluteFsPath { return AbsoluteFsPath.fromUnchecked('/'); }
|
||||
|
||||
copyFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void {
|
||||
this.writeFile(to, this.readFile(from));
|
||||
}
|
||||
|
||||
moveFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void {
|
||||
this.writeFile(to, this.readFile(from));
|
||||
const folder = this.findFromPath(AbsoluteFsPath.dirname(from)) as Folder;
|
||||
const basename = PathSegment.basename(from);
|
||||
delete folder[basename];
|
||||
}
|
||||
|
||||
ensureDir(path: AbsoluteFsPath): void { this.ensureFolders(this.files, path.split('/')); }
|
||||
|
||||
private processFiles(current: Folder, files: Folder): void {
|
||||
Object.keys(files).forEach(path => {
|
||||
const segments = path.split('/');
|
||||
const lastSegment = segments.pop() !;
|
||||
const containingFolder = this.ensureFolders(current, segments);
|
||||
const entity = files[path];
|
||||
if (isFolder(entity)) {
|
||||
const processedFolder = containingFolder[lastSegment] = {} as Folder;
|
||||
this.processFiles(processedFolder, entity);
|
||||
} else {
|
||||
containingFolder[lastSegment] = entity;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private ensureFolders(current: Folder, segments: string[]): Folder {
|
||||
for (const segment of segments) {
|
||||
if (isFile(current[segment])) {
|
||||
throw new Error(`Folder already exists as a file.`);
|
||||
}
|
||||
if (!current[segment]) {
|
||||
current[segment] = {};
|
||||
}
|
||||
current = current[segment] as Folder;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
private findFromPath(path: AbsoluteFsPath, options?: {followSymLinks: boolean}): Entity|null {
|
||||
const followSymLinks = !!options && options.followSymLinks;
|
||||
const segments = path.split('/');
|
||||
let current = this.files;
|
||||
while (segments.length) {
|
||||
const next: Entity = current[segments.shift() !];
|
||||
if (next === undefined) {
|
||||
return null;
|
||||
}
|
||||
if (segments.length > 0 && (!isFolder(next))) {
|
||||
return null;
|
||||
}
|
||||
if (isFile(next)) {
|
||||
return next;
|
||||
}
|
||||
if (isSymLink(next)) {
|
||||
return followSymLinks ?
|
||||
this.findFromPath(AbsoluteFsPath.resolve(next.path, ...segments), {followSymLinks}) :
|
||||
next;
|
||||
}
|
||||
current = next;
|
||||
}
|
||||
return current || null;
|
||||
}
|
||||
|
||||
private splitIntoFolderAndFile(path: AbsoluteFsPath): [AbsoluteFsPath, string] {
|
||||
const segments = path.split('/');
|
||||
const file = segments.pop() !;
|
||||
return [AbsoluteFsPath.fromUnchecked(segments.join('/')), file];
|
||||
}
|
||||
}
|
||||
|
||||
export type Entity = Folder | File | SymLink;
|
||||
export interface Folder { [pathSegments: string]: Entity; }
|
||||
export type File = string;
|
||||
export class SymLink {
|
||||
constructor(public path: AbsoluteFsPath) {}
|
||||
}
|
||||
|
||||
class MockFileStats implements FileStats {
|
||||
constructor(private entity: Entity) {}
|
||||
isFile(): boolean { return isFile(this.entity); }
|
||||
isDirectory(): boolean { return isFolder(this.entity); }
|
||||
isSymbolicLink(): boolean { return isSymLink(this.entity); }
|
||||
}
|
||||
|
||||
class MockFileSystemError extends Error {
|
||||
constructor(public code: string, public path: string, message: string) { super(message); }
|
||||
}
|
||||
|
||||
function isFile(item: Entity | null): item is File {
|
||||
return typeof item === 'string';
|
||||
}
|
||||
|
||||
function isSymLink(item: Entity | null): item is SymLink {
|
||||
return item instanceof SymLink;
|
||||
}
|
||||
|
||||
function isFolder(item: Entity | null): item is Folder {
|
||||
return item !== null && !isFile(item) && !isSymLink(item);
|
||||
}
|
|
@ -12,6 +12,7 @@ import {makeProgram} from '../../../src/ngtsc/testing/in_memory_typescript';
|
|||
import {BundleProgram} from '../../src/packages/bundle_program';
|
||||
import {EntryPointFormat, EntryPointJsonProperty} from '../../src/packages/entry_point';
|
||||
import {EntryPointBundle} from '../../src/packages/entry_point_bundle';
|
||||
import {Folder} from './mock_file_system';
|
||||
|
||||
export {getDeclaration} from '../../../src/ngtsc/testing/in_memory_typescript';
|
||||
|
||||
|
@ -121,3 +122,11 @@ export function convertToDirectTsLibImport(filesystem: {name: string, contents:
|
|||
return {...file, contents};
|
||||
});
|
||||
}
|
||||
|
||||
export function createFileSystemFromProgramFiles(
|
||||
...fileCollections: ({name: string, contents: string}[] | undefined)[]): Folder {
|
||||
const folder: Folder = {};
|
||||
fileCollections.forEach(
|
||||
files => files && files.forEach(file => folder[file.name] = file.contents));
|
||||
return folder;
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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')));
|
||||
}
|
||||
|
|
|
@ -11,21 +11,21 @@ import {AbsoluteFsPath} from '../../../src/ngtsc/path';
|
|||
import {DecorationAnalyzer} from '../../src/analysis/decoration_analyzer';
|
||||
import {NgccReferencesRegistry} from '../../src/analysis/ngcc_references_registry';
|
||||
import {SwitchMarkerAnalyzer} from '../../src/analysis/switch_marker_analyzer';
|
||||
import {NodeJSFileSystem} from '../../src/file_system/node_js_file_system';
|
||||
import {Esm2015ReflectionHost} from '../../src/host/esm2015_host';
|
||||
import {EsmRenderer} from '../../src/rendering/esm_renderer';
|
||||
import {makeTestEntryPointBundle} from '../helpers/utils';
|
||||
import {MockFileSystem} from '../helpers/mock_file_system';
|
||||
import {MockLogger} from '../helpers/mock_logger';
|
||||
|
||||
const _ = AbsoluteFsPath.fromUnchecked;
|
||||
|
||||
function setup(file: {name: string, contents: string}) {
|
||||
function setup(file: {name: AbsoluteFsPath, contents: string}) {
|
||||
const fs = new MockFileSystem();
|
||||
const logger = new MockLogger();
|
||||
const bundle = makeTestEntryPointBundle('es2015', 'esm2015', false, [file]) !;
|
||||
const typeChecker = bundle.src.program.getTypeChecker();
|
||||
const host = new Esm2015ReflectionHost(logger, false, typeChecker);
|
||||
const referencesRegistry = new NgccReferencesRegistry(host);
|
||||
const fs = new NodeJSFileSystem();
|
||||
const decorationAnalyses = new DecorationAnalyzer(
|
||||
fs, bundle.src.program, bundle.src.options, bundle.src.host,
|
||||
typeChecker, host, referencesRegistry, [_('/')], false)
|
||||
|
@ -40,7 +40,7 @@ function setup(file: {name: string, contents: string}) {
|
|||
}
|
||||
|
||||
const PROGRAM = {
|
||||
name: '/some/file.js',
|
||||
name: _('/some/file.js'),
|
||||
contents: `
|
||||
/* A copyright notice */
|
||||
import 'some-side-effect';
|
||||
|
@ -76,7 +76,7 @@ function compileNgModuleFactory__POST_R3__(injector, options, moduleType) {
|
|||
};
|
||||
|
||||
const PROGRAM_DECORATE_HELPER = {
|
||||
name: '/some/file.js',
|
||||
name: _('/some/file.js'),
|
||||
contents: `
|
||||
import * as tslib_1 from "tslib";
|
||||
var D_1;
|
||||
|
@ -142,7 +142,7 @@ import * as i1 from '@angular/common';`);
|
|||
{from: _('/some/a.js'), dtsFrom: _('/some/a.d.ts'), identifier: 'ComponentA1'},
|
||||
{from: _('/some/a.js'), dtsFrom: _('/some/a.d.ts'), identifier: 'ComponentA2'},
|
||||
{from: _('/some/foo/b.js'), dtsFrom: _('/some/foo/b.d.ts'), identifier: 'ComponentB'},
|
||||
{from: _(PROGRAM.name), dtsFrom: _(PROGRAM.name), identifier: 'TopLevelComponent'},
|
||||
{from: PROGRAM.name, dtsFrom: PROGRAM.name, identifier: 'TopLevelComponent'},
|
||||
]);
|
||||
expect(output.toString()).toContain(`
|
||||
// Some other content
|
||||
|
@ -159,7 +159,7 @@ export {TopLevelComponent};`);
|
|||
{from: _('/some/a.js'), alias: 'eComponentA1', identifier: 'ComponentA1'},
|
||||
{from: _('/some/a.js'), alias: 'eComponentA2', identifier: 'ComponentA2'},
|
||||
{from: _('/some/foo/b.js'), alias: 'eComponentB', identifier: 'ComponentB'},
|
||||
{from: _(PROGRAM.name), alias: 'eTopLevelComponent', identifier: 'TopLevelComponent'},
|
||||
{from: PROGRAM.name, alias: 'eTopLevelComponent', identifier: 'TopLevelComponent'},
|
||||
]);
|
||||
const outputString = output.toString();
|
||||
expect(outputString).not.toContain(`{eComponentA1 as ComponentA1}`);
|
||||
|
|
|
@ -11,24 +11,25 @@ import {AbsoluteFsPath} from '../../../src/ngtsc/path';
|
|||
import {DecorationAnalyzer} from '../../src/analysis/decoration_analyzer';
|
||||
import {NgccReferencesRegistry} from '../../src/analysis/ngcc_references_registry';
|
||||
import {SwitchMarkerAnalyzer} from '../../src/analysis/switch_marker_analyzer';
|
||||
import {NodeJSFileSystem} from '../../src/file_system/node_js_file_system';
|
||||
import {Esm5ReflectionHost} from '../../src/host/esm5_host';
|
||||
import {Esm5Renderer} from '../../src/rendering/esm5_renderer';
|
||||
import {makeTestEntryPointBundle, getDeclaration} from '../helpers/utils';
|
||||
import {MockFileSystem} from '../helpers/mock_file_system';
|
||||
import {MockLogger} from '../helpers/mock_logger';
|
||||
|
||||
const _ = AbsoluteFsPath.fromUnchecked;
|
||||
|
||||
function setup(file: {name: string, contents: string}) {
|
||||
function setup(file: {name: AbsoluteFsPath, contents: string}) {
|
||||
const fs = new MockFileSystem();
|
||||
const logger = new MockLogger();
|
||||
const bundle = makeTestEntryPointBundle('module', 'esm5', false, [file]);
|
||||
const typeChecker = bundle.src.program.getTypeChecker();
|
||||
const host = new Esm5ReflectionHost(logger, false, typeChecker);
|
||||
const referencesRegistry = new NgccReferencesRegistry(host);
|
||||
const fs = new NodeJSFileSystem();
|
||||
const decorationAnalyses = new DecorationAnalyzer(
|
||||
fs, bundle.src.program, bundle.src.options, bundle.src.host,
|
||||
typeChecker, host, referencesRegistry, [_('/')], false)
|
||||
const decorationAnalyses =
|
||||
new DecorationAnalyzer(
|
||||
fs, bundle.src.program, bundle.src.options, bundle.src.host, typeChecker, host,
|
||||
referencesRegistry, [AbsoluteFsPath.fromUnchecked('/')], false)
|
||||
.analyzeProgram();
|
||||
const switchMarkerAnalyses = new SwitchMarkerAnalyzer(host).analyzeProgram(bundle.src.program);
|
||||
const renderer = new Esm5Renderer(fs, logger, host, false, bundle);
|
||||
|
@ -40,7 +41,7 @@ function setup(file: {name: string, contents: string}) {
|
|||
}
|
||||
|
||||
const PROGRAM = {
|
||||
name: '/some/file.js',
|
||||
name: _('/some/file.js'),
|
||||
contents: `
|
||||
/* A copyright notice */
|
||||
import 'some-side-effect';
|
||||
|
@ -100,7 +101,7 @@ export {A, B, C, NoIife, BadIife};`
|
|||
};
|
||||
|
||||
const PROGRAM_DECORATE_HELPER = {
|
||||
name: '/some/file.js',
|
||||
name: _('/some/file.js'),
|
||||
contents: `
|
||||
import * as tslib_1 from "tslib";
|
||||
/* A copyright notice */
|
||||
|
@ -179,7 +180,7 @@ import * as i1 from '@angular/common';`);
|
|||
{from: _('/some/a.js'), dtsFrom: _('/some/a.d.ts'), identifier: 'ComponentA1'},
|
||||
{from: _('/some/a.js'), dtsFrom: _('/some/a.d.ts'), identifier: 'ComponentA2'},
|
||||
{from: _('/some/foo/b.js'), dtsFrom: _('/some/foo/b.d.ts'), identifier: 'ComponentB'},
|
||||
{from: _(PROGRAM.name), dtsFrom: _(PROGRAM.name), identifier: 'TopLevelComponent'},
|
||||
{from: PROGRAM.name, dtsFrom: PROGRAM.name, identifier: 'TopLevelComponent'},
|
||||
]);
|
||||
expect(output.toString()).toContain(`
|
||||
export {A, B, C, NoIife, BadIife};
|
||||
|
@ -193,10 +194,10 @@ export {TopLevelComponent};`);
|
|||
const {renderer} = setup(PROGRAM);
|
||||
const output = new MagicString(PROGRAM.contents);
|
||||
renderer.addExports(output, _(PROGRAM.name.replace(/\.js$/, '')), [
|
||||
{from: _('/some/a.js'), alias: 'eComponentA1', identifier: 'ComponentA1'},
|
||||
{from: _('/some/a.js'), alias: 'eComponentA2', identifier: 'ComponentA2'},
|
||||
{from: _('/some/foo/b.js'), alias: 'eComponentB', identifier: 'ComponentB'},
|
||||
{from: _(PROGRAM.name), alias: 'eTopLevelComponent', identifier: 'TopLevelComponent'},
|
||||
{from: _('/some/a.js'), alias: _('eComponentA1'), identifier: 'ComponentA1'},
|
||||
{from: _('/some/a.js'), alias: _('eComponentA2'), identifier: 'ComponentA2'},
|
||||
{from: _('/some/foo/b.js'), alias: _('eComponentB'), identifier: 'ComponentB'},
|
||||
{from: PROGRAM.name, alias: 'eTopLevelComponent', identifier: 'TopLevelComponent'},
|
||||
]);
|
||||
const outputString = output.toString();
|
||||
expect(outputString).not.toContain(`{eComponentA1 as ComponentA1}`);
|
||||
|
@ -285,14 +286,14 @@ SOME DEFINITION TEXT
|
|||
|
||||
const noIifeDeclaration =
|
||||
getDeclaration(program, sourceFile.fileName, 'NoIife', ts.isFunctionDeclaration);
|
||||
const mockNoIifeClass: any = {declaration: noIifeDeclaration, name: 'NoIife'};
|
||||
const mockNoIifeClass: any = {declaration: noIifeDeclaration, name: _('NoIife')};
|
||||
expect(() => renderer.addDefinitions(output, mockNoIifeClass, 'SOME DEFINITION TEXT'))
|
||||
.toThrowError(
|
||||
'Compiled class declaration is not inside an IIFE: NoIife in /some/file.js');
|
||||
|
||||
const badIifeDeclaration =
|
||||
getDeclaration(program, sourceFile.fileName, 'BadIife', ts.isVariableDeclaration);
|
||||
const mockBadIifeClass: any = {declaration: badIifeDeclaration, name: 'BadIife'};
|
||||
const mockBadIifeClass: any = {declaration: badIifeDeclaration, name: _('BadIife')};
|
||||
expect(() => renderer.addDefinitions(output, mockBadIifeClass, 'SOME DEFINITION TEXT'))
|
||||
.toThrowError(
|
||||
'Compiled class wrapper IIFE does not have a return statement: BadIife in /some/file.js');
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* 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 fs from 'fs';
|
||||
import MagicString from 'magic-string';
|
||||
import * as ts from 'typescript';
|
||||
import {fromObject, generateMapFileComment} from 'convert-source-map';
|
||||
|
@ -18,11 +17,11 @@ import {SwitchMarkerAnalyzer} from '../../src/analysis/switch_marker_analyzer';
|
|||
import {Esm2015ReflectionHost} from '../../src/host/esm2015_host';
|
||||
import {RedundantDecoratorMap, Renderer} from '../../src/rendering/renderer';
|
||||
import {EntryPointBundle} from '../../src/packages/entry_point_bundle';
|
||||
import {makeTestEntryPointBundle} from '../helpers/utils';
|
||||
import {makeTestEntryPointBundle, createFileSystemFromProgramFiles} from '../helpers/utils';
|
||||
import {Logger} from '../../src/logging/logger';
|
||||
import {MockFileSystem} from '../helpers/mock_file_system';
|
||||
import {MockLogger} from '../helpers/mock_logger';
|
||||
import {FileSystem} from '../../src/file_system/file_system';
|
||||
import {NodeJSFileSystem} from '../../src/file_system/node_js_file_system';
|
||||
|
||||
const _ = AbsoluteFsPath.fromUnchecked;
|
||||
|
||||
|
@ -58,14 +57,15 @@ class TestRenderer extends Renderer {
|
|||
|
||||
function createTestRenderer(
|
||||
packageName: string, files: {name: string, contents: string}[],
|
||||
dtsFiles?: {name: string, contents: string}[]) {
|
||||
dtsFiles?: {name: string, contents: string}[],
|
||||
mappingFiles?: {name: string, contents: string}[]) {
|
||||
const logger = new MockLogger();
|
||||
const fs = new MockFileSystem(createFileSystemFromProgramFiles(files, dtsFiles, mappingFiles));
|
||||
const isCore = packageName === '@angular/core';
|
||||
const bundle = makeTestEntryPointBundle('es2015', 'esm2015', isCore, files, dtsFiles);
|
||||
const typeChecker = bundle.src.program.getTypeChecker();
|
||||
const host = new Esm2015ReflectionHost(logger, isCore, typeChecker, bundle.dts);
|
||||
const referencesRegistry = new NgccReferencesRegistry(host);
|
||||
const fs = new NodeJSFileSystem();
|
||||
const decorationAnalyses = new DecorationAnalyzer(
|
||||
fs, bundle.src.program, bundle.src.options, bundle.src.host,
|
||||
typeChecker, host, referencesRegistry, bundle.rootDirs, isCore)
|
||||
|
@ -200,8 +200,8 @@ describe('Renderer', () => {
|
|||
const addDefinitionsSpy = renderer.addDefinitions as jasmine.Spy;
|
||||
expect(addDefinitionsSpy.calls.first().args[0].toString()).toEqual(RENDERED_CONTENTS);
|
||||
expect(addDefinitionsSpy.calls.first().args[1]).toEqual(jasmine.objectContaining({
|
||||
name: 'A',
|
||||
decorators: [jasmine.objectContaining({name: 'Directive'})],
|
||||
name: _('A'),
|
||||
decorators: [jasmine.objectContaining({name: _('Directive')})]
|
||||
}));
|
||||
expect(addDefinitionsSpy.calls.first().args[2])
|
||||
.toEqual(
|
||||
|
@ -259,15 +259,15 @@ describe('Renderer', () => {
|
|||
|
||||
it('should merge any external source map from the original file and write the output to an external source map',
|
||||
() => {
|
||||
// Mock out reading the map file from disk
|
||||
spyOn(fs, 'readFileSync').and.returnValue(INPUT_PROGRAM_MAP.toJSON());
|
||||
const {decorationAnalyses, renderer, switchMarkerAnalyses, privateDeclarationsAnalyses,
|
||||
moduleWithProvidersAnalyses} =
|
||||
createTestRenderer(
|
||||
'test-package', [{
|
||||
const sourceFiles = [{
|
||||
...INPUT_PROGRAM,
|
||||
contents: INPUT_PROGRAM.contents + '\n//# sourceMappingURL=file.js.map'
|
||||
}]);
|
||||
}];
|
||||
const mappingFiles =
|
||||
[{name: INPUT_PROGRAM.name + '.map', contents: INPUT_PROGRAM_MAP.toJSON()}];
|
||||
const {decorationAnalyses, renderer, switchMarkerAnalyses, privateDeclarationsAnalyses,
|
||||
moduleWithProvidersAnalyses} =
|
||||
createTestRenderer('test-package', sourceFiles, undefined, mappingFiles);
|
||||
const result = renderer.renderProgram(
|
||||
decorationAnalyses, switchMarkerAnalyses, privateDeclarationsAnalyses,
|
||||
moduleWithProvidersAnalyses);
|
||||
|
@ -275,7 +275,7 @@ describe('Renderer', () => {
|
|||
expect(result[0].contents)
|
||||
.toEqual(RENDERED_CONTENTS + '\n' + generateMapFileComment('file.js.map'));
|
||||
expect(result[1].path).toEqual('/src/file.js.map');
|
||||
expect(result[1].contents).toEqual(MERGED_OUTPUT_PROGRAM_MAP.toJSON());
|
||||
expect(JSON.parse(result[1].contents)).toEqual(MERGED_OUTPUT_PROGRAM_MAP.toObject());
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -5,20 +5,16 @@
|
|||
* 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} 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 {EntryPoint} from '../../src/packages/entry_point';
|
||||
import {EntryPointBundle} from '../../src/packages/entry_point_bundle';
|
||||
import {InPlaceFileWriter} from '../../src/writing/in_place_file_writer';
|
||||
import {MockFileSystem} from '../helpers/mock_file_system';
|
||||
|
||||
const _ = AbsoluteFsPath.fromUnchecked;
|
||||
|
||||
function createMockFileSystem() {
|
||||
mockFs({
|
||||
return new MockFileSystem({
|
||||
'/package/path': {
|
||||
'top-level.js': 'ORIGINAL TOP LEVEL',
|
||||
'folder-1': {
|
||||
|
@ -34,16 +30,9 @@ function createMockFileSystem() {
|
|||
});
|
||||
}
|
||||
|
||||
function restoreRealFileSystem() {
|
||||
mockFs.restore();
|
||||
}
|
||||
|
||||
describe('InPlaceFileWriter', () => {
|
||||
beforeEach(createMockFileSystem);
|
||||
afterEach(restoreRealFileSystem);
|
||||
|
||||
it('should write all the FileInfo to the disk', () => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const fs = createMockFileSystem();
|
||||
const fileWriter = new InPlaceFileWriter(fs);
|
||||
fileWriter.writeBundle({} as EntryPoint, {} as EntryPointBundle, [
|
||||
{path: _('/package/path/top-level.js'), contents: 'MODIFIED TOP LEVEL'},
|
||||
|
@ -51,16 +40,16 @@ describe('InPlaceFileWriter', () => {
|
|||
{path: _('/package/path/folder-2/file-4.js'), contents: 'MODIFIED FILE 4'},
|
||||
{path: _('/package/path/folder-3/file-5.js'), contents: 'NEW FILE 5'},
|
||||
]);
|
||||
expect(readFileSync('/package/path/top-level.js', 'utf8')).toEqual('MODIFIED TOP LEVEL');
|
||||
expect(readFileSync('/package/path/folder-1/file-1.js', 'utf8')).toEqual('MODIFIED FILE 1');
|
||||
expect(readFileSync('/package/path/folder-1/file-2.js', 'utf8')).toEqual('ORIGINAL FILE 2');
|
||||
expect(readFileSync('/package/path/folder-2/file-3.js', 'utf8')).toEqual('ORIGINAL FILE 3');
|
||||
expect(readFileSync('/package/path/folder-2/file-4.js', 'utf8')).toEqual('MODIFIED FILE 4');
|
||||
expect(readFileSync('/package/path/folder-3/file-5.js', 'utf8')).toEqual('NEW FILE 5');
|
||||
expect(fs.readFile(_('/package/path/top-level.js'))).toEqual('MODIFIED TOP LEVEL');
|
||||
expect(fs.readFile(_('/package/path/folder-1/file-1.js'))).toEqual('MODIFIED FILE 1');
|
||||
expect(fs.readFile(_('/package/path/folder-1/file-2.js'))).toEqual('ORIGINAL FILE 2');
|
||||
expect(fs.readFile(_('/package/path/folder-2/file-3.js'))).toEqual('ORIGINAL FILE 3');
|
||||
expect(fs.readFile(_('/package/path/folder-2/file-4.js'))).toEqual('MODIFIED FILE 4');
|
||||
expect(fs.readFile(_('/package/path/folder-3/file-5.js'))).toEqual('NEW FILE 5');
|
||||
});
|
||||
|
||||
it('should create backups of all files that previously existed', () => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const fs = createMockFileSystem();
|
||||
const fileWriter = new InPlaceFileWriter(fs);
|
||||
fileWriter.writeBundle({} as EntryPoint, {} as EntryPointBundle, [
|
||||
{path: _('/package/path/top-level.js'), contents: 'MODIFIED TOP LEVEL'},
|
||||
|
@ -68,19 +57,19 @@ describe('InPlaceFileWriter', () => {
|
|||
{path: _('/package/path/folder-2/file-4.js'), contents: 'MODIFIED FILE 4'},
|
||||
{path: _('/package/path/folder-3/file-5.js'), contents: 'NEW FILE 5'},
|
||||
]);
|
||||
expect(readFileSync('/package/path/top-level.js.__ivy_ngcc_bak', 'utf8'))
|
||||
expect(fs.readFile(_('/package/path/top-level.js.__ivy_ngcc_bak')))
|
||||
.toEqual('ORIGINAL TOP LEVEL');
|
||||
expect(readFileSync('/package/path/folder-1/file-1.js.__ivy_ngcc_bak', 'utf8'))
|
||||
expect(fs.readFile(_('/package/path/folder-1/file-1.js.__ivy_ngcc_bak')))
|
||||
.toEqual('ORIGINAL FILE 1');
|
||||
expect(existsSync('/package/path/folder-1/file-2.js.__ivy_ngcc_bak')).toBe(false);
|
||||
expect(existsSync('/package/path/folder-2/file-3.js.__ivy_ngcc_bak')).toBe(false);
|
||||
expect(readFileSync('/package/path/folder-2/file-4.js.__ivy_ngcc_bak', 'utf8'))
|
||||
expect(fs.exists(_('/package/path/folder-1/file-2.js.__ivy_ngcc_bak'))).toBe(false);
|
||||
expect(fs.exists(_('/package/path/folder-2/file-3.js.__ivy_ngcc_bak'))).toBe(false);
|
||||
expect(fs.readFile(_('/package/path/folder-2/file-4.js.__ivy_ngcc_bak')))
|
||||
.toEqual('ORIGINAL FILE 4');
|
||||
expect(existsSync('/package/path/folder-3/file-5.js.__ivy_ngcc_bak')).toBe(false);
|
||||
expect(fs.exists(_('/package/path/folder-3/file-5.js.__ivy_ngcc_bak'))).toBe(false);
|
||||
});
|
||||
|
||||
it('should error if the backup file already exists', () => {
|
||||
const fs = new NodeJSFileSystem();
|
||||
const fs = createMockFileSystem();
|
||||
const fileWriter = new InPlaceFileWriter(fs);
|
||||
expect(
|
||||
() => fileWriter.writeBundle(
|
||||
|
|
|
@ -5,24 +5,20 @@
|
|||
* 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} from 'fs';
|
||||
import * as mockFs from 'mock-fs';
|
||||
|
||||
import {AbsoluteFsPath} from '../../../src/ngtsc/path';
|
||||
import {FileSystem} from '../../src/file_system/file_system';
|
||||
import {NodeJSFileSystem} from '../../src/file_system/node_js_file_system';
|
||||
import {EntryPoint, EntryPointFormat, EntryPointJsonProperty, getEntryPointInfo} from '../../src/packages/entry_point';
|
||||
import {EntryPointBundle, makeEntryPointBundle} from '../../src/packages/entry_point_bundle';
|
||||
import {FileWriter} from '../../src/writing/file_writer';
|
||||
import {NewEntryPointFileWriter} from '../../src/writing/new_entry_point_file_writer';
|
||||
import {MockFileSystem} from '../helpers/mock_file_system';
|
||||
import {MockLogger} from '../helpers/mock_logger';
|
||||
import {loadPackageJson} from '../packages/entry_point_spec';
|
||||
|
||||
const _ = AbsoluteFsPath.from;
|
||||
|
||||
function createMockFileSystem() {
|
||||
mockFs({
|
||||
return new MockFileSystem({
|
||||
'/node_modules/test': {
|
||||
'package.json':
|
||||
'{"module": "./esm5.js", "es2015": "./es2015/index.js", "typings": "./index.d.ts"}',
|
||||
|
@ -75,14 +71,7 @@ function createMockFileSystem() {
|
|||
});
|
||||
}
|
||||
|
||||
function restoreRealFileSystem() {
|
||||
mockFs.restore();
|
||||
}
|
||||
|
||||
describe('NewEntryPointFileWriter', () => {
|
||||
beforeEach(createMockFileSystem);
|
||||
afterEach(restoreRealFileSystem);
|
||||
|
||||
let fs: FileSystem;
|
||||
let fileWriter: FileWriter;
|
||||
let entryPoint: EntryPoint;
|
||||
|
@ -91,7 +80,7 @@ describe('NewEntryPointFileWriter', () => {
|
|||
|
||||
describe('writeBundle() [primary entry-point]', () => {
|
||||
beforeEach(() => {
|
||||
fs = new NodeJSFileSystem();
|
||||
fs = createMockFileSystem();
|
||||
fileWriter = new NewEntryPointFileWriter(fs);
|
||||
entryPoint = getEntryPointInfo(
|
||||
fs, new MockLogger(), _('/node_modules/test'), _('/node_modules/test')) !;
|
||||
|
@ -107,14 +96,12 @@ describe('NewEntryPointFileWriter', () => {
|
|||
},
|
||||
{path: _('/node_modules/test/esm5.js.map'), contents: 'MODIFIED MAPPING DATA'},
|
||||
]);
|
||||
expect(readFileSync('/node_modules/test/__ivy_ngcc__/esm5.js', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/__ivy_ngcc__/esm5.js')))
|
||||
.toEqual('export function FooTop() {} // MODIFIED');
|
||||
expect(readFileSync('/node_modules/test/esm5.js', 'utf8'))
|
||||
.toEqual('export function FooTop() {}');
|
||||
expect(readFileSync('/node_modules/test/__ivy_ngcc__/esm5.js.map', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/esm5.js'))).toEqual('export function FooTop() {}');
|
||||
expect(fs.readFile(_('/node_modules/test/__ivy_ngcc__/esm5.js.map')))
|
||||
.toEqual('MODIFIED MAPPING DATA');
|
||||
expect(readFileSync('/node_modules/test/esm5.js.map', 'utf8'))
|
||||
.toEqual('ORIGINAL MAPPING DATA');
|
||||
expect(fs.readFile(_('/node_modules/test/esm5.js.map'))).toEqual('ORIGINAL MAPPING DATA');
|
||||
});
|
||||
|
||||
it('should also copy unmodified files in the program', () => {
|
||||
|
@ -124,13 +111,12 @@ describe('NewEntryPointFileWriter', () => {
|
|||
contents: 'export class FooTop {} // MODIFIED'
|
||||
},
|
||||
]);
|
||||
expect(readFileSync('/node_modules/test/__ivy_ngcc__/es2015/foo.js', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/__ivy_ngcc__/es2015/foo.js')))
|
||||
.toEqual('export class FooTop {} // MODIFIED');
|
||||
expect(readFileSync('/node_modules/test/es2015/foo.js', 'utf8'))
|
||||
.toEqual('export class FooTop {}');
|
||||
expect(readFileSync('/node_modules/test/__ivy_ngcc__/es2015/index.js', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/es2015/foo.js'))).toEqual('export class FooTop {}');
|
||||
expect(fs.readFile(_('/node_modules/test/__ivy_ngcc__/es2015/index.js')))
|
||||
.toEqual('export {FooTop} from "./foo";');
|
||||
expect(readFileSync('/node_modules/test/es2015/index.js', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/es2015/index.js')))
|
||||
.toEqual('export {FooTop} from "./foo";');
|
||||
});
|
||||
|
||||
|
@ -141,7 +127,7 @@ describe('NewEntryPointFileWriter', () => {
|
|||
contents: 'export function FooTop() {} // MODIFIED'
|
||||
},
|
||||
]);
|
||||
expect(loadPackageJson('/node_modules/test')).toEqual(jasmine.objectContaining({
|
||||
expect(loadPackageJson(fs, '/node_modules/test')).toEqual(jasmine.objectContaining({
|
||||
module_ivy_ngcc: '__ivy_ngcc__/esm5.js',
|
||||
}));
|
||||
|
||||
|
@ -151,7 +137,7 @@ describe('NewEntryPointFileWriter', () => {
|
|||
contents: 'export class FooTop {} // MODIFIED'
|
||||
},
|
||||
]);
|
||||
expect(loadPackageJson('/node_modules/test')).toEqual(jasmine.objectContaining({
|
||||
expect(loadPackageJson(fs, '/node_modules/test')).toEqual(jasmine.objectContaining({
|
||||
module_ivy_ngcc: '__ivy_ngcc__/esm5.js',
|
||||
es2015_ivy_ngcc: '__ivy_ngcc__/es2015/index.js',
|
||||
}));
|
||||
|
@ -161,27 +147,26 @@ describe('NewEntryPointFileWriter', () => {
|
|||
fileWriter.writeBundle(entryPoint, esm2015bundle, [
|
||||
{
|
||||
path: _('/node_modules/test/index.d.ts'),
|
||||
contents: 'export declare class FooTop {} // MODIFIED',
|
||||
contents: 'export declare class FooTop {} // MODIFIED'
|
||||
},
|
||||
{path: _('/node_modules/test/index.d.ts.map'), contents: 'MODIFIED MAPPING DATA'},
|
||||
]);
|
||||
expect(readFileSync('/node_modules/test/index.d.ts', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/index.d.ts')))
|
||||
.toEqual('export declare class FooTop {} // MODIFIED');
|
||||
expect(readFileSync('/node_modules/test/index.d.ts.__ivy_ngcc_bak', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/index.d.ts.__ivy_ngcc_bak')))
|
||||
.toEqual('export declare class FooTop {}');
|
||||
expect(existsSync('/node_modules/test/__ivy_ngcc__/index.d.ts')).toBe(false);
|
||||
expect(fs.exists(_('/node_modules/test/__ivy_ngcc__/index.d.ts'))).toBe(false);
|
||||
|
||||
expect(readFileSync('/node_modules/test/index.d.ts.map', 'utf8'))
|
||||
.toEqual('MODIFIED MAPPING DATA');
|
||||
expect(readFileSync('/node_modules/test/index.d.ts.map.__ivy_ngcc_bak', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/index.d.ts.map'))).toEqual('MODIFIED MAPPING DATA');
|
||||
expect(fs.readFile(_('/node_modules/test/index.d.ts.map.__ivy_ngcc_bak')))
|
||||
.toEqual('ORIGINAL MAPPING DATA');
|
||||
expect(existsSync('/node_modules/test/__ivy_ngcc__/index.d.ts.map')).toBe(false);
|
||||
expect(fs.exists(_('/node_modules/test/__ivy_ngcc__/index.d.ts.map'))).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('writeBundle() [secondary entry-point]', () => {
|
||||
beforeEach(() => {
|
||||
fs = new NodeJSFileSystem();
|
||||
fs = createMockFileSystem();
|
||||
fileWriter = new NewEntryPointFileWriter(fs);
|
||||
entryPoint = getEntryPointInfo(
|
||||
fs, new MockLogger(), _('/node_modules/test'), _('/node_modules/test/a')) !;
|
||||
|
@ -196,10 +181,9 @@ describe('NewEntryPointFileWriter', () => {
|
|||
contents: 'export function FooA() {} // MODIFIED'
|
||||
},
|
||||
]);
|
||||
expect(readFileSync('/node_modules/test/__ivy_ngcc__/a/esm5.js', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/__ivy_ngcc__/a/esm5.js')))
|
||||
.toEqual('export function FooA() {} // MODIFIED');
|
||||
expect(readFileSync('/node_modules/test/a/esm5.js', 'utf8'))
|
||||
.toEqual('export function FooA() {}');
|
||||
expect(fs.readFile(_('/node_modules/test/a/esm5.js'))).toEqual('export function FooA() {}');
|
||||
});
|
||||
|
||||
it('should also copy unmodified files in the program', () => {
|
||||
|
@ -209,13 +193,12 @@ describe('NewEntryPointFileWriter', () => {
|
|||
contents: 'export class FooA {} // MODIFIED'
|
||||
},
|
||||
]);
|
||||
expect(readFileSync('/node_modules/test/__ivy_ngcc__/a/es2015/foo.js', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/__ivy_ngcc__/a/es2015/foo.js')))
|
||||
.toEqual('export class FooA {} // MODIFIED');
|
||||
expect(readFileSync('/node_modules/test/a/es2015/foo.js', 'utf8'))
|
||||
.toEqual('export class FooA {}');
|
||||
expect(readFileSync('/node_modules/test/__ivy_ngcc__/a/es2015/index.js', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/a/es2015/foo.js'))).toEqual('export class FooA {}');
|
||||
expect(fs.readFile(_('/node_modules/test/__ivy_ngcc__/a/es2015/index.js')))
|
||||
.toEqual('export {FooA} from "./foo";');
|
||||
expect(readFileSync('/node_modules/test/a/es2015/index.js', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/a/es2015/index.js')))
|
||||
.toEqual('export {FooA} from "./foo";');
|
||||
});
|
||||
|
||||
|
@ -226,7 +209,7 @@ describe('NewEntryPointFileWriter', () => {
|
|||
contents: 'export function FooA() {} // MODIFIED'
|
||||
},
|
||||
]);
|
||||
expect(loadPackageJson('/node_modules/test/a')).toEqual(jasmine.objectContaining({
|
||||
expect(loadPackageJson(fs, '/node_modules/test/a')).toEqual(jasmine.objectContaining({
|
||||
module_ivy_ngcc: '../__ivy_ngcc__/a/esm5.js',
|
||||
}));
|
||||
|
||||
|
@ -236,7 +219,7 @@ describe('NewEntryPointFileWriter', () => {
|
|||
contents: 'export class FooA {} // MODIFIED'
|
||||
},
|
||||
]);
|
||||
expect(loadPackageJson('/node_modules/test/a')).toEqual(jasmine.objectContaining({
|
||||
expect(loadPackageJson(fs, '/node_modules/test/a')).toEqual(jasmine.objectContaining({
|
||||
module_ivy_ngcc: '../__ivy_ngcc__/a/esm5.js',
|
||||
es2015_ivy_ngcc: '../__ivy_ngcc__/a/es2015/index.js',
|
||||
}));
|
||||
|
@ -249,17 +232,17 @@ describe('NewEntryPointFileWriter', () => {
|
|||
contents: 'export declare class FooA {} // MODIFIED'
|
||||
},
|
||||
]);
|
||||
expect(readFileSync('/node_modules/test/a/index.d.ts', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/a/index.d.ts')))
|
||||
.toEqual('export declare class FooA {} // MODIFIED');
|
||||
expect(readFileSync('/node_modules/test/a/index.d.ts.__ivy_ngcc_bak', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/a/index.d.ts.__ivy_ngcc_bak')))
|
||||
.toEqual('export declare class FooA {}');
|
||||
expect(existsSync('/node_modules/test/__ivy_ngcc__/a/index.d.ts')).toBe(false);
|
||||
expect(fs.exists(_('/node_modules/test/__ivy_ngcc__/a/index.d.ts'))).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('writeBundle() [entry-point (with files placed outside entry-point folder)]', () => {
|
||||
beforeEach(() => {
|
||||
fs = new NodeJSFileSystem();
|
||||
fs = createMockFileSystem();
|
||||
fileWriter = new NewEntryPointFileWriter(fs);
|
||||
entryPoint = getEntryPointInfo(
|
||||
fs, new MockLogger(), _('/node_modules/test'), _('/node_modules/test/b')) !;
|
||||
|
@ -274,10 +257,9 @@ describe('NewEntryPointFileWriter', () => {
|
|||
contents: 'export function FooB() {} // MODIFIED'
|
||||
},
|
||||
]);
|
||||
expect(readFileSync('/node_modules/test/__ivy_ngcc__/lib/esm5.js', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/__ivy_ngcc__/lib/esm5.js')))
|
||||
.toEqual('export function FooB() {} // MODIFIED');
|
||||
expect(readFileSync('/node_modules/test/lib/esm5.js', 'utf8'))
|
||||
.toEqual('export function FooB() {}');
|
||||
expect(fs.readFile(_('/node_modules/test/lib/esm5.js'))).toEqual('export function FooB() {}');
|
||||
});
|
||||
|
||||
it('should also copy unmodified files in the program', () => {
|
||||
|
@ -287,13 +269,13 @@ describe('NewEntryPointFileWriter', () => {
|
|||
contents: 'export class FooB {} // MODIFIED'
|
||||
},
|
||||
]);
|
||||
expect(readFileSync('/node_modules/test/__ivy_ngcc__/lib/es2015/foo.js', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/__ivy_ngcc__/lib/es2015/foo.js')))
|
||||
.toEqual('export class FooB {} // MODIFIED');
|
||||
expect(readFileSync('/node_modules/test/lib/es2015/foo.js', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/lib/es2015/foo.js')))
|
||||
.toEqual('import {FooA} from "test/a"; import "events"; export class FooB {}');
|
||||
expect(readFileSync('/node_modules/test/__ivy_ngcc__/lib/es2015/index.js', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/__ivy_ngcc__/lib/es2015/index.js')))
|
||||
.toEqual('export {FooB} from "./foo"; import * from "other";');
|
||||
expect(readFileSync('/node_modules/test/lib/es2015/index.js', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/lib/es2015/index.js')))
|
||||
.toEqual('export {FooB} from "./foo"; import * from "other";');
|
||||
});
|
||||
|
||||
|
@ -301,11 +283,11 @@ describe('NewEntryPointFileWriter', () => {
|
|||
() => {
|
||||
fileWriter.writeBundle(entryPoint, esm2015bundle, [
|
||||
{
|
||||
path: '/node_modules/test/lib/es2015/foo.js',
|
||||
path: _('/node_modules/test/lib/es2015/foo.js'),
|
||||
contents: 'export class FooB {} // MODIFIED'
|
||||
},
|
||||
]);
|
||||
expect(existsSync('/node_modules/test/__ivy_ngcc__/a/index.d.ts')).toEqual(false);
|
||||
expect(fs.exists(_('/node_modules/test/__ivy_ngcc__/a/index.d.ts'))).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not copy files outside of the package', () => {
|
||||
|
@ -315,8 +297,8 @@ describe('NewEntryPointFileWriter', () => {
|
|||
contents: 'export class FooB {} // MODIFIED'
|
||||
},
|
||||
]);
|
||||
expect(existsSync('/node_modules/test/other/index.d.ts')).toEqual(false);
|
||||
expect(existsSync('/node_modules/test/events/events.js')).toEqual(false);
|
||||
expect(fs.exists(_('/node_modules/test/other/index.d.ts'))).toEqual(false);
|
||||
expect(fs.exists(_('/node_modules/test/events/events.js'))).toEqual(false);
|
||||
});
|
||||
|
||||
it('should update the package.json properties', () => {
|
||||
|
@ -326,7 +308,7 @@ describe('NewEntryPointFileWriter', () => {
|
|||
contents: 'export function FooB() {} // MODIFIED'
|
||||
},
|
||||
]);
|
||||
expect(loadPackageJson('/node_modules/test/b')).toEqual(jasmine.objectContaining({
|
||||
expect(loadPackageJson(fs, '/node_modules/test/b')).toEqual(jasmine.objectContaining({
|
||||
module_ivy_ngcc: '../__ivy_ngcc__/lib/esm5.js',
|
||||
}));
|
||||
|
||||
|
@ -336,7 +318,7 @@ describe('NewEntryPointFileWriter', () => {
|
|||
contents: 'export class FooB {} // MODIFIED'
|
||||
},
|
||||
]);
|
||||
expect(loadPackageJson('/node_modules/test/b')).toEqual(jasmine.objectContaining({
|
||||
expect(loadPackageJson(fs, '/node_modules/test/b')).toEqual(jasmine.objectContaining({
|
||||
module_ivy_ngcc: '../__ivy_ngcc__/lib/esm5.js',
|
||||
es2015_ivy_ngcc: '../__ivy_ngcc__/lib/es2015/index.js',
|
||||
}));
|
||||
|
@ -349,11 +331,11 @@ describe('NewEntryPointFileWriter', () => {
|
|||
contents: 'export declare class FooB {} // MODIFIED'
|
||||
},
|
||||
]);
|
||||
expect(readFileSync('/node_modules/test/typings/index.d.ts', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/typings/index.d.ts')))
|
||||
.toEqual('export declare class FooB {} // MODIFIED');
|
||||
expect(readFileSync('/node_modules/test/typings/index.d.ts.__ivy_ngcc_bak', 'utf8'))
|
||||
expect(fs.readFile(_('/node_modules/test/typings/index.d.ts.__ivy_ngcc_bak')))
|
||||
.toEqual('export declare class FooB {}');
|
||||
expect(existsSync('/node_modules/test/__ivy_ngcc__/typings/index.d.ts')).toBe(false);
|
||||
expect(fs.exists(_('/node_modules/test/__ivy_ngcc__/typings/index.d.ts'))).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue