Skip to content

Commit

Permalink
HasteFS file size (jestjs#7580)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeysal authored and captain-yossarian committed Jul 18, 2019
1 parent 55283bb commit bd982bb
Show file tree
Hide file tree
Showing 13 changed files with 189 additions and 63 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
- `[jest-haste-map]` [**BREAKING**] Remove name from hash in `HasteMap.getCacheFilePath` ([#7218](https://github.com/facebook/jest/pull/7218))
- `[babel-preset-jest]` [**BREAKING**] Export a function instead of an object for Babel 7 compatibility ([#7203](https://github.com/facebook/jest/pull/7203))
- `[jest-haste-map]` [**BREAKING**] Expose relative paths when getting the file iterator ([#7321](https://github.com/facebook/jest/pull/7321))
- `[jest-cli]` Print version ending in `-dev` when running a local Jest clone
- `[jest-haste-map]` Add `hasteFS.getSize(path)` ([#7580](https://github.com/facebook/jest/pull/7580))
- `[jest-cli]` Print version ending in `-dev` when running a local Jest clone ([#7582](https://github.com/facebook/jest/pull/7582))
- `[jest-cli]` Add Support for `globalSetup` and `globalTeardown` in projects ([#6865](https://github.com/facebook/jest/pull/6865))
- `[jest-runtime]` Add `extraGlobals` to config to load extra global variables into the execution vm ([#7454](https://github.com/facebook/jest/pull/7454))
- `[jest-util]` Export `specialChars` containing Unicode characters and ANSI escapes for console output ([#7532](https://github.com/facebook/jest/pull/7532))
Expand Down
60 changes: 60 additions & 0 deletions e2e/__tests__/haste_map_size.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Copyright (c) 2018-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

'use strict';

import os from 'os';
import path from 'path';
import HasteMap from 'jest-haste-map';
import {cleanup, writeFiles} from '../Utils';

const DIR = path.resolve(os.tmpdir(), 'haste_map_size');

beforeEach(() => {
cleanup(DIR);
writeFiles(DIR, {
'file.js': '"abc"',
});
});
afterEach(() => cleanup(DIR));

const options = {
extensions: ['js'],
forceNodeFilesystemAPI: true,
ignorePattern: / ^/,
maxWorkers: 2,
mocksPattern: '',
name: 'tmp',
platforms: [],
retainAllFiles: true,
rootDir: DIR,
roots: [DIR],
useWatchman: false,
watch: false,
};

test('reports the correct file size', async () => {
const hasteMap = new HasteMap(options);
const hasteFS = (await hasteMap.build()).hasteFS;
expect(hasteFS.getSize(path.join(DIR, 'file.js'))).toBe(5);
});

test('updates the file size when a file changes', async () => {
const hasteMap = new HasteMap({...options, watch: true});
await hasteMap.build();

writeFiles(DIR, {
'file.js': '"asdf"',
});
const {hasteFS} = await new Promise(resolve =>
hasteMap.once('change', resolve),
);
hasteMap.end();
expect(hasteFS.getSize(path.join(DIR, 'file.js'))).toBe(6);
});
4 changes: 2 additions & 2 deletions packages/jest-cli/src/TestSequencer.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ export default class TestSequencer {
// fastest results.
sort(tests: Array<Test>): Array<Test> {
const stats = {};
const fileSize = test =>
stats[test.path] || (stats[test.path] = fs.statSync(test.path).size);
const fileSize = ({path, context: {hasteFS}}) =>
stats[path] || (stats[path] = hasteFS.getSize(path) || 0);
const hasFailed = (cache, test) =>
cache[test.path] && cache[test.path][0] === FAIL;
const time = (cache, test) => cache[test.path] && cache[test.path][1];
Expand Down
7 changes: 6 additions & 1 deletion packages/jest-cli/src/__tests__/test_sequencer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ const context = {
cacheDirectory: '/cache',
name: 'test',
},
hasteFS: {
getSize: path => path.length,
},
};

const secondContext = {
Expand All @@ -31,6 +34,9 @@ const secondContext = {
cacheDirectory: '/cache2',
name: 'test2',
},
hasteFS: {
getSize: path => path.length,
},
};

const toTests = paths =>
Expand All @@ -45,7 +51,6 @@ beforeEach(() => {

fs.readFileSync = jest.fn(() => '{}');
fs.existsSync = () => true;
fs.statSync = jest.fn(filePath => ({size: filePath.length}));
fs.writeFileSync = jest.fn();
});

Expand Down
5 changes: 5 additions & 0 deletions packages/jest-haste-map/src/HasteFS.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ export default class HasteFS {
return (fileMetadata && fileMetadata[H.ID]) || null;
}

getSize(file: Path): ?number {
const fileMetadata = this._getFileData(file);
return (fileMetadata && fileMetadata[H.SIZE]) || null;
}

getDependencies(file: Path): ?Array<string> {
const fileMetadata = this._getFileData(file);
return (fileMetadata && fileMetadata[H.DEPENDENCIES]) || null;
Expand Down
62 changes: 44 additions & 18 deletions packages/jest-haste-map/src/__tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jest.mock('../crawlers/watchman', () =>
if (list[file]) {
const hash = computeSha1 ? mockHashContents(list[file]) : null;

data.files.set(relativeFilePath, ['', 32, 0, [], hash]);
data.files.set(relativeFilePath, ['', 32, 42, 0, [], hash]);
} else {
data.files.delete(relativeFilePath);
}
Expand Down Expand Up @@ -337,26 +337,28 @@ describe('HasteMap', () => {

expect(data.files).toEqual(
createMap({
'fruits/Banana.js': ['Banana', 32, 1, ['Strawberry'], null],
'fruits/Pear.js': ['Pear', 32, 1, ['Banana', 'Strawberry'], null],
'fruits/Strawberry.js': ['Strawberry', 32, 1, [], null],
'fruits/__mocks__/Pear.js': ['', 32, 1, ['Melon'], null],
'fruits/Banana.js': ['Banana', 32, 42, 1, ['Strawberry'], null],
'fruits/Pear.js': ['Pear', 32, 42, 1, ['Banana', 'Strawberry'], null],
'fruits/Strawberry.js': ['Strawberry', 32, 42, 1, [], null],
'fruits/__mocks__/Pear.js': ['', 32, 42, 1, ['Melon'], null],
// node modules
'fruits/node_modules/fbjs/lib/flatMap.js': [
'flatMap',
32,
42,
1,
[],
null,
],
'fruits/node_modules/react/React.js': [
'React',
32,
42,
1,
['Component'],
null,
],
'vegetables/Melon.js': ['Melon', 32, 1, [], null],
'vegetables/Melon.js': ['Melon', 32, 42, 1, [], null],
}),
);

Expand Down Expand Up @@ -405,11 +407,18 @@ describe('HasteMap', () => {

// The node crawler returns "null" for the SHA-1.
data.files = createMap({
'fruits/Banana.js': ['Banana', 32, 0, ['Strawberry'], null],
'fruits/Pear.js': ['Pear', 32, 0, ['Banana', 'Strawberry'], null],
'fruits/Strawberry.js': ['Strawberry', 32, 0, [], null],
'fruits/__mocks__/Pear.js': ['', 32, 0, ['Melon'], null],
'vegetables/Melon.js': ['Melon', 32, 0, [], null],
'fruits/Banana.js': ['Banana', 32, 42, 0, ['Strawberry'], null],
'fruits/Pear.js': [
'Pear',
32,
42,
0,
['Banana', 'Strawberry'],
null,
],
'fruits/Strawberry.js': ['Strawberry', 32, 42, 0, [], null],
'fruits/__mocks__/Pear.js': ['', 32, 42, 0, ['Melon'], null],
'vegetables/Melon.js': ['Melon', 32, 42, 0, [], null],
});

return Promise.resolve(data);
Expand All @@ -430,34 +439,39 @@ describe('HasteMap', () => {
'fruits/Banana.js': [
'Banana',
32,
42,
1,
['Strawberry'],
'7772b628e422e8cf59c526be4bb9f44c0898e3d1',
],
'fruits/Pear.js': [
'Pear',
32,
42,
1,
['Banana', 'Strawberry'],
'89d0c2cc11dcc5e1df50b8af04ab1b597acfba2f',
],
'fruits/Strawberry.js': [
'Strawberry',
32,
42,
1,
[],
'e8aa38e232b3795f062f1d777731d9240c0f8c25',
],
'fruits/__mocks__/Pear.js': [
'',
32,
42,
1,
['Melon'],
'8d40afbb6e2dc78e1ba383b6d02cafad35cceef2',
],
'vegetables/Melon.js': [
'Melon',
32,
42,
1,
[],
'f16ccf6f2334ceff2ddb47628a2c5f2d748198ca',
Expand Down Expand Up @@ -507,6 +521,7 @@ describe('HasteMap', () => {
expect(data.files.get('fruits/node_modules/fbjs/fbjs.js')).toEqual([
'',
32,
42,
0,
[],
null,
Expand Down Expand Up @@ -604,18 +619,20 @@ describe('HasteMap', () => {
'fruits/Strawberry.android.js': [
'Strawberry',
32,
42,
1,
['Blackberry'],
null,
],
'fruits/Strawberry.ios.js': [
'Strawberry',
32,
42,
1,
['Raspberry'],
null,
],
'fruits/Strawberry.js': ['Strawberry', 32, 1, ['Banana'], null],
'fruits/Strawberry.js': ['Strawberry', 32, 42, 1, ['Banana'], null],
}),
);

Expand Down Expand Up @@ -702,7 +719,14 @@ describe('HasteMap', () => {
expect(useBuitinsInContext(data.clocks)).toEqual(mockClocks);

const files = new Map(initialData.files);
files.set('fruits/Banana.js', ['Banana', 32, 1, ['Kiwi'], null]);
files.set('fruits/Banana.js', [
'Banana',
32,
42,
1,
['Kiwi'],
null,
]);

expect(useBuitinsInContext(data.files)).toEqual(files);

Expand Down Expand Up @@ -962,7 +986,7 @@ describe('HasteMap', () => {
watchman.mockImplementation(options =>
mockImpl(options).then(() => {
const {data} = options;
data.files.set('fruits/invalid/file.js', ['', 34, 0, []]);
data.files.set('fruits/invalid/file.js', ['', 34, 44, 0, []]);
return data;
}),
);
Expand Down Expand Up @@ -1060,7 +1084,7 @@ describe('HasteMap', () => {
node.mockImplementation(options => {
const {data} = options;
data.files = createMap({
'fruits/Banana.js': ['', 32, 0, [], null],
'fruits/Banana.js': ['', 32, 42, 0, [], null],
});
return Promise.resolve(data);
});
Expand All @@ -1073,7 +1097,7 @@ describe('HasteMap', () => {

expect(data.files).toEqual(
createMap({
'fruits/Banana.js': ['Banana', 32, 1, ['Strawberry'], null],
'fruits/Banana.js': ['Banana', 32, 42, 1, ['Strawberry'], null],
}),
);

Expand All @@ -1091,7 +1115,7 @@ describe('HasteMap', () => {
node.mockImplementation(options => {
const {data} = options;
data.files = createMap({
'fruits/Banana.js': ['', 32, 0, [], null],
'fruits/Banana.js': ['', 32, 42, 0, [], null],
});
return Promise.resolve(data);
});
Expand All @@ -1104,7 +1128,7 @@ describe('HasteMap', () => {

expect(data.files).toEqual(
createMap({
'fruits/Banana.js': ['Banana', 32, 1, ['Strawberry'], null],
'fruits/Banana.js': ['Banana', 32, 42, 1, ['Strawberry'], null],
}),
);
});
Expand Down Expand Up @@ -1184,11 +1208,13 @@ describe('HasteMap', () => {
const MOCK_STAT_FILE = {
isDirectory: () => false,
mtime: {getTime: () => 45},
size: 55,
};

const MOCK_STAT_FOLDER = {
isDirectory: () => true,
mtime: {getTime: () => 45},
size: 55,
};

hm_it('handles several change events at once', async hm => {
Expand Down
7 changes: 4 additions & 3 deletions packages/jest-haste-map/src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ export default {
/* file map attributes */
ID: 0,
MTIME: 1,
VISITED: 2,
DEPENDENCIES: 3,
SHA1: 4,
SIZE: 2,
VISITED: 3,
DEPENDENCIES: 4,
SHA1: 5,

/* module map attributes */
PATH: 0,
Expand Down
Loading

0 comments on commit bd982bb

Please sign in to comment.