diff --git a/CHANGELOG.md b/CHANGELOG.md index ad6df5adf66c..2682be8d5b53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - `[jest-core]` Make `detectOpenHandles` imply `runInBand` ([#8283](https://github.com/facebook/jest/pull/8283)) - `[jest-haste-map]` Fix the `mapper` option which was incorrectly ignored ([#8299](https://github.com/facebook/jest/pull/8299)) - `[jest-jasmine2]` Fix describe return value warning being shown if the describe function throws ([#8335](https://github.com/facebook/jest/pull/8335)) +- `[jest-transform]` Replace colons in transform cache filenames to support Windows ### Chore & Maintenance diff --git a/packages/jest-transform/src/ScriptTransformer.ts b/packages/jest-transform/src/ScriptTransformer.ts index 3e0e7c4d8b93..dee421aab0b7 100644 --- a/packages/jest-transform/src/ScriptTransformer.ts +++ b/packages/jest-transform/src/ScriptTransformer.ts @@ -121,11 +121,11 @@ export default class ScriptTransformer { // Create sub folders based on the cacheKey to avoid creating one // directory with many files. const cacheDir = path.join(baseCacheDir, cacheKey[0] + cacheKey[1]); + const cacheFilenamePrefix = path + .basename(filename, path.extname(filename)) + .replace(/:/g, '_COLON_'); const cachePath = slash( - path.join( - cacheDir, - path.basename(filename, path.extname(filename)) + '_' + cacheKey, - ), + path.join(cacheDir, cacheFilenamePrefix + '_' + cacheKey), ); createDirectory(cacheDir); diff --git a/packages/jest-transform/src/__tests__/script_transformer.test.js b/packages/jest-transform/src/__tests__/script_transformer.test.js index 994d28d7066c..bcacc14fb8ee 100644 --- a/packages/jest-transform/src/__tests__/script_transformer.test.js +++ b/packages/jest-transform/src/__tests__/script_transformer.test.js @@ -152,6 +152,7 @@ describe('ScriptTransformer', () => { mockFs = object({ '/fruits/banana.js': ['module.exports = "banana";'].join('\n'), + '/fruits/banana:colon.js': ['module.exports = "bananaColon";'].join('\n'), '/fruits/grapefruit.js': [ 'module.exports = function () { return "grapefruit"; }', ].join('\n'), @@ -532,6 +533,34 @@ describe('ScriptTransformer', () => { expect(writeFileAtomic.sync).toBeCalled(); }); + it('reads values from the cache when the file contains colons', () => { + const transformConfig = { + ...config, + transform: [['^.+\\.js$', 'test_preprocessor']], + }; + let scriptTransformer = new ScriptTransformer(transformConfig); + scriptTransformer.transform('/fruits/banana:colon.js', {}); + + const cachePath = getCachePath(mockFs, config); + expect(writeFileAtomic.sync).toBeCalled(); + expect(writeFileAtomic.sync.mock.calls[0][0]).toBe(cachePath); + + // Cache the state in `mockFsCopy` + const mockFsCopy = mockFs; + jest.resetModuleRegistry(); + reset(); + + // Restore the cached fs + mockFs = mockFsCopy; + scriptTransformer = new ScriptTransformer(transformConfig); + scriptTransformer.transform('/fruits/banana:colon.js', {}); + + expect(fs.readFileSync).toHaveBeenCalledTimes(2); + expect(fs.readFileSync).toBeCalledWith('/fruits/banana:colon.js', 'utf8'); + expect(fs.readFileSync).toBeCalledWith(cachePath, 'utf8'); + expect(writeFileAtomic.sync).not.toBeCalled(); + }); + it('does not reuse the in-memory cache between different projects', () => { const scriptTransformer = new ScriptTransformer({ ...config,