fix(core): Avoid using Object.keys on Buffer and other non-plain objects (#6131)

* create a unified way to check if an object is empty

* avoid running `Object.keys` on Buffer objects, to avoid unnecessary memory usage
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2023-04-28 11:05:48 +00:00
committed by GitHub
parent 188ef042cd
commit a3aba835a1
5 changed files with 101 additions and 8 deletions

View File

@@ -1,4 +1,77 @@
import { jsonParse, jsonStringify, deepCopy } from '@/utils';
import { jsonParse, jsonStringify, deepCopy, isObjectEmpty } from '@/utils';
describe('isObjectEmpty', () => {
it('should handle null and undefined', () => {
expect(isObjectEmpty(null)).toEqual(true);
expect(isObjectEmpty(undefined)).toEqual(true);
});
it('should handle arrays', () => {
expect(isObjectEmpty([])).toEqual(true);
expect(isObjectEmpty([1, 2, 3])).toEqual(false);
});
it('should handle Set and Map', () => {
expect(isObjectEmpty(new Set())).toEqual(true);
expect(isObjectEmpty(new Set([1, 2, 3]))).toEqual(false);
expect(isObjectEmpty(new Map())).toEqual(true);
expect(
isObjectEmpty(
new Map([
['a', 1],
['b', 2],
]),
),
).toEqual(false);
});
it('should handle Buffer, ArrayBuffer, and Uint8Array', () => {
expect(isObjectEmpty(Buffer.from(''))).toEqual(true);
expect(isObjectEmpty(Buffer.from('abcd'))).toEqual(false);
expect(isObjectEmpty(Uint8Array.from([]))).toEqual(true);
expect(isObjectEmpty(Uint8Array.from([1, 2, 3]))).toEqual(false);
expect(isObjectEmpty(new ArrayBuffer(0))).toEqual(true);
expect(isObjectEmpty(new ArrayBuffer(1))).toEqual(false);
});
it('should handle plain objects', () => {
expect(isObjectEmpty({})).toEqual(true);
expect(isObjectEmpty({ a: 1, b: 2 })).toEqual(false);
});
it('should handle instantiated classes', () => {
expect(isObjectEmpty(new (class Test {})())).toEqual(true);
expect(
isObjectEmpty(
new (class Test {
prop = 123;
})(),
),
).toEqual(false);
});
it('should not call Object.keys unless a plain object', () => {
const keySpy = jest.spyOn(Object, 'keys');
const { calls } = keySpy.mock;
const assertCalls = (count: number) => {
if (calls.length !== count) throw new Error(`Object.keys was called ${calls.length} times`);
};
assertCalls(0);
isObjectEmpty(null);
assertCalls(0);
isObjectEmpty([1, 2, 3]);
assertCalls(0);
isObjectEmpty(Buffer.from('123'));
assertCalls(0);
isObjectEmpty({});
assertCalls(1);
});
});
describe('jsonParse', () => {
it('parses JSON', () => {