Skip to content

Commit

Permalink
[jest-util] optimize proxy env 🐎 (#8355)
Browse files Browse the repository at this point in the history
  • Loading branch information
Connormiha authored and SimenB committed Apr 22, 2019
1 parent cd11240 commit 53da908
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 29 deletions.
12 changes: 11 additions & 1 deletion packages/jest-util/src/__tests__/createProcessObject.test.ts
Expand Up @@ -6,9 +6,17 @@
*/

import EventEmitter from 'events';
import createProcessObject from '../createProcessObject';

let createProcessObject;

function requireCreateProcessObject() {
jest.isolateModules(() => {
createProcessObject = require('../createProcessObject').default;
});
}

it('creates a process object that looks like the original one', () => {
requireCreateProcessObject();
const fakeProcess = createProcessObject();

// "process" inherits from EventEmitter through the prototype chain.
Expand All @@ -35,6 +43,7 @@ it('fakes require("process") so it is equal to "global.process"', () => {

it('checks that process.env works as expected on Linux platforms', () => {
Object.defineProperty(process, 'platform', {get: () => 'linux'});
requireCreateProcessObject();

// Existing properties inside process.env are copied to the fake environment.
process.env.PROP_STRING = 'foo';
Expand Down Expand Up @@ -73,6 +82,7 @@ it('checks that process.env works as expected on Linux platforms', () => {

it('checks that process.env works as expected in Windows platforms', () => {
Object.defineProperty(process, 'platform', {get: () => 'win32'});
requireCreateProcessObject();

// Windows is not case sensitive when it comes to property names.
process.env.PROP_STRING = 'foo';
Expand Down
67 changes: 39 additions & 28 deletions packages/jest-util/src/createProcessObject.ts
Expand Up @@ -8,49 +8,60 @@
import deepCyclicCopy from './deepCyclicCopy';

const BLACKLIST = new Set(['env', 'mainModule', '_events']);
const isWin32 = process.platform === 'win32';
const proto: Record<string, any> = Object.getPrototypeOf(process.env);

// The "process.env" object has a bunch of particularities: first, it does not
// directly extend from Object; second, it converts any assigned value to a
// string; and third, it is case-insensitive in Windows. We use a proxy here to
// mimic it (see https://nodejs.org/api/process.html#process_process_env).

function createProcessEnv(): NodeJS.ProcessEnv {
if (typeof Proxy === 'undefined') {
return deepCyclicCopy(process.env);
}

const proto: Record<string, any> = Object.getPrototypeOf(process.env);
const real = Object.create(proto);
const lookup: typeof process.env = {};

const proxy = new Proxy(real, {
deleteProperty(_target, key) {
for (const name in real) {
if (real.hasOwnProperty(name)) {
if (typeof key === 'string' && process.platform === 'win32') {
if (name.toLowerCase() === key.toLowerCase()) {
delete real[name];
delete lookup[name.toLowerCase()];
}
} else {
if (key === name) {
delete real[name];
delete lookup[name];
}
function deletePropertyWin32(_target: any, key: any) {
for (const name in real) {
if (real.hasOwnProperty(name)) {
if (typeof key === 'string') {
if (name.toLowerCase() === key.toLowerCase()) {
delete real[name];
delete lookup[name.toLowerCase()];
}
} else {
if (key === name) {
delete real[name];
delete lookup[name];
}
}
}
}

return true;
},
return true;
}

get(_target, key) {
if (typeof key === 'string' && process.platform === 'win32') {
return lookup[key in proto ? key : key.toLowerCase()];
} else {
return real[key];
}
},
function deleteProperty(_target: any, key: any) {
delete real[key];
delete lookup[key];

return true;
}

function getProperty(_target: any, key: any) {
return real[key];
}

function getPropertyWin32(_target: any, key: any) {
if (typeof key === 'string') {
return lookup[key in proto ? key : key.toLowerCase()];
} else {
return real[key];
}
}

const proxy = new Proxy(real, {
deleteProperty: isWin32 ? deletePropertyWin32 : deleteProperty,
get: isWin32 ? getPropertyWin32 : getProperty,

set(_target, key, value) {
const strValue = '' + value;
Expand Down

0 comments on commit 53da908

Please sign in to comment.