Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3409261
D7753.id26274.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
3 KB
Referenced Files
None
Subscribers
None
D7753.id26274.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Thu, Dec 5, 3:25 PM (10 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2617395
Default Alt Text
D7753.id26274.diff (3 KB)
Attached To
Mode
D7753: [lib] introduce function to find deep difference between two objects
Attached
Detach File
Event Timeline
Log In to Comment