Skip to content

Commit

Permalink
Use v8.serialize when available (#5565)
Browse files Browse the repository at this point in the history
  • Loading branch information
cpojer authored and mjesun committed Feb 14, 2018
1 parent 10276f9 commit c35b78b
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 42 deletions.
17 changes: 11 additions & 6 deletions packages/jest-haste-map/src/__tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ let mockFs;

jest.mock('graceful-fs', () => ({
readFileSync: jest.fn((path, options) => {
expect(options).toBe('utf8');

// A file change can be triggered by writing into the
// mockChangedFiles object.
if (mockChangedFiles && path in mockChangedFiles) {
Expand All @@ -87,7 +85,7 @@ jest.mock('graceful-fs', () => ({
throw error;
}),
writeFileSync: jest.fn((path, data, options) => {
expect(options).toBe('utf8');
expect(options).toBe(require('v8').serialize ? undefined : 'utf8');
mockFs[path] = data;
}),
}));
Expand Down Expand Up @@ -468,8 +466,11 @@ describe('HasteMap', () => {
.build()
.then(({__hasteMapForTest: data}) => {
expect(fs.readFileSync.mock.calls.length).toBe(1);
expect(fs.readFileSync).toBeCalledWith(cacheFilePath, 'utf8');

if (require('v8').deserialize) {
expect(fs.readFileSync).toBeCalledWith(cacheFilePath);
} else {
expect(fs.readFileSync).toBeCalledWith(cacheFilePath, 'utf8');
}
expect(data.clocks).toEqual(mockClocks);
expect(data.files).toEqual(initialData.files);
expect(data.map).toEqual(initialData.map);
Expand Down Expand Up @@ -504,7 +505,11 @@ describe('HasteMap', () => {
.then(({__hasteMapForTest: data}) => {
expect(fs.readFileSync.mock.calls.length).toBe(2);

expect(fs.readFileSync).toBeCalledWith(cacheFilePath, 'utf8');
if (require('v8').serialize) {
expect(fs.readFileSync).toBeCalledWith(cacheFilePath);
} else {
expect(fs.readFileSync).toBeCalledWith(cacheFilePath, 'utf8');
}
expect(fs.readFileSync).toBeCalledWith('/fruits/banana.js', 'utf8');

expect(data.clocks).toEqual(mockClocks);
Expand Down
93 changes: 57 additions & 36 deletions packages/jest-haste-map/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,30 @@
* @flow
*/

import {execSync} from 'child_process';
import {version as VERSION} from '../package.json';
import {worker} from './worker';
import crypto from 'crypto';
import EventEmitter from 'events';
import fs from 'graceful-fs';
import getMockName from './get_mock_name';
import getPlatformExtension from './lib/get_platform_extension';
// eslint-disable-next-line import/no-duplicates
import H from './constants';
import HasteFS from './haste_fs';
import HasteModuleMap from './module_map';
// eslint-disable-next-line import/default
import nodeCrawl from './crawlers/node';
import normalizePathSep from './lib/normalize_path_sep';
import os from 'os';
import path from 'path';
import sane from 'sane';
import v8 from 'v8';
// eslint-disable-next-line import/default
import watchmanCrawl from './crawlers/watchman';
import WatchmanWatcher from './lib/watchman_watcher';
import Worker from 'jest-worker';

import type {Console} from 'console';
import type {Path} from 'types/Config';
import type {
Expand All @@ -18,34 +42,9 @@ import type {
MockData,
} from 'types/HasteMap';

import {worker} from './worker';

// eslint-disable-next-line import/no-duplicates
import typeof HType from './constants';

import EventEmitter from 'events';
import os from 'os';
import path from 'path';
import crypto from 'crypto';
import {execSync} from 'child_process';
import fs from 'graceful-fs';
import sane from 'sane';
import {version as VERSION} from '../package.json';
// eslint-disable-next-line import/no-duplicates
import H from './constants';
import HasteFS from './haste_fs';
import HasteModuleMap from './module_map';
import getMockName from './get_mock_name';
import getPlatformExtension from './lib/get_platform_extension';
import normalizePathSep from './lib/normalize_path_sep';
import Worker from 'jest-worker';
import WatchmanWatcher from './lib/watchman_watcher';

// eslint-disable-next-line import/default
import nodeCrawl from './crawlers/node';
// eslint-disable-next-line import/default
import watchmanCrawl from './crawlers/watchman';

type Options = {
cacheDirectory?: string,
console?: Console,
Expand Down Expand Up @@ -291,7 +290,21 @@ class HasteMap extends EventEmitter {
* 1. read data from the cache or create an empty structure.
*/
read(): InternalHasteMap {
return this._parse(fs.readFileSync(this._cachePath, 'utf8'));
if (v8.deserialize) {
// This may throw. `_buildFileMap` will catch it and create a new map.
const {version, hasteMap} = v8.deserialize(
fs.readFileSync(this._cachePath),
);
if (version !== process.versions.v8) {
throw new Error('jest-haste-map: v8 versions do not match.');
}
return removePrototypes(hasteMap);
} else {
const hasteMap = (JSON.parse(
fs.readFileSync(this._cachePath, 'utf8'),
): InternalHasteMap);
return removePrototypes(hasteMap);
}
}

readModuleMap(): ModuleMap {
Expand Down Expand Up @@ -520,8 +533,18 @@ class HasteMap extends EventEmitter {
/**
* 4. serialize the new `HasteMap` in a cache file.
*/
_persist(hasteMap: InternalHasteMap): void {
fs.writeFileSync(this._cachePath, JSON.stringify(hasteMap), 'utf8');
_persist(hasteMap: InternalHasteMap) {
if (v8.serialize) {
fs.writeFileSync(
this._cachePath,
v8.serialize({
hasteMap,
version: process.versions.v8,
}),
);
} else {
fs.writeFileSync(this._cachePath, JSON.stringify(hasteMap), 'utf8');
}
}

/**
Expand All @@ -544,14 +567,6 @@ class HasteMap extends EventEmitter {
return this._worker;
}

_parse(hasteMapPath: string): InternalHasteMap {
const hasteMap = (JSON.parse(hasteMapPath): InternalHasteMap);
for (const key in hasteMap) {
Object.setPrototypeOf(hasteMap[key], null);
}
return hasteMap;
}

_crawl(hasteMap: InternalHasteMap): Promise<InternalHasteMap> {
const options = this._options;
const ignore = this._ignore.bind(this);
Expand Down Expand Up @@ -898,6 +913,12 @@ class HasteMap extends EventEmitter {
}

const copy = object => Object.assign(Object.create(null), object);
const removePrototypes = object => {
for (const key in object) {
Object.setPrototypeOf(object[key], null);
}
return object;
};

HasteMap.H = H;
HasteMap.ModuleMap = HasteModuleMap;
Expand Down

0 comments on commit c35b78b

Please sign in to comment.