Page MenuHomePhabricator

D7753.id26274.diff
No OneTemporary

D7753.id26274.diff

diff --git a/lib/utils/objects.js b/lib/utils/objects.js
--- a/lib/utils/objects.js
+++ b/lib/utils/objects.js
@@ -4,6 +4,7 @@
import invariant from 'invariant';
import _difference from 'lodash/fp/difference.js';
import _isEqual from 'lodash/fp/isEqual.js';
+import _isPlainObject from 'lodash/fp/isPlainObject.js';
import stringHash from 'string-hash';
type Map<K, T> = { +[key: K]: T };
@@ -52,6 +53,27 @@
return stringHash(stableStringify(obj));
}
+// returns an object with properties from obj1 not included in obj2
+function deepDiff(obj1: Object, obj2: Object): Object {
+ const diff = {};
+ for (const key in obj1) {
+ if (key in obj2 && _isEqual(obj1[key], obj2[key])) {
+ continue;
+ }
+
+ if (!_isPlainObject(obj1[key]) || !_isPlainObject(obj2[key])) {
+ diff[key] = obj1[key];
+ continue;
+ }
+
+ const nestedDiff = deepDiff(obj1[key], obj2[key]);
+ if (Object.keys(nestedDiff).length > 0) {
+ diff[key] = nestedDiff;
+ }
+ }
+ return diff;
+}
+
function assertObjectsAreEqual<K, T>(
processedObject: Map<K, T>,
expectedObject: Map<K, T>,
@@ -75,4 +97,4 @@
);
}
-export { findMaximumDepth, values, hash, assertObjectsAreEqual };
+export { findMaximumDepth, values, hash, assertObjectsAreEqual, deepDiff };
diff --git a/lib/utils/objects.test.js b/lib/utils/objects.test.js
new file mode 100644
--- /dev/null
+++ b/lib/utils/objects.test.js
@@ -0,0 +1,103 @@
+// @flow
+
+import { deepDiff } from './objects.js';
+
+describe('deepDiff tests', () => {
+ it('should return an empty object if the objects are identical', () => {
+ const obj1 = {
+ key1: 'value1',
+ key2: { foo: 'bar' },
+ };
+ const obj2 = {
+ key1: 'value1',
+ key2: { foo: 'bar' },
+ };
+ const diff = deepDiff(obj1, obj2);
+ expect(diff).toEqual({});
+ });
+
+ it('should return the differences between two objects', () => {
+ const obj1 = {
+ key1: 'value1',
+ key2: { prop: 'a' },
+ };
+ const obj2 = {
+ key1: 'value2',
+ key2: { prop: 'b' },
+ };
+ const diff = deepDiff(obj1, obj2);
+ expect(diff).toEqual({
+ key1: 'value1',
+ key2: {
+ prop: 'a',
+ },
+ });
+ });
+
+ it('should handle objects nested in objects', () => {
+ const obj1 = {
+ key1: 'value1',
+ key2: { prop: 'a', nested: { xyz: 123 } },
+ };
+ const obj2 = {
+ key1: 'value1',
+ key2: { prop: 'a', nested: { xyz: 124 } },
+ };
+ const diff = deepDiff(obj1, obj2);
+ expect(diff).toEqual({
+ key2: {
+ nested: {
+ xyz: 123,
+ },
+ },
+ });
+ });
+
+ it('should handle nested objects with null and undefined values', () => {
+ const obj1 = {
+ key1: null,
+ key2: { prop: undefined },
+ };
+ const obj2 = {
+ key1: undefined,
+ key2: { prop: null },
+ };
+ const diff = deepDiff(obj1, obj2);
+ expect(diff).toEqual({
+ key1: null,
+ key2: {
+ prop: undefined,
+ },
+ });
+ });
+
+ it('should handle objects with different value types', () => {
+ const obj1 = {
+ key1: 'value1',
+ key2: 123,
+ };
+ const obj2 = {
+ key1: 'value1',
+ key2: '123',
+ };
+ const diff = deepDiff(obj1, obj2);
+ expect(diff).toEqual({
+ key2: 123,
+ });
+ });
+
+ it('should handle objects with array value types', () => {
+ const obj1 = {
+ key1: ['value1'],
+ key2: ['a', 1],
+ };
+ const obj2 = {
+ key1: ['value1'],
+ key2: ['a', 2],
+ };
+ const diff = deepDiff(obj1, obj2);
+ expect(diff).toEqual({
+ key2: ['a', 1],
+ });
+ });
+});

File Metadata

Mime Type
text/plain
Expires
Thu, Dec 5, 3:25 PM (14 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2617395
Default Alt Text
D7753.id26274.diff (3 KB)

Event Timeline