metro-bundler: @format node-haste subdir

Summary: Format everything, one subdir at a time.

Reviewed By: mjesun

Differential Revision: D5481590

fbshipit-source-id: 6d9157e6857d61b8116bcf9285bd4be415c5ba01
This commit is contained in:
Jean Lauliac 2017-07-24 15:29:33 -07:00 committed by Facebook Github Bot
parent 0f3d7117d4
commit 74e78ee43f
11 changed files with 178 additions and 140 deletions

View File

@ -1,4 +1,4 @@
/** /**
* Copyright (c) 2015-present, Facebook, Inc. * Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *
@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
* *
* @flow * @flow
* @format
*/ */
'use strict'; 'use strict';
@ -16,11 +17,13 @@ const path = require('path');
const NODE_MODULES = path.sep + 'node_modules' + path.sep; const NODE_MODULES = path.sep + 'node_modules' + path.sep;
class DependencyGraphHelpers { class DependencyGraphHelpers {
_providesModuleNodeModules: Array<string>; _providesModuleNodeModules: Array<string>;
_assetExts: Array<string>; _assetExts: Array<string>;
constructor({providesModuleNodeModules, assetExts}: { constructor({
providesModuleNodeModules,
assetExts,
}: {
+providesModuleNodeModules: Array<string>, +providesModuleNodeModules: Array<string>,
+assetExts: Array<string>, +assetExts: Array<string>,
}) { }) {

View File

@ -1,4 +1,4 @@
/** /**
* Copyright (c) 2015-present, Facebook, Inc. * Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *
@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
* *
* @flow * @flow
* @format
*/ */
'use strict'; 'use strict';
@ -14,7 +15,6 @@
const NO_OPTIONS = {}; const NO_OPTIONS = {};
class ResolutionResponse<TModule: {hash(): string}, TOptions> { class ResolutionResponse<TModule: {hash(): string}, TOptions> {
dependencies: Array<TModule>; dependencies: Array<TModule>;
mainModuleId: ?(number | string); mainModuleId: ?(number | string);
mocks: mixed; mocks: mixed;
@ -49,20 +49,16 @@ class ResolutionResponse<TModule: {hash(): string}, TOptions> {
mocks = this.mocks, mocks = this.mocks,
} = properties; } = properties;
const numPrependedDependencies = dependencies === this.dependencies const numPrependedDependencies =
? this.numPrependedDependencies : 0; dependencies === this.dependencies ? this.numPrependedDependencies : 0;
/* $FlowFixMe: Flow doesn't like Object.assign on class-made objects. */ /* $FlowFixMe: Flow doesn't like Object.assign on class-made objects. */
return Object.assign( return Object.assign(new this.constructor(this.options), this, {
new this.constructor(this.options), dependencies,
this, mainModuleId,
{ mocks,
dependencies, numPrependedDependencies,
mainModuleId, });
mocks,
numPrependedDependencies,
},
);
} }
_assertNotFinalized() { _assertNotFinalized() {
@ -119,7 +115,9 @@ class ResolutionResponse<TModule: {hash(): string}, TOptions> {
this.mocks = mocks; this.mocks = mocks;
} }
getResolvedDependencyPairs(module: TModule): $ReadOnlyArray<[string, TModule]> { getResolvedDependencyPairs(
module: TModule,
): $ReadOnlyArray<[string, TModule]> {
this._assertFinalized(); this._assertFinalized();
return this._mappings[module.hash()]; return this._mappings[module.hash()];
} }

View File

@ -5,7 +5,10 @@
* This source code is licensed under the BSD-style license found in the * 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 * 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. * of patent rights can be found in the PATENTS file in the same directory.
*
* @format
*/ */
'use strict'; 'use strict';
const {EventEmitter} = require('events'); const {EventEmitter} = require('events');
@ -169,20 +172,27 @@ fs.open.mockImplementation(function(filepath) {
callback(error, fd); callback(error, fd);
}); });
fs.read.mockImplementation((fd, buffer, writeOffset, length, position, callback = noop) => { fs.read.mockImplementation(
let bytesWritten; (fd, buffer, writeOffset, length, position, callback = noop) => {
try { let bytesWritten;
if (position == null || position < 0) { try {
({position} = fd); if (position == null || position < 0) {
({position} = fd);
}
bytesWritten = fd.buffer.copy(
buffer,
writeOffset,
position,
position + length,
);
fd.position = position + bytesWritten;
} catch (e) {
callback(Error('invalid argument'));
return;
} }
bytesWritten = fd.buffer.copy(buffer, writeOffset, position, position + length); callback(null, bytesWritten, buffer);
fd.position = position + bytesWritten; },
} catch (e) { );
callback(Error('invalid argument'));
return;
}
callback(null, bytesWritten, buffer);
});
fs.close.mockImplementation((fd, callback = noop) => { fs.close.mockImplementation((fd, callback = noop) => {
try { try {
@ -263,7 +273,9 @@ fs.watch.mockImplementation((filename, options, listener) => {
fsWatcher.on('change', listener); fsWatcher.on('change', listener);
fsWatcher.close = () => { fsWatcher.close = () => {
watcherList.splice(watcherList.indexOf(fsWatcher), 1); watcherList.splice(watcherList.indexOf(fsWatcher), 1);
fsWatcher.close = () => { throw new Error('FSWatcher is already closed'); }; fsWatcher.close = () => {
throw new Error('FSWatcher is already closed');
};
}; };
watcherList.push(fsWatcher); watcherList.push(fsWatcher);
}); });
@ -273,7 +285,9 @@ fs.__triggerWatchEvent = (eventType, filename) => {
directWatchers.forEach(wtc => wtc.emit('change', eventType)); directWatchers.forEach(wtc => wtc.emit('change', eventType));
const dirPath = path.dirname(filename); const dirPath = path.dirname(filename);
const dirWatchers = watcherListByPath.get(dirPath) || []; const dirWatchers = watcherListByPath.get(dirPath) || [];
dirWatchers.forEach(wtc => wtc.emit('change', eventType, path.relative(dirPath, filename))); dirWatchers.forEach(wtc =>
wtc.emit('change', eventType, path.relative(dirPath, filename)),
);
}; };
function getToNode(filepath) { function getToNode(filepath) {

View File

@ -5,7 +5,10 @@
* This source code is licensed under the BSD-style license found in the * 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 * 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. * of patent rights can be found in the PATENTS file in the same directory.
*
* @format
*/ */
'use strict'; 'use strict';
module.exports = require('./fs'); module.exports = require('./fs');

View File

@ -5,7 +5,10 @@
* This source code is licensed under the BSD-style license found in the * 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 * 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. * of patent rights can be found in the PATENTS file in the same directory.
*
* @format
*/ */
'use strict'; 'use strict';
const AssetModule = require('../AssetModule'); const AssetModule = require('../AssetModule');
@ -14,13 +17,15 @@ describe('AssetModule:', () => {
const defaults = {file: '/arbitrary.png'}; const defaults = {file: '/arbitrary.png'};
it('has no dependencies by default', () => { it('has no dependencies by default', () => {
return new AssetModule(defaults).getDependencies() return new AssetModule(defaults)
.getDependencies()
.then(deps => expect(deps).toEqual([])); .then(deps => expect(deps).toEqual([]));
}); });
it('can be parametrized with dependencies', () => { it('can be parametrized with dependencies', () => {
const dependencies = ['arbitrary', 'dependencies']; const dependencies = ['arbitrary', 'dependencies'];
return new AssetModule({...defaults, dependencies}).getDependencies() return new AssetModule({...defaults, dependencies})
.getDependencies()
.then(deps => expect(deps).toEqual(dependencies)); .then(deps => expect(deps).toEqual(dependencies));
}); });
}); });

View File

@ -8,6 +8,7 @@
* *
* @format * @format
*/ */
'use strict'; 'use strict';
jest.useRealTimers(); jest.useRealTimers();

View File

@ -5,10 +5,14 @@
* This source code is licensed under the BSD-style license found in the * 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 * 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. * of patent rights can be found in the PATENTS file in the same directory.
*
* @format
*/ */
'use strict'; 'use strict';
jest.mock('fs') jest
.mock('fs')
.mock('graceful-fs') .mock('graceful-fs')
.mock('../ModuleCache') .mock('../ModuleCache')
.mock('../DependencyGraph/DependencyGraphHelpers') .mock('../DependencyGraph/DependencyGraphHelpers')
@ -20,12 +24,11 @@ const DependencyGraphHelpers = require('../DependencyGraph/DependencyGraphHelper
const TransformCaching = require('../../lib/TransformCaching'); const TransformCaching = require('../../lib/TransformCaching');
const fs = require('fs'); const fs = require('fs');
const packageJson = const packageJson = JSON.stringify({
JSON.stringify({ name: 'arbitrary',
name: 'arbitrary', version: '1.0.0',
version: '1.0.0', description: "A require('foo') story",
description: "A require('foo') story", });
});
function mockFS(rootChildren) { function mockFS(rootChildren) {
fs.__setMockFilesystem({root: rootChildren}); fs.__setMockFilesystem({root: rootChildren});
@ -46,9 +49,9 @@ describe('Module', () => {
const transformCache = TransformCaching.mocked(); const transformCache = TransformCaching.mocked();
const createCache = () => ({ const createCache = () => ({
get: jest.genMockFn().mockImplementation( get: jest
(filepath, field, cb) => cb(filepath) .genMockFn()
), .mockImplementation((filepath, field, cb) => cb(filepath)),
invalidate: jest.genMockFn(), invalidate: jest.genMockFn(),
end: jest.genMockFn(), end: jest.genMockFn(),
}); });
@ -62,14 +65,14 @@ describe('Module', () => {
}, },
...options, ...options,
cache, cache,
file: options && options.file || fileName, file: (options && options.file) || fileName,
depGraphHelpers: new DependencyGraphHelpers(), depGraphHelpers: new DependencyGraphHelpers(),
moduleCache: new ModuleCache({cache}), moduleCache: new ModuleCache({cache}),
getTransformCacheKey: () => transformCacheKey, getTransformCacheKey: () => transformCacheKey,
}); });
const createJSONModule = const createJSONModule = options =>
options => createModule({...options, file: '/root/package.json'}); createModule({...options, file: '/root/package.json'});
beforeEach(function() { beforeEach(function() {
process.platform = 'linux'; process.platform = 'linux';
@ -80,8 +83,7 @@ describe('Module', () => {
describe('Module ID', () => { describe('Module ID', () => {
const moduleId = 'arbitraryModule'; const moduleId = 'arbitraryModule';
const source = const source = `/**
`/**
* @providesModule ${moduleId} * @providesModule ${moduleId}
*/ */
`; `;
@ -97,23 +99,24 @@ describe('Module', () => {
}); });
it('extracts the module name from the header', () => it('extracts the module name from the header', () =>
module.getName().then(name => expect(name).toEqual(moduleId)) module.getName().then(name => expect(name).toEqual(moduleId)));
);
it('identifies the module as haste module', () => it('identifies the module as haste module', () =>
expect(module.isHaste()).toBe(true) expect(module.isHaste()).toBe(true));
);
it('does not transform the file in order to access the name', () => { it('does not transform the file in order to access the name', () => {
const transformCode = const transformCode = jest
jest.genMockFn().mockReturnValue(Promise.resolve()); .genMockFn()
return createModule({transformCode}).getName() .mockReturnValue(Promise.resolve());
return createModule({transformCode})
.getName()
.then(() => expect(transformCode).not.toBeCalled()); .then(() => expect(transformCode).not.toBeCalled());
}); });
it('does not transform the file in order to access the haste status', () => { it('does not transform the file in order to access the haste status', () => {
const transformCode = const transformCode = jest
jest.genMockFn().mockReturnValue(Promise.resolve()); .genMockFn()
.mockReturnValue(Promise.resolve());
createModule({transformCode}).isHaste(); createModule({transformCode}).isHaste();
expect(transformCode).not.toBeCalled(); expect(transformCode).not.toBeCalled();
}); });
@ -125,23 +128,24 @@ describe('Module', () => {
}); });
it('uses the file name as module name', () => it('uses the file name as module name', () =>
module.getName().then(name => expect(name).toEqual(fileName)) module.getName().then(name => expect(name).toEqual(fileName)));
);
it('does not identify the module as haste module', () => it('does not identify the module as haste module', () =>
expect(module.isHaste()).toBe(false) expect(module.isHaste()).toBe(false));
);
it('does not transform the file in order to access the name', () => { it('does not transform the file in order to access the name', () => {
const transformCode = const transformCode = jest
jest.genMockFn().mockReturnValue(Promise.resolve()); .genMockFn()
return createModule({transformCode}).getName() .mockReturnValue(Promise.resolve());
return createModule({transformCode})
.getName()
.then(() => expect(transformCode).not.toBeCalled()); .then(() => expect(transformCode).not.toBeCalled());
}); });
it('does not transform the file in order to access the haste status', () => { it('does not transform the file in order to access the haste status', () => {
const transformCode = const transformCode = jest
jest.genMockFn().mockReturnValue(Promise.resolve()); .genMockFn()
.mockReturnValue(Promise.resolve());
createModule({transformCode}).isHaste(); createModule({transformCode}).isHaste();
expect(transformCode).not.toBeCalled(); expect(transformCode).not.toBeCalled();
}); });
@ -155,14 +159,10 @@ describe('Module', () => {
}); });
it('exposes file contents as `code` property on the data exposed by `read()`', () => it('exposes file contents as `code` property on the data exposed by `read()`', () =>
createModule().read().then(({code}) => createModule().read().then(({code}) => expect(code).toBe(fileContents)));
expect(code).toBe(fileContents))
);
it('exposes file contents via the `getCode()` method', () => it('exposes file contents via the `getCode()` method', () =>
createModule().getCode().then(code => createModule().getCode().then(code => expect(code).toBe(fileContents)));
expect(code).toBe(fileContents))
);
}); });
describe('Custom Code Transform', () => { describe('Custom Code Transform', () => {
@ -176,7 +176,8 @@ describe('Module', () => {
beforeEach(function() { beforeEach(function() {
transformResult = {code: ''}; transformResult = {code: ''};
transformCode = jest.genMockFn() transformCode = jest
.genMockFn()
.mockImplementation((module, sourceCode, options) => { .mockImplementation((module, sourceCode, options) => {
transformCache.writeSync({ transformCache.writeSync({
filePath: module.path, filePath: module.path,
@ -192,18 +193,18 @@ describe('Module', () => {
it('passes the module and file contents to the transform function when reading', () => { it('passes the module and file contents to the transform function when reading', () => {
const module = createModule({transformCode}); const module = createModule({transformCode});
return module.read() return module.read().then(() => {
.then(() => { expect(transformCode).toBeCalledWith(module, fileContents, undefined);
expect(transformCode).toBeCalledWith(module, fileContents, undefined); });
});
}); });
it('passes any additional options to the transform function when reading', () => { it('passes any additional options to the transform function when reading', () => {
const module = createModule({transformCode}); const module = createModule({transformCode});
const transformOptions = {arbitrary: Object()}; const transformOptions = {arbitrary: Object()};
return module.read(transformOptions) return module
.read(transformOptions)
.then(() => .then(() =>
expect(transformCode.mock.calls[0][2]).toBe(transformOptions) expect(transformCode.mock.calls[0][2]).toBe(transformOptions),
); );
}); });
@ -255,85 +256,79 @@ describe('Module', () => {
it('exposes the transformed code rather than the raw file contents', () => { it('exposes the transformed code rather than the raw file contents', () => {
transformResult = {code: exampleCode}; transformResult = {code: exampleCode};
const module = createModule({transformCode}); const module = createModule({transformCode});
return Promise.all([module.read(), module.getCode()]) return Promise.all([
.then(([data, code]) => { module.read(),
expect(data.code).toBe(exampleCode); module.getCode(),
expect(code).toBe(exampleCode); ]).then(([data, code]) => {
}); expect(data.code).toBe(exampleCode);
expect(code).toBe(exampleCode);
});
}); });
it('exposes the raw file contents as `source` property', () => { it('exposes the raw file contents as `source` property', () => {
const module = createModule({transformCode}); const module = createModule({transformCode});
return module.read() return module.read().then(data => expect(data.source).toBe(fileContents));
.then(data => expect(data.source).toBe(fileContents));
}); });
it('exposes a source map returned by the transform', () => { it('exposes a source map returned by the transform', () => {
const map = {version: 3}; const map = {version: 3};
transformResult = {map, code: exampleCode}; transformResult = {map, code: exampleCode};
const module = createModule({transformCode}); const module = createModule({transformCode});
return Promise.all([module.read(), module.getMap()]) return Promise.all([
.then(([data, sourceMap]) => { module.read(),
expect(data.map).toBe(map); module.getMap(),
expect(sourceMap).toBe(map); ]).then(([data, sourceMap]) => {
}); expect(data.map).toBe(map);
expect(sourceMap).toBe(map);
});
}); });
it('caches the transform result for the same transform options', () => { it('caches the transform result for the same transform options', () => {
let module = createModule({transformCode}); let module = createModule({transformCode});
return module.read() return module.read().then(() => {
.then(() => { expect(transformCode).toHaveBeenCalledTimes(1);
// We want to check transform caching rather than shallow caching of
// Promises returned by read().
module = createModule({transformCode});
return module.read().then(() => {
expect(transformCode).toHaveBeenCalledTimes(1); expect(transformCode).toHaveBeenCalledTimes(1);
// We want to check transform caching rather than shallow caching of
// Promises returned by read().
module = createModule({transformCode});
return module.read()
.then(() => {
expect(transformCode).toHaveBeenCalledTimes(1);
});
}); });
});
}); });
it('triggers a new transform for different transform options', () => { it('triggers a new transform for different transform options', () => {
const module = createModule({transformCode}); const module = createModule({transformCode});
return module.read({foo: 1}) return module.read({foo: 1}).then(() => {
.then(() => { expect(transformCode).toHaveBeenCalledTimes(1);
expect(transformCode).toHaveBeenCalledTimes(1); return module.read({foo: 2}).then(() => {
return module.read({foo: 2}) expect(transformCode).toHaveBeenCalledTimes(2);
.then(() => {
expect(transformCode).toHaveBeenCalledTimes(2);
});
}); });
});
}); });
it('triggers a new transform for different source code', () => { it('triggers a new transform for different source code', () => {
let module = createModule({transformCode}); let module = createModule({transformCode});
return module.read() return module.read().then(() => {
.then(() => { expect(transformCode).toHaveBeenCalledTimes(1);
expect(transformCode).toHaveBeenCalledTimes(1); cache = createCache();
cache = createCache(); mockIndexFile('test');
mockIndexFile('test'); module = createModule({transformCode});
module = createModule({transformCode}); return module.read().then(() => {
return module.read() expect(transformCode).toHaveBeenCalledTimes(2);
.then(() => {
expect(transformCode).toHaveBeenCalledTimes(2);
});
}); });
});
}); });
it('triggers a new transform for different transform cache key', () => { it('triggers a new transform for different transform cache key', () => {
let module = createModule({transformCode}); let module = createModule({transformCode});
return module.read() return module.read().then(() => {
.then(() => { expect(transformCode).toHaveBeenCalledTimes(1);
expect(transformCode).toHaveBeenCalledTimes(1); transformCacheKey = 'other';
transformCacheKey = 'other'; module = createModule({transformCode});
module = createModule({transformCode}); return module.read().then(() => {
return module.read() expect(transformCode).toHaveBeenCalledTimes(2);
.then(() => {
expect(transformCode).toHaveBeenCalledTimes(2);
});
}); });
});
}); });
}); });
}); });

View File

@ -1,4 +1,4 @@
/** /**
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved. * All rights reserved.
* *
@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
* *
* @flow * @flow
* @format
*/ */
'use strict'; 'use strict';
@ -19,7 +20,7 @@ module.exports = class AsyncTaskGroup<TTaskHandle> {
constructor() { constructor() {
this._runningTasks = new Set(); this._runningTasks = new Set();
this._resolve = null; this._resolve = null;
this.done = new Promise(resolve => this._resolve = resolve); this.done = new Promise(resolve => (this._resolve = resolve));
} }
start(taskHandle: TTaskHandle) { start(taskHandle: TTaskHandle) {

View File

@ -5,7 +5,10 @@
* This source code is licensed under the BSD-style license found in the * 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 * 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. * of patent rights can be found in the PATENTS file in the same directory.
*
* @format
*/ */
'use strict'; 'use strict';
var AssetPaths = require('../AssetPaths'); var AssetPaths = require('../AssetPaths');
@ -72,7 +75,7 @@ describe('AssetPaths', () => {
}); });
describe('resolution extraction', () => { describe('resolution extraction', () => {
it('should extract resolution simple case', () => { it('should extract resolution simple case', () => {
var data = AssetPaths.parse('test@2x.png', TEST_PLATFORMS); var data = AssetPaths.parse('test@2x.png', TEST_PLATFORMS);
expect(data).toEqual({ expect(data).toEqual({
assetName: 'test.png', assetName: 'test.png',
@ -83,7 +86,7 @@ describe('AssetPaths', () => {
}); });
}); });
it('should default resolution to 1', () => { it('should default resolution to 1', () => {
var data = AssetPaths.parse('test.png', TEST_PLATFORMS); var data = AssetPaths.parse('test.png', TEST_PLATFORMS);
expect(data).toEqual({ expect(data).toEqual({
assetName: 'test.png', assetName: 'test.png',
@ -94,7 +97,7 @@ describe('AssetPaths', () => {
}); });
}); });
it('should support float', () => { it('should support float', () => {
var data = AssetPaths.parse('test@1.1x.png', TEST_PLATFORMS); var data = AssetPaths.parse('test@1.1x.png', TEST_PLATFORMS);
expect(data).toEqual({ expect(data).toEqual({
assetName: 'test.png', assetName: 'test.png',

View File

@ -5,7 +5,10 @@
* This source code is licensed under the BSD-style license found in the * 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 * 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. * of patent rights can be found in the PATENTS file in the same directory.
*
* @format
*/ */
'use strict'; 'use strict';
var parsePlatformFilePath = require('../parsePlatformFilePath'); var parsePlatformFilePath = require('../parsePlatformFilePath');
@ -23,9 +26,17 @@ describe('parsePlatformFilePath', function() {
expect(get('/b/c/a@1.5x.ios.png')).toBe('ios'); expect(get('/b/c/a@1.5x.ios.png')).toBe('ios');
expect(get('/b/c/a@1.5x.lol.png')).toBe(null); expect(get('/b/c/a@1.5x.lol.png')).toBe(null);
expect(get('/b/c/a.lol.png')).toBe(null); expect(get('/b/c/a.lol.png')).toBe(null);
expect(parsePlatformFilePath('a.ios.js', new Set(['ios'])).platform).toBe('ios'); expect(parsePlatformFilePath('a.ios.js', new Set(['ios'])).platform).toBe(
expect(parsePlatformFilePath('a.android.js', new Set(['android'])).platform).toBe('android'); 'ios',
expect(parsePlatformFilePath('a.ios.js', new Set(['ubuntu'])).platform).toBe(null); );
expect(parsePlatformFilePath('a.ubuntu.js', new Set(['ubuntu'])).platform).toBe('ubuntu'); expect(
parsePlatformFilePath('a.android.js', new Set(['android'])).platform,
).toBe('android');
expect(
parsePlatformFilePath('a.ios.js', new Set(['ubuntu'])).platform,
).toBe(null);
expect(
parsePlatformFilePath('a.ubuntu.js', new Set(['ubuntu'])).platform,
).toBe('ubuntu');
}); });
}); });

View File

@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
* *
* @flow * @flow
* @format
*/ */
'use strict'; 'use strict';
@ -18,7 +19,10 @@ export type LocalPath = OpaqueLocalPath & string;
// FIXME: This function has the shortcoming of potentially returning identical // FIXME: This function has the shortcoming of potentially returning identical
// paths for two files in different roots. // paths for two files in different roots.
function toLocalPath(roots: $ReadOnlyArray<string>, absolutePath: string): LocalPath { function toLocalPath(
roots: $ReadOnlyArray<string>,
absolutePath: string,
): LocalPath {
for (let i = 0; i < roots.length; i++) { for (let i = 0; i < roots.length; i++) {
const localPath = relative(roots[i], absolutePath); const localPath = relative(roots[i], absolutePath);
if (localPath[0] !== '.') { if (localPath[0] !== '.') {
@ -27,7 +31,7 @@ function toLocalPath(roots: $ReadOnlyArray<string>, absolutePath: string): Local
} }
throw new Error( throw new Error(
'Expected root module to be relative to one of the project roots' 'Expected root module to be relative to one of the project roots',
); );
} }