From 71b28b81e3c18c054943cfdfe414d6390e9c36bf Mon Sep 17 00:00:00 2001 From: Nikolay Date: Fri, 12 Jul 2019 17:24:05 +1000 Subject: [PATCH 1/2] Typescript definitions --- index.d.ts | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/index.d.ts b/index.d.ts index e848bff..4b62032 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,9 +1,37 @@ -export function diff (originalObj: object, updatedObj: object): object +type DeepPartial = { + [K in keyof T]?: DeepPartial +} -export function addedDiff (originalObj: object, updatedObj: object): object +interface IDictionary { + [key: string]: T; +} -export function deletedDiff (originalObj: object, updatedObj: object): object +/* + In "deep-object-diff" there're 2 scenarios for a property diff: + 1. If the property is an object or primitive, the diff is a deep partial; + 2. If the property is an array, the diff is a dictionary. + Its keys are indices, and the values are deep partials of the change. +*/ +type PropertyDiff = T extends Array + ? IDictionary + : DeepPartial; -export function updatedDiff (originalObj: object, updatedObj: object): object +export type Diff = { + [P in keyof T]?: PropertyDiff; +}; -export function detailedDiff (originalObj: object, updatedObj: object): object +export interface IDetailedDiff { + added: Diff; + deleted: Diff; + updated: Diff; +} + +export function diff (originalObj: T, updatedObj: T): Diff + +export function addedDiff (originalObj: T, updatedObj: T): Diff + +export function deletedDiff (originalObj: T, updatedObj: T): Diff + +export function updatedDiff (originalObj: T, updatedObj: T): Diff + +export function detailedDiff (originalObj: T, updatedObj: T): IDetailedDiff From 944656dc9a3ec5bc91c51abe118417e1b9a73a7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Maradan?= <3043485+Leomaradan@users.noreply.github.com> Date: Thu, 15 Aug 2019 08:48:18 +0200 Subject: [PATCH 2/2] Add support for NaN value NaN cannot be checked as equality. This commit add a test based on isNaN --- src/diff/index.js | 4 ++++ src/diff/index.test.js | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/diff/index.js b/src/diff/index.js index 74b961b..ee29b00 100644 --- a/src/diff/index.js +++ b/src/diff/index.js @@ -3,6 +3,10 @@ import { isDate, isEmpty, isObject, properObject } from '../utils'; const diff = (lhs, rhs) => { if (lhs === rhs) return {}; // equal return no diff + if (typeof lhs === "number" && typeof rhs === "number") { + if (isNaN(lhs) && isNaN(rhs)) return {}; // NaN is equal + } + if (!isObject(lhs) || !isObject(rhs)) return rhs; // return updated rhs const l = properObject(lhs); diff --git a/src/diff/index.test.js b/src/diff/index.test.js index 32ba35f..11dcde7 100644 --- a/src/diff/index.test.js +++ b/src/diff/index.test.js @@ -13,6 +13,7 @@ describe('.diff', () => { ['object', { a: 1 }], ['array', [1]], ['function', () => ({})], + ['NaN', NaN], ['date', new Date()], ['date with milliseconds', new Date('2017-01-01T00:00:00.637Z')], ])('returns empty object when given values of type %s are equal', (type, value) => { @@ -56,7 +57,7 @@ describe('.diff', () => { }); test('returns subset of right hand side value when nested values differ', () => { - expect(diff({ a: { b: 1, c: 2} }, { a: { b: 1, c: 3 } })).toEqual({ a: { c: 3 } }); + expect(diff({ a: { b: 1, c: 2 } }, { a: { b: 1, c: 3 } })).toEqual({ a: { c: 3 } }); }); test('returns subset of right hand side value when nested values differ at multiple paths', () => { @@ -72,7 +73,7 @@ describe('.diff', () => { }); test('returns keys as undefined when deleted from right hand side', () => { - expect(diff({ a: 1, b: { c: 2 }}, { a: 1 })).toEqual({ b: undefined }); + expect(diff({ a: 1, b: { c: 2 } }, { a: 1 })).toEqual({ b: undefined }); }); }); @@ -139,7 +140,7 @@ describe('.diff', () => { test('returns subset of right hand side value when nested values differ', () => { const lhs = Object.create(null); - lhs.a = { b: 1, c: 2}; + lhs.a = { b: 1, c: 2 }; const rhs = Object.create(null); rhs.a = { b: 1, c: 3 }; expect(diff(lhs, rhs)).toEqual({ a: { c: 3 } }); @@ -173,5 +174,15 @@ describe('.diff', () => { expect(diff(lhs, rhs)).toEqual({ b: 2 }); }); }); + + describe('nested NaN', () => { + test('returns empty object when there is nested NaN value', () => { + expect(diff({ a: 1, b: NaN }, { a: 1, b: NaN })).toEqual({}); + }); + + test('returns subset of right hand side when a left hand side value is not a NaN', () => { + expect(diff({ a: 1, b: 2 }, { a: 1, b: NaN })).toEqual({ b: NaN }); + }); + }); }); });