Skip to content

Commit

Permalink
split out copiers from utils, and use more defined copiers for JIT op…
Browse files Browse the repository at this point in the history
…timizations
  • Loading branch information
planttheidea committed Sep 28, 2022
1 parent b82035e commit c303049
Show file tree
Hide file tree
Showing 5 changed files with 382 additions and 334 deletions.
162 changes: 162 additions & 0 deletions __tests__/copiers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
type PlainObject = {
[key: string]: any;
[index: number]: any;
};

import { createCache } from '../src/utils';

let copiers: typeof import('../src/copiers');

beforeEach(() => {
jest.isolateModules(() => {
copiers = require('../src/copiers');
});
});

describe('copyObjectLoose', () => {
it('will create an object clone when property symbols are not supported', () => {
const original = Object.getOwnPropertySymbols;

jest.isolateModules(() => {
Object.getOwnPropertySymbols = undefined;
copiers = require('../src/copiers');
});

const symbol = Symbol('quz');
const object = {
bar: { baz: 'quz' },
foo: 'bar',
[symbol]: 'blah',
};
const handleCopy = jest.fn().mockImplementation((arg) => arg);
const cache = createCache();

const result = copiers.copyObjectLoose(
object,
Object.getPrototypeOf(object),
handleCopy,
cache
);

Object.getOwnPropertySymbols = original;

expect(result).not.toBe(object);
expect(result).toEqual(
Object.keys(object).reduce((clone: PlainObject, key): PlainObject => {
clone[key] = object[key as keyof typeof object];

return clone;
}, {})
);

expect(handleCopy).toHaveBeenCalledTimes(Object.keys(object).length);
});

it('will create an object clone when property symbols are supported', () => {
const object = {
bar: { baz: 'quz' },
[Symbol('quz')]: 'blah',
};
const handleCopy = jest.fn().mockImplementation((arg) => arg);
const cache = createCache();

const result = copiers.copyObjectLoose(
object,
Object.getPrototypeOf(object),
handleCopy,
cache
);

expect(result).not.toBe(object);
expect(result).toEqual(object);

expect(handleCopy).toHaveBeenCalledTimes(
Object.keys(object).length + Object.getOwnPropertySymbols(object).length
);
});
});

describe('copyObjectStrict', () => {
it('will create an object clone when property symbols are not supported', () => {
const original = Object.getOwnPropertySymbols;

jest.isolateModules(() => {
Object.getOwnPropertySymbols = undefined;
copiers = require('../src/copiers');
});

const object: PlainObject = {
bar: { baz: 'quz' },
};

Object.defineProperty(object, 'foo', {
value: 'bar',
});

Object.defineProperty(object, Symbol('quz'), {
enumerable: true,
value: 'blah',
});

const handleCopy = jest.fn().mockImplementation((arg) => arg);
const cache = createCache();

const result = copiers.copyObjectStrict(
object,
Object.getPrototypeOf(object),
handleCopy,
cache
);

Object.getOwnPropertySymbols = original;

expect(result).not.toBe(object);
expect(result).toEqual(
Object.keys(object).reduce(
(clone: PlainObject, key: string): PlainObject => {
clone[key] = object[key];

return clone;
},
{}
)
);

expect(handleCopy).toHaveBeenCalledTimes(
Object.getOwnPropertyNames(object).length
);
});

it('will create an object clone when property symbols are not supported', () => {
const object: PlainObject = {
bar: { baz: 'quz' },
};

Object.defineProperty(object, 'foo', {
value: 'bar',
});

Object.defineProperty(object, Symbol('quz'), {
enumerable: true,
value: 'blah',
});

const handleCopy = jest.fn().mockImplementation((arg) => arg);
const cache = createCache();

const result = copiers.copyObjectStrict(
object,
Object.getPrototypeOf(object),
handleCopy,
cache
);

expect(result).not.toBe(object);
expect(result).toEqual(object);

expect(handleCopy).toHaveBeenCalledTimes(
Object.getOwnPropertyNames(object).length +
Object.getOwnPropertySymbols(object).length
);
});
});
148 changes: 0 additions & 148 deletions __tests__/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,154 +137,6 @@ describe('getCleanClone', () => {
});
});

describe('getObjectCloneLoose', () => {
it('will create an object clone when property symbols are not supported', () => {
const original = Object.getOwnPropertySymbols;

jest.isolateModules(() => {
Object.getOwnPropertySymbols = undefined;
utils = require('../src/utils');
});

const symbol = Symbol('quz');
const object = {
bar: { baz: 'quz' },
foo: 'bar',
[symbol]: 'blah',
};
const handleCopy = jest.fn().mockImplementation((arg) => arg);
const cache = utils.createCache();

const result = utils.getObjectCloneLoose(
object,
Object.getPrototypeOf(object),
handleCopy,
cache
);

Object.getOwnPropertySymbols = original;

expect(result).not.toBe(object);
expect(result).toEqual(
Object.keys(object).reduce((clone: PlainObject, key): PlainObject => {
clone[key] = object[key as keyof typeof object];

return clone;
}, {})
);

expect(handleCopy).toHaveBeenCalledTimes(Object.keys(object).length);
});

it('will create an object clone when property symbols are supported', () => {
const object = {
bar: { baz: 'quz' },
[Symbol('quz')]: 'blah',
};
const handleCopy = jest.fn().mockImplementation((arg) => arg);
const cache = utils.createCache();

const result = utils.getObjectCloneLoose(
object,
Object.getPrototypeOf(object),
handleCopy,
cache
);

expect(result).not.toBe(object);
expect(result).toEqual(object);

expect(handleCopy).toHaveBeenCalledTimes(
Object.keys(object).length + Object.getOwnPropertySymbols(object).length
);
});
});

describe('getObjectCloneStrict', () => {
it('will create an object clone when property symbols are not supported', () => {
const original = Object.getOwnPropertySymbols;

jest.isolateModules(() => {
Object.getOwnPropertySymbols = undefined;
utils = require('../src/utils');
});

const object: PlainObject = {
bar: { baz: 'quz' },
};

Object.defineProperty(object, 'foo', {
value: 'bar',
});

Object.defineProperty(object, Symbol('quz'), {
enumerable: true,
value: 'blah',
});

const handleCopy = jest.fn().mockImplementation((arg) => arg);
const cache = utils.createCache();

const result = utils.getObjectCloneStrict(
object,
Object.getPrototypeOf(object),
handleCopy,
cache
);

Object.getOwnPropertySymbols = original;

expect(result).not.toBe(object);
expect(result).toEqual(
Object.keys(object).reduce(
(clone: PlainObject, key: string): PlainObject => {
clone[key] = object[key];

return clone;
},
{}
)
);

expect(handleCopy).toHaveBeenCalledTimes(
Object.getOwnPropertyNames(object).length
);
});

it('will create an object clone when property symbols are not supported', () => {
const object: PlainObject = {
bar: { baz: 'quz' },
};

Object.defineProperty(object, 'foo', {
value: 'bar',
});

Object.defineProperty(object, Symbol('quz'), {
enumerable: true,
value: 'blah',
});

const handleCopy = jest.fn().mockImplementation((arg) => arg);
const cache = utils.createCache();

const result = utils.getObjectCloneStrict(
object,
Object.getPrototypeOf(object),
handleCopy,
cache
);

expect(result).not.toBe(object);
expect(result).toEqual(object);

expect(handleCopy).toHaveBeenCalledTimes(
Object.getOwnPropertyNames(object).length +
Object.getOwnPropertySymbols(object).length
);
});
});

describe('getRegExpFlags', () => {
it('will return an empty string when no flags are on the regexp', () => {
const regexp = /foo/;
Expand Down
Loading

0 comments on commit c303049

Please sign in to comment.