angular-cn/packages/compiler-cli/ngcc/test/dependencies/esm_dependency_host_spec.ts

272 lines
14 KiB
TypeScript
Raw Normal View History

/**
* @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';
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
import {absoluteFrom, getFileSystem, relativeFrom} from '../../../src/ngtsc/file_system';
import {runInEachFileSystem} from '../../../src/ngtsc/file_system/testing';
import {loadTestFiles} from '../../../test/helpers';
fix(ivy): ngcc - resolve `main` property paths correctly (#31509) There are two places in the ngcc processing where it needs to load the content of a file given by a general path: * when determining the format of an entry-point. To do this ngcc uses the value of the relevant property in package.json. But in the case of `main` it must parse the contents of the entry-point file to decide whether the format is UMD or CommonJS. * when parsing the source files for dependencies to determine the order in which compilation must occur. The relative imports in each file are parsed and followed recursively, looking for external imports. Previously, we naively assumed that the path would match the file name exactly. But actually we must consider the standard module resolution conventions. E.g. the extension (.js) may be missing, or the path may refer to a directory containing an index.js file. This commit fixes both places. This commit now requires the `DependencyHost` instances to check the existence of more files than before (at worst all the different possible post-fixes). This should not create a significant performance reduction for ngcc. Since the results of the checks will be cached, and similar work is done inside the TS compiler, so what we lose in doing it here, is saved later in the processing. The main performance loss would be where there are lots of files that need to be parsed for dependencies that do not end up being processed by TS. But compared to the main ngcc processing this dependency parsing is a small proportion of the work done and so should not impact much on the overall performance of ngcc. // FW-1444 PR Close #31509
2019-07-11 07:34:45 -04:00
import {EsmDependencyHost, hasImportOrReexportStatements, isStringImportOrReexport} from '../../src/dependencies/esm_dependency_host';
import {ModuleResolver} from '../../src/dependencies/module_resolver';
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
runInEachFileSystem(() => {
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
describe('EsmDependencyHost', () => {
let _: typeof absoluteFrom;
let host: EsmDependencyHost;
beforeEach(() => {
_ = absoluteFrom;
setupMockFileSystem();
const fs = getFileSystem();
host = new EsmDependencyHost(fs, new ModuleResolver(fs));
});
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
describe('getDependencies()', () => {
it('should not generate a TS AST if the source does not contain any imports or re-exports',
() => {
spyOn(ts, 'createSourceFile');
host.findDependencies(_('/no/imports/or/re-exports/index.js'));
expect(ts.createSourceFile).not.toHaveBeenCalled();
});
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
it('should resolve all the external imports of the source file', () => {
const {dependencies, missing, deepImports} =
host.findDependencies(_('/external/imports/index.js'));
expect(dependencies.size).toBe(2);
expect(missing.size).toBe(0);
expect(deepImports.size).toBe(0);
expect(dependencies.has(_('/node_modules/lib-1'))).toBe(true);
expect(dependencies.has(_('/node_modules/lib-1/sub-1'))).toBe(true);
});
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
it('should resolve all the external re-exports of the source file', () => {
const {dependencies, missing, deepImports} =
host.findDependencies(_('/external/re-exports/index.js'));
expect(dependencies.size).toBe(2);
expect(missing.size).toBe(0);
expect(deepImports.size).toBe(0);
expect(dependencies.has(_('/node_modules/lib-1'))).toBe(true);
expect(dependencies.has(_('/node_modules/lib-1/sub-1'))).toBe(true);
});
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
it('should capture missing external imports', () => {
const {dependencies, missing, deepImports} =
host.findDependencies(_('/external/imports-missing/index.js'));
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
expect(dependencies.size).toBe(1);
expect(dependencies.has(_('/node_modules/lib-1'))).toBe(true);
expect(missing.size).toBe(1);
expect(missing.has(relativeFrom('missing'))).toBe(true);
expect(deepImports.size).toBe(0);
});
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
it('should not register deep imports as missing', () => {
// This scenario verifies the behavior of the dependency analysis when an external import
// is found that does not map to an entry-point but still exists on disk, i.e. a deep
// import. Such deep imports are captured for diagnostics purposes.
const {dependencies, missing, deepImports} =
host.findDependencies(_('/external/deep-import/index.js'));
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
expect(dependencies.size).toBe(0);
expect(missing.size).toBe(0);
expect(deepImports.size).toBe(1);
expect(deepImports.has(_('/node_modules/lib-1/deep/import'))).toBe(true);
});
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
it('should recurse into internal dependencies', () => {
const {dependencies, missing, deepImports} =
host.findDependencies(_('/internal/outer/index.js'));
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
expect(dependencies.size).toBe(1);
expect(dependencies.has(_('/node_modules/lib-1/sub-1'))).toBe(true);
expect(missing.size).toBe(0);
expect(deepImports.size).toBe(0);
});
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
it('should handle circular internal dependencies', () => {
const {dependencies, missing, deepImports} =
host.findDependencies(_('/internal/circular-a/index.js'));
expect(dependencies.size).toBe(2);
expect(dependencies.has(_('/node_modules/lib-1'))).toBe(true);
expect(dependencies.has(_('/node_modules/lib-1/sub-1'))).toBe(true);
expect(missing.size).toBe(0);
expect(deepImports.size).toBe(0);
});
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
it('should support `paths` alias mappings when resolving modules', () => {
const fs = getFileSystem();
host = new EsmDependencyHost(fs, new ModuleResolver(fs, {
baseUrl: '/dist',
paths: {
'@app/*': ['*'],
'@lib/*/test': ['lib/*/test'],
}
}));
const {dependencies, missing, deepImports} =
host.findDependencies(_('/path-alias/index.js'));
expect(dependencies.size).toBe(4);
expect(dependencies.has(_('/dist/components'))).toBe(true);
expect(dependencies.has(_('/dist/shared'))).toBe(true);
expect(dependencies.has(_('/dist/lib/shared/test'))).toBe(true);
expect(dependencies.has(_('/node_modules/lib-1'))).toBe(true);
expect(missing.size).toBe(0);
expect(deepImports.size).toBe(0);
});
fix(ivy): ngcc - resolve `main` property paths correctly (#31509) There are two places in the ngcc processing where it needs to load the content of a file given by a general path: * when determining the format of an entry-point. To do this ngcc uses the value of the relevant property in package.json. But in the case of `main` it must parse the contents of the entry-point file to decide whether the format is UMD or CommonJS. * when parsing the source files for dependencies to determine the order in which compilation must occur. The relative imports in each file are parsed and followed recursively, looking for external imports. Previously, we naively assumed that the path would match the file name exactly. But actually we must consider the standard module resolution conventions. E.g. the extension (.js) may be missing, or the path may refer to a directory containing an index.js file. This commit fixes both places. This commit now requires the `DependencyHost` instances to check the existence of more files than before (at worst all the different possible post-fixes). This should not create a significant performance reduction for ngcc. Since the results of the checks will be cached, and similar work is done inside the TS compiler, so what we lose in doing it here, is saved later in the processing. The main performance loss would be where there are lots of files that need to be parsed for dependencies that do not end up being processed by TS. But compared to the main ngcc processing this dependency parsing is a small proportion of the work done and so should not impact much on the overall performance of ngcc. // FW-1444 PR Close #31509
2019-07-11 07:34:45 -04:00
it('should handle entry-point paths with no extension', () => {
const {dependencies, missing, deepImports} =
host.findDependencies(_('/external/imports/index'));
expect(dependencies.size).toBe(2);
expect(missing.size).toBe(0);
expect(deepImports.size).toBe(0);
expect(dependencies.has(_('/node_modules/lib-1'))).toBe(true);
expect(dependencies.has(_('/node_modules/lib-1/sub-1'))).toBe(true);
});
});
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
function setupMockFileSystem(): void {
loadTestFiles([
{
name: _('/no/imports/or/re-exports/index.js'),
contents: '// some text but no import-like statements'
},
{name: _('/no/imports/or/re-exports/package.json'), contents: '{"esm2015": "./index.js"}'},
{name: _('/no/imports/or/re-exports/index.metadata.json'), contents: 'MOCK METADATA'},
{
name: _('/external/imports/index.js'),
contents: `import {X} from 'lib-1';\nimport {Y} from 'lib-1/sub-1';`
},
{name: _('/external/imports/package.json'), contents: '{"esm2015": "./index.js"}'},
{name: _('/external/imports/index.metadata.json'), contents: 'MOCK METADATA'},
{
name: _('/external/re-exports/index.js'),
contents: `export {X} from 'lib-1';\nexport {Y} from 'lib-1/sub-1';`
},
{name: _('/external/re-exports/package.json'), contents: '{"esm2015": "./index.js"}'},
{name: _('/external/re-exports/index.metadata.json'), contents: 'MOCK METADATA'},
{
name: _('/external/imports-missing/index.js'),
contents: `import {X} from 'lib-1';\nimport {Y} from 'missing';`
},
{name: _('/external/imports-missing/package.json'), contents: '{"esm2015": "./index.js"}'},
{name: _('/external/imports-missing/index.metadata.json'), contents: 'MOCK METADATA'},
{
name: _('/external/deep-import/index.js'),
contents: `import {Y} from 'lib-1/deep/import';`
},
{name: _('/external/deep-import/package.json'), contents: '{"esm2015": "./index.js"}'},
{name: _('/external/deep-import/index.metadata.json'), contents: 'MOCK METADATA'},
{name: _('/internal/outer/index.js'), contents: `import {X} from '../inner';`},
{name: _('/internal/outer/package.json'), contents: '{"esm2015": "./index.js"}'},
{name: _('/internal/outer/index.metadata.json'), contents: 'MOCK METADATA'},
{
name: _('/internal/inner/index.js'),
contents: `import {Y} from 'lib-1/sub-1'; export declare class X {}`
},
{
name: _('/internal/circular-a/index.js'),
contents:
`import {B} from '../circular-b'; import {X} from '../circular-b'; export {Y} from 'lib-1/sub-1';`
},
{
name: _('/internal/circular-b/index.js'),
contents:
`import {A} from '../circular-a'; import {Y} from '../circular-a'; export {X} from 'lib-1';`
},
{name: _('/internal/circular-a/package.json'), contents: '{"esm2015": "./index.js"}'},
{name: _('/internal/circular-a/index.metadata.json'), contents: 'MOCK METADATA'},
{name: _('/re-directed/index.js'), contents: `import {Z} from 'lib-1/sub-2';`},
{name: _('/re-directed/package.json'), contents: '{"esm2015": "./index.js"}'},
{name: _('/re-directed/index.metadata.json'), contents: 'MOCK METADATA'},
{
name: _('/path-alias/index.js'),
contents:
`import {TestHelper} from '@app/components';\nimport {Service} from '@app/shared';\nimport {TestHelper} from '@lib/shared/test';\nimport {X} from 'lib-1';`
},
{name: _('/path-alias/package.json'), contents: '{"esm2015": "./index.js"}'},
{name: _('/path-alias/index.metadata.json'), contents: 'MOCK METADATA'},
{name: _('/node_modules/lib-1/index.js'), contents: 'export declare class X {}'},
{name: _('/node_modules/lib-1/package.json'), contents: '{"esm2015": "./index.js"}'},
{name: _('/node_modules/lib-1/index.metadata.json'), contents: 'MOCK METADATA'},
{
name: _('/node_modules/lib-1/deep/import/index.js'),
contents: 'export declare class DeepImport {}'
},
{name: _('/node_modules/lib-1/sub-1/index.js'), contents: 'export declare class Y {}'},
{name: _('/node_modules/lib-1/sub-1/package.json'), contents: '{"esm2015": "./index.js"}'},
{name: _('/node_modules/lib-1/sub-1/index.metadata.json'), contents: 'MOCK METADATA'},
{name: _('/node_modules/lib-1/sub-2.js'), contents: `export * from './sub-2/sub-2';`},
{name: _('/node_modules/lib-1/sub-2/sub-2.js'), contents: `export declare class Z {}';`},
{name: _('/node_modules/lib-1/sub-2/package.json'), contents: '{"esm2015": "./sub-2.js"}'},
{name: _('/node_modules/lib-1/sub-2/sub-2.metadata.json'), contents: 'MOCK METADATA'},
{name: _('/dist/components/index.js'), contents: `class MyComponent {};`},
{name: _('/dist/components/package.json'), contents: '{"esm2015": "./index.js"}'},
{name: _('/dist/components/index.metadata.json'), contents: 'MOCK METADATA'},
{
name: _('/dist/shared/index.js'),
contents: `import {X} from 'lib-1';\nexport class Service {}`
},
{name: _('/dist/shared/package.json'), contents: '{"esm2015": "./index.js"}'},
{name: _('/dist/shared/index.metadata.json'), contents: 'MOCK METADATA'},
{name: _('/dist/lib/shared/test/index.js'), contents: `export class TestHelper {}`},
{name: _('/dist/lib/shared/test/package.json'), contents: '{"esm2015": "./index.js"}'},
{name: _('/dist/lib/shared/test/index.metadata.json'), contents: 'MOCK METADATA'},
]);
}
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
describe('isStringImportOrReexport', () => {
it('should return true if the statement is an import', () => {
fix(ivy): ngcc - resolve `main` property paths correctly (#31509) There are two places in the ngcc processing where it needs to load the content of a file given by a general path: * when determining the format of an entry-point. To do this ngcc uses the value of the relevant property in package.json. But in the case of `main` it must parse the contents of the entry-point file to decide whether the format is UMD or CommonJS. * when parsing the source files for dependencies to determine the order in which compilation must occur. The relative imports in each file are parsed and followed recursively, looking for external imports. Previously, we naively assumed that the path would match the file name exactly. But actually we must consider the standard module resolution conventions. E.g. the extension (.js) may be missing, or the path may refer to a directory containing an index.js file. This commit fixes both places. This commit now requires the `DependencyHost` instances to check the existence of more files than before (at worst all the different possible post-fixes). This should not create a significant performance reduction for ngcc. Since the results of the checks will be cached, and similar work is done inside the TS compiler, so what we lose in doing it here, is saved later in the processing. The main performance loss would be where there are lots of files that need to be parsed for dependencies that do not end up being processed by TS. But compared to the main ngcc processing this dependency parsing is a small proportion of the work done and so should not impact much on the overall performance of ngcc. // FW-1444 PR Close #31509
2019-07-11 07:34:45 -04:00
expect(isStringImportOrReexport(createStatement('import {X} from "some/x";'))).toBe(true);
expect(isStringImportOrReexport(createStatement('import * as X from "some/x";')))
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
.toBe(true);
});
it('should return true if the statement is a re-export', () => {
fix(ivy): ngcc - resolve `main` property paths correctly (#31509) There are two places in the ngcc processing where it needs to load the content of a file given by a general path: * when determining the format of an entry-point. To do this ngcc uses the value of the relevant property in package.json. But in the case of `main` it must parse the contents of the entry-point file to decide whether the format is UMD or CommonJS. * when parsing the source files for dependencies to determine the order in which compilation must occur. The relative imports in each file are parsed and followed recursively, looking for external imports. Previously, we naively assumed that the path would match the file name exactly. But actually we must consider the standard module resolution conventions. E.g. the extension (.js) may be missing, or the path may refer to a directory containing an index.js file. This commit fixes both places. This commit now requires the `DependencyHost` instances to check the existence of more files than before (at worst all the different possible post-fixes). This should not create a significant performance reduction for ngcc. Since the results of the checks will be cached, and similar work is done inside the TS compiler, so what we lose in doing it here, is saved later in the processing. The main performance loss would be where there are lots of files that need to be parsed for dependencies that do not end up being processed by TS. But compared to the main ngcc processing this dependency parsing is a small proportion of the work done and so should not impact much on the overall performance of ngcc. // FW-1444 PR Close #31509
2019-07-11 07:34:45 -04:00
expect(isStringImportOrReexport(createStatement('export {X} from "some/x";'))).toBe(true);
expect(isStringImportOrReexport(createStatement('export * from "some/x";'))).toBe(true);
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
});
it('should return false if the statement is not an import or a re-export', () => {
fix(ivy): ngcc - resolve `main` property paths correctly (#31509) There are two places in the ngcc processing where it needs to load the content of a file given by a general path: * when determining the format of an entry-point. To do this ngcc uses the value of the relevant property in package.json. But in the case of `main` it must parse the contents of the entry-point file to decide whether the format is UMD or CommonJS. * when parsing the source files for dependencies to determine the order in which compilation must occur. The relative imports in each file are parsed and followed recursively, looking for external imports. Previously, we naively assumed that the path would match the file name exactly. But actually we must consider the standard module resolution conventions. E.g. the extension (.js) may be missing, or the path may refer to a directory containing an index.js file. This commit fixes both places. This commit now requires the `DependencyHost` instances to check the existence of more files than before (at worst all the different possible post-fixes). This should not create a significant performance reduction for ngcc. Since the results of the checks will be cached, and similar work is done inside the TS compiler, so what we lose in doing it here, is saved later in the processing. The main performance loss would be where there are lots of files that need to be parsed for dependencies that do not end up being processed by TS. But compared to the main ngcc processing this dependency parsing is a small proportion of the work done and so should not impact much on the overall performance of ngcc. // FW-1444 PR Close #31509
2019-07-11 07:34:45 -04:00
expect(isStringImportOrReexport(createStatement('class X {}'))).toBe(false);
expect(isStringImportOrReexport(createStatement('export function foo() {}'))).toBe(false);
expect(isStringImportOrReexport(createStatement('export const X = 10;'))).toBe(false);
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
});
function createStatement(source: string) {
return ts
.createSourceFile('source.js', source, ts.ScriptTarget.ES2015, false, ts.ScriptKind.JS)
.statements[0];
}
});
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
describe('hasImportOrReexportStatements', () => {
it('should return true if there is an import statement', () => {
fix(ivy): ngcc - resolve `main` property paths correctly (#31509) There are two places in the ngcc processing where it needs to load the content of a file given by a general path: * when determining the format of an entry-point. To do this ngcc uses the value of the relevant property in package.json. But in the case of `main` it must parse the contents of the entry-point file to decide whether the format is UMD or CommonJS. * when parsing the source files for dependencies to determine the order in which compilation must occur. The relative imports in each file are parsed and followed recursively, looking for external imports. Previously, we naively assumed that the path would match the file name exactly. But actually we must consider the standard module resolution conventions. E.g. the extension (.js) may be missing, or the path may refer to a directory containing an index.js file. This commit fixes both places. This commit now requires the `DependencyHost` instances to check the existence of more files than before (at worst all the different possible post-fixes). This should not create a significant performance reduction for ngcc. Since the results of the checks will be cached, and similar work is done inside the TS compiler, so what we lose in doing it here, is saved later in the processing. The main performance loss would be where there are lots of files that need to be parsed for dependencies that do not end up being processed by TS. But compared to the main ngcc processing this dependency parsing is a small proportion of the work done and so should not impact much on the overall performance of ngcc. // FW-1444 PR Close #31509
2019-07-11 07:34:45 -04:00
expect(hasImportOrReexportStatements('import {X} from "some/x";')).toBe(true);
expect(hasImportOrReexportStatements('import * as X from "some/x";')).toBe(true);
expect(hasImportOrReexportStatements('blah blah\n\n import {X} from "some/x";\nblah blah'))
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
.toBe(true);
fix(ivy): ngcc - resolve `main` property paths correctly (#31509) There are two places in the ngcc processing where it needs to load the content of a file given by a general path: * when determining the format of an entry-point. To do this ngcc uses the value of the relevant property in package.json. But in the case of `main` it must parse the contents of the entry-point file to decide whether the format is UMD or CommonJS. * when parsing the source files for dependencies to determine the order in which compilation must occur. The relative imports in each file are parsed and followed recursively, looking for external imports. Previously, we naively assumed that the path would match the file name exactly. But actually we must consider the standard module resolution conventions. E.g. the extension (.js) may be missing, or the path may refer to a directory containing an index.js file. This commit fixes both places. This commit now requires the `DependencyHost` instances to check the existence of more files than before (at worst all the different possible post-fixes). This should not create a significant performance reduction for ngcc. Since the results of the checks will be cached, and similar work is done inside the TS compiler, so what we lose in doing it here, is saved later in the processing. The main performance loss would be where there are lots of files that need to be parsed for dependencies that do not end up being processed by TS. But compared to the main ngcc processing this dependency parsing is a small proportion of the work done and so should not impact much on the overall performance of ngcc. // FW-1444 PR Close #31509
2019-07-11 07:34:45 -04:00
expect(hasImportOrReexportStatements('\t\timport {X} from "some/x";')).toBe(true);
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
});
it('should return true if there is a re-export statement', () => {
fix(ivy): ngcc - resolve `main` property paths correctly (#31509) There are two places in the ngcc processing where it needs to load the content of a file given by a general path: * when determining the format of an entry-point. To do this ngcc uses the value of the relevant property in package.json. But in the case of `main` it must parse the contents of the entry-point file to decide whether the format is UMD or CommonJS. * when parsing the source files for dependencies to determine the order in which compilation must occur. The relative imports in each file are parsed and followed recursively, looking for external imports. Previously, we naively assumed that the path would match the file name exactly. But actually we must consider the standard module resolution conventions. E.g. the extension (.js) may be missing, or the path may refer to a directory containing an index.js file. This commit fixes both places. This commit now requires the `DependencyHost` instances to check the existence of more files than before (at worst all the different possible post-fixes). This should not create a significant performance reduction for ngcc. Since the results of the checks will be cached, and similar work is done inside the TS compiler, so what we lose in doing it here, is saved later in the processing. The main performance loss would be where there are lots of files that need to be parsed for dependencies that do not end up being processed by TS. But compared to the main ngcc processing this dependency parsing is a small proportion of the work done and so should not impact much on the overall performance of ngcc. // FW-1444 PR Close #31509
2019-07-11 07:34:45 -04:00
expect(hasImportOrReexportStatements('export {X} from "some/x";')).toBe(true);
expect(hasImportOrReexportStatements('blah blah\n\n export {X} from "some/x";\nblah blah'))
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
.toBe(true);
fix(ivy): ngcc - resolve `main` property paths correctly (#31509) There are two places in the ngcc processing where it needs to load the content of a file given by a general path: * when determining the format of an entry-point. To do this ngcc uses the value of the relevant property in package.json. But in the case of `main` it must parse the contents of the entry-point file to decide whether the format is UMD or CommonJS. * when parsing the source files for dependencies to determine the order in which compilation must occur. The relative imports in each file are parsed and followed recursively, looking for external imports. Previously, we naively assumed that the path would match the file name exactly. But actually we must consider the standard module resolution conventions. E.g. the extension (.js) may be missing, or the path may refer to a directory containing an index.js file. This commit fixes both places. This commit now requires the `DependencyHost` instances to check the existence of more files than before (at worst all the different possible post-fixes). This should not create a significant performance reduction for ngcc. Since the results of the checks will be cached, and similar work is done inside the TS compiler, so what we lose in doing it here, is saved later in the processing. The main performance loss would be where there are lots of files that need to be parsed for dependencies that do not end up being processed by TS. But compared to the main ngcc processing this dependency parsing is a small proportion of the work done and so should not impact much on the overall performance of ngcc. // FW-1444 PR Close #31509
2019-07-11 07:34:45 -04:00
expect(hasImportOrReexportStatements('\t\texport {X} from "some/x";')).toBe(true);
expect(hasImportOrReexportStatements(
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
'blah blah\n\n export * from "@angular/core;\nblah blah'))
.toBe(true);
});
it('should return false if there is no import nor re-export statement', () => {
fix(ivy): ngcc - resolve `main` property paths correctly (#31509) There are two places in the ngcc processing where it needs to load the content of a file given by a general path: * when determining the format of an entry-point. To do this ngcc uses the value of the relevant property in package.json. But in the case of `main` it must parse the contents of the entry-point file to decide whether the format is UMD or CommonJS. * when parsing the source files for dependencies to determine the order in which compilation must occur. The relative imports in each file are parsed and followed recursively, looking for external imports. Previously, we naively assumed that the path would match the file name exactly. But actually we must consider the standard module resolution conventions. E.g. the extension (.js) may be missing, or the path may refer to a directory containing an index.js file. This commit fixes both places. This commit now requires the `DependencyHost` instances to check the existence of more files than before (at worst all the different possible post-fixes). This should not create a significant performance reduction for ngcc. Since the results of the checks will be cached, and similar work is done inside the TS compiler, so what we lose in doing it here, is saved later in the processing. The main performance loss would be where there are lots of files that need to be parsed for dependencies that do not end up being processed by TS. But compared to the main ngcc processing this dependency parsing is a small proportion of the work done and so should not impact much on the overall performance of ngcc. // FW-1444 PR Close #31509
2019-07-11 07:34:45 -04:00
expect(hasImportOrReexportStatements('blah blah')).toBe(false);
expect(hasImportOrReexportStatements('export function moo() {}')).toBe(false);
expect(hasImportOrReexportStatements('Some text that happens to include the word import'))
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
.toBe(false);
});
});
});
refactor(ivy): implement a virtual file-system layer in ngtsc + ngcc (#30921) To improve cross platform support, all file access (and path manipulation) is now done through a well known interface (`FileSystem`). For testing a number of `MockFileSystem` implementations are provided. These provide an in-memory file-system which emulates operating systems like OS/X, Unix and Windows. The current file system is always available via the static method, `FileSystem.getFileSystem()`. This is also used by a number of static methods on `AbsoluteFsPath` and `PathSegment`, to avoid having to pass `FileSystem` objects around all the time. The result of this is that one must be careful to ensure that the file-system has been initialized before using any of these static methods. To prevent this happening accidentally the current file system always starts out as an instance of `InvalidFileSystem`, which will throw an error if any of its methods are called. You can set the current file-system by calling `FileSystem.setFileSystem()`. During testing you can call the helper function `initMockFileSystem(os)` which takes a string name of the OS to emulate, and will also monkey-patch aspects of the TypeScript library to ensure that TS is also using the current file-system. Finally there is the `NgtscCompilerHost` to be used for any TypeScript compilation, which uses a given file-system. All tests that interact with the file-system should be tested against each of the mock file-systems. A series of helpers have been provided to support such tests: * `runInEachFileSystem()` - wrap your tests in this helper to run all the wrapped tests in each of the mock file-systems. * `addTestFilesToFileSystem()` - use this to add files and their contents to the mock file system for testing. * `loadTestFilesFromDisk()` - use this to load a mirror image of files on disk into the in-memory mock file-system. * `loadFakeCore()` - use this to load a fake version of `@angular/core` into the mock file-system. All ngcc and ngtsc source and tests now use this virtual file-system setup. PR Close #30921
2019-06-06 15:22:32 -04:00
});