Skip to content

Commit

Permalink
Support null-prototype objects as first-class citizens in keepFresh
Browse files Browse the repository at this point in the history
… operator. Aftershock for release 0.10.3.
  • Loading branch information
igorkamyshev committed Oct 28, 2023
1 parent e8f909f commit ac5e2d8
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .changeset/sharp-icons-explain.md
@@ -0,0 +1,5 @@
---
'@farfetched/core': patch
---

Support null-prototype objects as first-class citizens in `keepFresh` operator. Aftershock for release 0.10.3.
42 changes: 29 additions & 13 deletions packages/core/src/libs/lohyphen/__tests__/is_equal.test.ts
Expand Up @@ -82,18 +82,34 @@ describe('Functional', () => {
});

describe('isEqual', () => {
test('do not throw on weird objects, issue #385', () => {
function createWeirdObject() {
const a = {};
// @ts-expect-error 🤷‍♂️
a.__proto__ = null;
return a;
}

const weirdObject1 = createWeirdObject();
const weirdObject2 = createWeirdObject();

expect(() => isEqual(weirdObject1, weirdObject2)).not.toThrow();
expect(isEqual(weirdObject1, weirdObject2)).toBe(false);
describe('null-proto objects, issue #385', () => {
test('empty objects', () => {
const weirdObject1 = Object.create(null);
const weirdObject2 = Object.create(null);

expect(() => isEqual(weirdObject1, weirdObject2)).not.toThrow();
expect(isEqual(weirdObject1, weirdObject2)).toBe(true);
});

test('different objects', () => {
const weirdObject1 = Object.create(null);
weirdObject1.a = 1;

const weirdObject2 = Object.create(null);

expect(() => isEqual(weirdObject1, weirdObject2)).not.toThrow();
expect(isEqual(weirdObject1, weirdObject2)).toBe(false);
});

test('same objects', () => {
const weirdObject1 = Object.create(null);
weirdObject1.a = 1;

const weirdObject2 = Object.create(null);
weirdObject2.a = 1;

expect(() => isEqual(weirdObject1, weirdObject2)).not.toThrow();
expect(isEqual(weirdObject1, weirdObject2)).toBe(true);
});
});
});
9 changes: 6 additions & 3 deletions packages/core/src/libs/lohyphen/is_equal.ts
Expand Up @@ -34,8 +34,7 @@ export function isEqual(a: any, b: any): boolean {
for (let i = 0, l = keysA.length; i < l; i++) {
const key = keysA[i];

// eslint-disable-next-line no-prototype-builtins
if (!b.hasOwnProperty(keysA[i])) {
if (!Object.prototype.hasOwnProperty.call(b, keysA[i])) {
return false;
}

Expand Down Expand Up @@ -75,13 +74,17 @@ export function isEqual(a: any, b: any): boolean {
return true;
} else if (typeA === 'object') {
if (
a.valueOf &&
b.valueOf &&
a.valueOf !== Object.prototype.valueOf() &&
b.valueOf !== Object.prototype.valueOf()
) {
return a.valueOf() === b.valueOf();
}

if (
a.toString &&
a.toString &&
a.toString !== Object.prototype.toString() &&
b.toString !== Object.prototype.toString()
) {
Expand Down Expand Up @@ -121,7 +124,7 @@ function getType(a: any): string {
return 'null';
} else if (isArrayLike(a)) {
return 'array';
} else if (a.constructor === Object) {
} else if (a.constructor === Object || Object.getPrototypeOf(a) === null) {
return 'pure-object';
}

Expand Down

0 comments on commit ac5e2d8

Please sign in to comment.