diff --git a/packages/metro-file-map/src/__tests__/createStaticCrawler-test.js b/packages/metro-file-map/src/__tests__/createStaticCrawler-test.js index 3f12b6c5bc..c49179a3f5 100644 --- a/packages/metro-file-map/src/__tests__/createStaticCrawler-test.js +++ b/packages/metro-file-map/src/__tests__/createStaticCrawler-test.js @@ -79,8 +79,8 @@ function createFileMap( describe('createStaticCrawler', () => { test('builds a FileSystem from the supplied listing', async () => { const {fileMap} = createFileMap([ - {path: 'src/index.js'}, - {path: 'src/nested/other.js'}, + {path: path.join('src', 'index.js')}, + {path: path.join('src', 'nested', 'other.js')}, {path: p('absolute.js')}, ]); @@ -98,10 +98,10 @@ describe('createStaticCrawler', () => { test('populates HastePlugin from per-file plugin data', async () => { const {fileMap, hastePlugin} = createFileMap([ - {path: 'src/Thing.js', pluginData: {haste: 'Thing'}}, - {path: 'src/Thing.ios.js', pluginData: {haste: 'Thing'}}, - {path: 'src/NoHaste.js'}, - {path: 'pkg/package.json', pluginData: {haste: 'HastePkg'}}, + {path: path.join('src', 'Thing.js'), pluginData: {haste: 'Thing'}}, + {path: path.join('src', 'Thing.ios.js'), pluginData: {haste: 'Thing'}}, + {path: path.join('src', 'NoHaste.js')}, + {path: path.join('pkg', 'package.json'), pluginData: {haste: 'HastePkg'}}, ]); await fileMap.build(); @@ -122,7 +122,7 @@ describe('createStaticCrawler', () => { test('does not process any file contents', async () => { const processBatch = jest.spyOn(FileProcessor.prototype, 'processBatch'); const {fileMap} = createFileMap([ - {path: 'src/index.js', pluginData: {haste: 'Index'}}, + {path: path.join('src', 'index.js'), pluginData: {haste: 'Index'}}, ]); await fileMap.build(); @@ -137,7 +137,10 @@ describe('createStaticCrawler', () => { // data supplied here is taken at face value. Callers must filter for // themselves. const {fileMap, hastePlugin} = createFileMap([ - {path: 'node_modules/pkg/Thing.js', pluginData: {haste: 'Thing'}}, + { + path: path.join('node_modules', 'pkg', 'Thing.js'), + pluginData: {haste: 'Thing'}, + }, ]); await fileMap.build(); @@ -152,7 +155,9 @@ describe('createStaticCrawler', () => { // more than one pass - a single-use iterable would report nothing the // second time. const staticFactory = createStaticCrawler({ - files: [{path: 'src/Thing.js', pluginData: {haste: 'Thing'}}], + files: [ + {path: path.join('src', 'Thing.js'), pluginData: {haste: 'Thing'}}, + ], }); let inner: ?Crawler = null; let seenOptions: ?CrawlerOptions = null; @@ -181,7 +186,7 @@ describe('createStaticCrawler', () => { }); test('end() is safe when not watching', async () => { - const {fileMap} = createFileMap([{path: 'src/index.js'}]); + const {fileMap} = createFileMap([{path: path.join('src', 'index.js')}]); await fileMap.build(); await expect(fileMap.end()).resolves.toBeUndefined(); }); diff --git a/packages/metro-resolver/src/__tests__/scheme-resolvers-test.js b/packages/metro-resolver/src/__tests__/scheme-resolvers-test.js index 411c4701b0..f8ede811bc 100644 --- a/packages/metro-resolver/src/__tests__/scheme-resolvers-test.js +++ b/packages/metro-resolver/src/__tests__/scheme-resolvers-test.js @@ -18,13 +18,13 @@ import type { ResolutionContext, } from '../index'; -import {createResolutionContext} from './utils'; +import {createResolutionContext, posixToSystemPath as p} from './utils'; const Resolver = require('../index'); const fileMap = { - '/root/project/foo.js': '', - '/root/project/bar.js': '', + [p('/root/project/foo.js')]: '', + [p('/root/project/bar.js')]: '', }; function createContext( @@ -32,7 +32,7 @@ function createContext( ): ResolutionContext { return { ...createResolutionContext(fileMap), - originModulePath: '/root/project/foo.js', + originModulePath: p('/root/project/foo.js'), schemeResolvers, }; } @@ -58,7 +58,7 @@ function makeCapturingResolver(resolution: Resolution): { test('invokes a registered scheme resolver with the full specifier', () => { const resolution: Resolution = { type: 'sourceFile', - filePath: '/resolved/by/scheme.js', + filePath: p('/resolved/by/scheme.js'), }; const {resolver, calls} = makeCapturingResolver(resolution); const context = createContext({test: resolver}); @@ -81,7 +81,7 @@ test('scheme resolver can delegate back to default resolution', () => { expect(Resolver.resolve(context, 'test:anything', null)).toEqual({ type: 'sourceFile', - filePath: '/root/project/bar.js', + filePath: p('/root/project/bar.js'), }); }); @@ -127,7 +127,7 @@ test('an unregistered scheme still resolves if another strategy succeeds', () => const context = { ...createContext({test: resolver}), resolveHasteModule: (name: string) => - name === 'other:module' ? '/root/project/bar.js' : null, + name === 'other:module' ? p('/root/project/bar.js') : null, }; // The deprecated backwards-compatibility path: a scheme-like specifier with @@ -135,7 +135,7 @@ test('an unregistered scheme still resolves if another strategy succeeds', () => // rather than failing on the scheme. expect(Resolver.resolve(context, 'other:module', null)).toEqual({ type: 'sourceFile', - filePath: '/root/project/bar.js', + filePath: p('/root/project/bar.js'), }); expect(calls).toHaveLength(0); }); @@ -148,7 +148,7 @@ test('relative specifiers are resolved before scheme dispatch', () => { // mistaken for a scheme, even when scheme resolvers are registered. expect(Resolver.resolve(context, './bar', null)).toEqual({ type: 'sourceFile', - filePath: '/root/project/bar.js', + filePath: p('/root/project/bar.js'), }); expect(calls).toHaveLength(0); }); diff --git a/packages/metro/src/lib/__tests__/metroSchemeResolver-test.js b/packages/metro/src/lib/__tests__/metroSchemeResolver-test.js index 725ff72139..3cad290c8f 100644 --- a/packages/metro/src/lib/__tests__/metroSchemeResolver-test.js +++ b/packages/metro/src/lib/__tests__/metroSchemeResolver-test.js @@ -16,6 +16,11 @@ import type {CustomResolutionContext, CustomResolver} from 'metro-resolver'; import metroSchemeResolver from '../metroSchemeResolver'; import {createResolutionContext} from 'metro-resolver/private/__tests__/utils'; +const p: (posixPath: string) => string = + process.platform === 'win32' + ? posixPath => posixPath.replace(/^\//, 'C:\\').replaceAll('/', '\\') + : posixPath => posixPath; + type Call = { originModulePath: string, specifier: string, @@ -25,7 +30,7 @@ type Call = { function makeContext(resolveRequest: CustomResolver): CustomResolutionContext { return { ...createResolutionContext({}), - originModulePath: '/root/project/foo.js', + originModulePath: p('/root/project/foo.js'), resolveRequest, }; } @@ -43,7 +48,7 @@ function makeCapturingResolveRequest(): { specifier, platform, }); - return {type: 'sourceFile', filePath: '/resolved.js'}; + return {type: 'sourceFile', filePath: p('/resolved.js')}; }; return {resolveRequest, calls}; } @@ -54,14 +59,14 @@ test('resolves metro:babel-runtime to @babel/runtime via package self resolution expect(metroSchemeResolver(context, 'metro:babel-runtime', 'ios')).toEqual({ type: 'sourceFile', - filePath: '/resolved.js', + filePath: p('/resolved.js'), }); expect(calls).toHaveLength(1); expect(calls[0].specifier).toBe('@babel/runtime'); expect(calls[0].platform).toBe('ios'); // The origin is @babel/runtime's own package.json (statically resolved), so // Metro resolves the subpath as a package self-reference via its `exports`. - expect(calls[0].originModulePath).toContain('@babel/runtime'); + expect(calls[0].originModulePath).toContain(p('@babel/runtime')); expect(calls[0].originModulePath.endsWith('package.json')).toBe(true); }); diff --git a/packages/metro/src/lib/metroSchemeResolver.js b/packages/metro/src/lib/metroSchemeResolver.js index 7b44ad03bf..590256bd5e 100644 --- a/packages/metro/src/lib/metroSchemeResolver.js +++ b/packages/metro/src/lib/metroSchemeResolver.js @@ -38,7 +38,7 @@ function getBabelRuntimePackageJsonPath(): string { * Resolver used for Metro's own `metro:` URI scheme, currently handling only * metro:babel-runtime and subpaths. */ -const metroSchemeResolver: CustomResolver = (context, specifier, platform) => { +export default ((context, specifier, platform) => { const {protocol, pathname} = new URL(specifier); // Maps `metro:babel-runtime` (and subpaths, e.g. @@ -61,6 +61,4 @@ const metroSchemeResolver: CustomResolver = (context, specifier, platform) => { } throw new Error(`Unsupported '${protocol}' pathname: ${pathname}`); -}; - -export default metroSchemeResolver; +}) as CustomResolver;