From fc48b91f29389c83faf93205150494ae29bfaeea Mon Sep 17 00:00:00 2001 From: Jean Lauliac Date: Tue, 27 Jun 2017 19:34:03 +0100 Subject: [PATCH] jest-haste-map: watchman crawler: normalize paths (#3887) * jest-haste-map: watchman crawler: normalize paths * also normalize path coming from watcher * simplify, add module + tests * add posix case --- .../jest-haste-map/src/crawlers/watchman.js | 3 ++- packages/jest-haste-map/src/index.js | 3 ++- .../lib/__tests__/normalize_path_sep.test.js | 27 +++++++++++++++++++ .../src/lib/normalize_path_sep.js | 20 ++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 packages/jest-haste-map/src/lib/__tests__/normalize_path_sep.test.js create mode 100644 packages/jest-haste-map/src/lib/normalize_path_sep.js diff --git a/packages/jest-haste-map/src/crawlers/watchman.js b/packages/jest-haste-map/src/crawlers/watchman.js index 2c79d289d5cf..9125911e5b5b 100644 --- a/packages/jest-haste-map/src/crawlers/watchman.js +++ b/packages/jest-haste-map/src/crawlers/watchman.js @@ -11,6 +11,7 @@ import type {InternalHasteMap} from 'types/HasteMap'; import type {CrawlerOptions} from '../types'; +import normalizePathSep from '../lib/normalize_path_sep'; import path from 'path'; import watchman from 'fb-watchman'; import H from '../constants'; @@ -104,7 +105,7 @@ module.exports = function watchmanCrawl( clocks[root] = response.clock; response.files.forEach(fileData => { - const name = root + path.sep + fileData.name; + const name = root + path.sep + normalizePathSep(fileData.name); if (!fileData.exists) { delete files[name]; } else if (!ignore(name)) { diff --git a/packages/jest-haste-map/src/index.js b/packages/jest-haste-map/src/index.js index 50aa9321d165..571285386e68 100644 --- a/packages/jest-haste-map/src/index.js +++ b/packages/jest-haste-map/src/index.js @@ -38,6 +38,7 @@ import HasteModuleMap from './module_map'; import getMockName from './get_mock_name'; import getPlatformExtension from './lib/get_platform_extension'; import nodeCrawl from './crawlers/node'; +import normalizePathSep from './lib/normalize_path_sep'; import watchmanCrawl from './crawlers/watchman'; import worker from './worker'; @@ -616,7 +617,7 @@ class HasteMap extends EventEmitter { root: Path, stat: {mtime: Date}, ) => { - filePath = path.join(root, filePath); + filePath = path.join(root, normalizePathSep(filePath)); if ( this._ignore(filePath) || !extensions.some(extension => filePath.endsWith(extension)) diff --git a/packages/jest-haste-map/src/lib/__tests__/normalize_path_sep.test.js b/packages/jest-haste-map/src/lib/__tests__/normalize_path_sep.test.js new file mode 100644 index 000000000000..9f28324aa12d --- /dev/null +++ b/packages/jest-haste-map/src/lib/__tests__/normalize_path_sep.test.js @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @emails oncall+jsinfra + */ +'use strict'; + +describe('normalizePathSep', () => { + it('does nothing on posix', () => { + jest.resetModules(); + jest.mock('path', () => require.requireActual('path').posix); + const normalizePathSep = require('../normalize_path_sep'); + expect(normalizePathSep('foo/bar/baz.js')).toEqual('foo/bar/baz.js'); + }); + + it('replace slashes on windows', () => { + jest.resetModules(); + jest.mock('path', () => require.requireActual('path').win32); + const normalizePathSep = require('../normalize_path_sep'); + expect(normalizePathSep('foo/bar/baz.js')).toEqual('foo\\bar\\baz.js'); + }); +}); diff --git a/packages/jest-haste-map/src/lib/normalize_path_sep.js b/packages/jest-haste-map/src/lib/normalize_path_sep.js new file mode 100644 index 000000000000..abd3eb06ea21 --- /dev/null +++ b/packages/jest-haste-map/src/lib/normalize_path_sep.js @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @flow + */ + +const path = require('path'); + +let normalizePathSep; +if (path.sep == '/') { + normalizePathSep = (filePath: string) => filePath; +} else { + normalizePathSep = (filePath: string) => filePath.replace(/\//g, path.sep); +} + +module.exports = normalizePathSep;