-
Notifications
You must be signed in to change notification settings - Fork 24.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Summary: Adds utilities needed for bundle creation: `completeModuleWrapper` appends numeric IDs for the module itself and its dependencies to a module wrapped. `createGetModuleId` returns a function that returns sequential numeric IDs for strings, and is idempotent. Reviewed By: cpojer Differential Revision: D4240334 fbshipit-source-id: c165482ebcf0e81ebb83ba6ff634de095ffb6bf0
- Loading branch information
1 parent
da079f7
commit eda09f8
Showing
2 changed files
with
135 additions
and
0 deletions.
There are no files selected for viewing
83 changes: 83 additions & 0 deletions
83
packager/react-packager/src/ModuleGraph/output/__tests__/util-test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/** | ||
* Copyright (c) 2016-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. | ||
*/ | ||
'use strict'; | ||
|
||
jest.disableAutomock(); | ||
|
||
const {match} = require('sinon'); | ||
const {fn} = require('../../test-helpers'); | ||
const { | ||
addModuleIdsToModuleWrapper, | ||
createIdForPathFn, | ||
} = require('../util'); | ||
|
||
const {any} = jasmine; | ||
|
||
describe('`addModuleIdsToModuleWrapper`:', () => { | ||
const path = 'path/to/file'; | ||
const createModule = (dependencies = []) => ({ | ||
dependencies, | ||
file: {code: '__d(function(){});', isModule: true, path}, | ||
}); | ||
|
||
it('completes the module wrapped with module ID, and an array of dependency IDs', () => { | ||
const dependencies = [ | ||
{id: 'a', path: 'path/to/a.js'}, | ||
{id: 'b', path: 'location/of/b.js'}, | ||
]; | ||
const module = createModule(dependencies); | ||
|
||
const idForPath = fn(); | ||
idForPath.stub | ||
.withArgs(match({path})).returns(12) | ||
.withArgs(match({path: dependencies[0].path})).returns(345) | ||
.withArgs(match({path: dependencies[1].path})).returns(6); | ||
|
||
expect(addModuleIdsToModuleWrapper(module, idForPath)) | ||
.toEqual('__d(function(){}, 12, [345, 6]);'); | ||
}); | ||
|
||
it('omits the array of dependency IDs if it is empty', () => { | ||
const module = createModule(); | ||
expect(addModuleIdsToModuleWrapper(module, () => 98)) | ||
.toEqual(`__d(function(){}, ${98});`); | ||
}); | ||
}); | ||
|
||
describe('`createIdForPathFn`', () => { | ||
let idForPath; | ||
beforeEach(() => { | ||
idForPath = createIdForPathFn(); | ||
}); | ||
|
||
it('returns a number for a string', () => { | ||
expect(idForPath({path: 'arbitrary'})).toEqual(any(Number)); | ||
}); | ||
|
||
it('returns consecutive numbers', () => { | ||
const strings = [ | ||
'arbitrary string', | ||
'looking/like/a/path', | ||
'/absolute/path/to/file.js', | ||
'/more files/are here', | ||
]; | ||
|
||
strings.forEach((string, i) => { | ||
expect(idForPath({path: string})).toEqual(i); | ||
}); | ||
}); | ||
|
||
it('returns the same id if the same string is passed in again', () => { | ||
const path = 'this/is/an/arbitrary/path.js'; | ||
const id = idForPath({path}); | ||
idForPath({path: '/other/file'}); | ||
idForPath({path: 'and/another/file'}); | ||
expect(idForPath({path})).toEqual(id); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/** | ||
* Copyright (c) 2016-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 | ||
*/ | ||
'use strict'; | ||
|
||
import type {Module} from '../types.flow'; | ||
|
||
// Transformed modules have the form | ||
// __d(function(require, module, global, exports, dependencyMap) { | ||
// /* code */ | ||
// }); | ||
// | ||
// This function adds the numeric module ID, and an array with dependencies of | ||
// the dependencies of the module before the closing parenthesis. | ||
exports.addModuleIdsToModuleWrapper = ( | ||
module: Module, | ||
idForPath: {path: string} => number, | ||
): string => { | ||
const {dependencies, file} = module; | ||
const {code} = file; | ||
const index = code.lastIndexOf(')'); | ||
const depencyIds = | ||
dependencies.length ? `, [${dependencies.map(idForPath).join(', ')}]` : ''; | ||
return ( | ||
code.slice(0, index) + | ||
`, ${idForPath(file)}` + | ||
depencyIds + | ||
code.slice(index) | ||
); | ||
}; | ||
|
||
// Creates an idempotent function that returns numeric IDs for objects based | ||
// on their `path` property. | ||
exports.createIdForPathFn = (): ({path: string} => number) => { | ||
const seen = new Map(); | ||
let next = 0; | ||
return ({path}) => { | ||
let id = seen.get(path); | ||
if (id == null) { | ||
id = next++; | ||
seen.set(path, id); | ||
} | ||
return id; | ||
}; | ||
}; |