mattphillips / deep-object-diff

Deep diffs two objects, including nested structures of arrays and objects, and returns the difference. ❄️
https://www.npmjs.com/package/deep-object-diff
MIT License
1.05k stars 89 forks source link

detailedDiff behavior when deleting items from an array does not match README.md documentation #74

Closed NanoDylan closed 2 years ago

NanoDylan commented 2 years ago

According to the detailedDiff example in the README.md, the behavior of detailedDiff when deleting items from an array is to show the deleted items by index. I checked deep-object-diff@1.1.0 (the version that the README.md was updated with detailedDiff and example usage) and the current version deep-object-diff@1.1.7. Instead of indicating the deleted object index within the array in the deleted section, it merely shows the array name in the deleted section with an empty object {}.

const { detailedDiff } = require('deep-object-diff');

const lhs = {
  foo: {
    bar: {
      a: ['a', 'b'],
      b: 2,
      c: ['x', 'y'],
      e: 100 // deleted
    }
  },
  buzz: 'world'
};

const rhs = {
  foo: {
    bar: {
      a: ['a'], // index 1 ('b')  deleted
      b: 2, // unchanged
      c: ['x', 'y', 'z'], // 'z' added
      d: 'Hello, world!' // added
    }
  },
  buzz: 'fizz' // updated
};

const objectDifferences = detailedDiff(lhs, rhs);
console.log(JSON.stringify(objectDifferences, null, 2));

/*  Results documented in README.md. Note that the array 'a' shows '1': undefined, indicating the item missing from the array by its index.
{
  added: {
    foo: {
      bar: {
        c: {
          '2': 'z'
        },
        d: 'Hello, world!'
      }
    }
  },
  deleted: {
    foo: {
      bar: {
        a: {
          '1': undefined
        },
        e: undefined
      }
    }
  },
  updated: {
    buzz: 'fizz'
  }
}
 */

/*
 * Results in deep-object-diff@1.1.0
{
  "added": {
    "foo": {
      "bar": {
        "c": {
          "2": "z"
        },
        "d": "Hello, world!"
      }
    }
  },
  "deleted": {
    "foo": {
      "bar": {
        "a": {}
      }
    }
  },
  "updated": {
    "buzz": "fizz"
  }
}
 */

/*
 * Results in current version deep-object-diff@1.1.7  (same as deep-object-diff@1.1.7)
{
  "added": {
    "foo": {
      "bar": {
        "c": {
          "2": "z"
        },
        "d": "Hello, world!"
      }
    }
  },
  "deleted": {
    "foo": {
      "bar": {
        "a": {}
      }
    }
  },
  "updated": {
    "buzz": "fizz"
  }
}
 */
mattphillips commented 2 years ago

Hi @NanoDylan I'm not to replicate this issue. I think that you might be bumping into a common issue with deep-object-diff and JSON.stringify - specifically with undefined.

When you use stringify to log your diff any undefined values will be removed (as they are not valid JSON).

If you check the diff on https://npm.runkit.com/deep-object-diff with the following code you'll see that version 1.1.0 and 1.1.7 output an identical object.

const { detailedDiff } = require("deep-object-diff@1.1.0");
const { detailedDiff: latestDetailedDiff } = require("deep-object-diff");

const lhs = {
  foo: {
    bar: {
      a: ['a', 'b'],
      b: 2,
      c: ['x', 'y'],
      e: 100 // deleted
    }
  },
  buzz: 'world'
};

const rhs = {
  foo: {
    bar: {
      a: ['a'], // index 1 ('b')  deleted
      b: 2, // unchanged
      c: ['x', 'y', 'z'], // 'z' added
      d: 'Hello, world!' // added
    }
  },
  buzz: 'fizz' // updated
};

console.log(detailedDiff(lhs, rhs));
console.log(latestDetailedDiff(lhs, rhs));

I'm going to close this issue for now but do feel free to re-open / ping me if what I've said above is not correct 👍

NanoDylan commented 2 years ago

Totally my bad. Thank you for the detailed example and pointer to runkit. 👍