From 321acbf424b2faea944d25c33f9ca96a07be3efa Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Tue, 7 Jul 2020 22:15:58 -0700 Subject: [PATCH] feat: add a shallowEqual helper --- src/utils/__tests__/shallowEqual.js | 101 ++++++++++++++++++++++++++++ src/utils/shallowEqual.js | 22 ++++++ 2 files changed, 123 insertions(+) create mode 100644 src/utils/__tests__/shallowEqual.js create mode 100644 src/utils/shallowEqual.js diff --git a/src/utils/__tests__/shallowEqual.js b/src/utils/__tests__/shallowEqual.js new file mode 100644 index 000000000..92fb9145e --- /dev/null +++ b/src/utils/__tests__/shallowEqual.js @@ -0,0 +1,101 @@ +import shallowEqual from '../shallowEqual'; + +test('true when both objects are empty', () => { + const result = shallowEqual({}, {}); + + expect(result).toBe(true); +}); + +test('true when both objects are referentially equal', () => { + const obj = { a: 1, b: 2 }; + + const result = shallowEqual(obj, obj); + + expect(result).toBe(true); +}); + +test('true when all values are the same', () => { + const result = shallowEqual({ a: 1, b: 2 }, { a: 1, b: 2 }); + + expect(result).toBe(true); +}); + +test('true when values are referentially equal', () => { + const nestedObj = { a: 1 }; + + const result = shallowEqual({ key: nestedObj }, { key: nestedObj }); + + expect(result).toBe(true); +}); + +test('false when values are not shallow', () => { + const result = shallowEqual({ a: {} }, { a: {} }); + + expect(result).toBe(false); +}); + +test('false when one value has too many keys', () => { + const result = shallowEqual({ a: 1 }, { a: 1, b: 2 }); + + expect(result).toBe(false); +}); + +test('false when value is undefined but key is not present in second object', () => { + const result = shallowEqual({ a: undefined }, {}); + + expect(result).toBe(false); +}); + +test('true when all array items are equal', () => { + const result = shallowEqual([1, 2], [1, 2]); + + expect(result).toBe(true); +}); + +test('false when array length differs', () => { + const result = shallowEqual([1], [1, 2]); + + expect(result).toBe(false); +}); + +test('true when both values are null', () => { + const result = shallowEqual(null, null); + + expect(result).toBe(true); +}); + +test('true when both values are undefined', () => { + const result = shallowEqual(undefined, undefined); + + expect(result).toBe(true); +}); + +test('false when one of the values is null', () => { + const result = shallowEqual({}, null); + + expect(result).toBe(false); +}); + +test('false when one of the values is undefined', () => { + const result = shallowEqual({}, undefined); + + expect(result).toBe(false); +}); + +test('true when values are not objects and are equal', () => { + const result = shallowEqual(1, 1); + + expect(result).toBe(true); +}); + +test('false when values are not objects and are not equal', () => { + const result = shallowEqual(1, 2); + + expect(result).toBe(false); +}); + +test('false when one value is not an object', () => { + const result = shallowEqual({}, 2); + + expect(result).toBe(false); +}); diff --git a/src/utils/shallowEqual.js b/src/utils/shallowEqual.js new file mode 100644 index 000000000..cf76e428c --- /dev/null +++ b/src/utils/shallowEqual.js @@ -0,0 +1,22 @@ +const hasOwnProperty = Object.prototype.hasOwnProperty; + +const shallowEqual = (a, b) => { + if (a === b) { + return true; + } + + if (typeof a !== 'object' || !a || typeof b !== 'object' || !b) { + return false; + } + + const aKeys = Object.keys(a); + const bKeys = Object.keys(b); + + if (aKeys.length !== bKeys.length) { + return false; + } + + return aKeys.every((key) => hasOwnProperty.call(b, key) && a[key] === b[key]); +}; + +export default shallowEqual;