microdiff icon indicating copy to clipboard operation
microdiff copied to clipboard

Inconsistent diff Behavior for Object-derived Type Changes

Open delaneyb opened this issue 1 year ago • 0 comments

Issue Summary:

The diff function exhibits inconsistent behavior when comparing changes between properties of different Object-derived types such as Array, Set, Map, etc. It appears to misidentify certain type changes as property additions/removals rather than recognizing a complete change in the property's type.

Example:

const changes = diff({ data: [] }, { data: { val: 'test' } });
// Returned: [ { type: 'CREATE', path: ['data', 'val'], value: 'test' } ]
// Expected: [ { type: 'CHANGE', path: ['data'], value: { val: 'test' } } ]

Description of the bug:

When the diff function encounters property values that have changed type—specifically from an Array, Set, Map, Error, Promise, or Proxy to another object type—it incorrectly reports the changes as individual property mutations (CREATE and REMOVE) rather than recognizing a CHANGE in the entire value for the key.

For types such as Function, Date, and RegExp, when these are nested property values, the change is correctly detected as a CHANGE. However, when types like Array, Set, or Map are nested, they do not receive the same treatment.

Additional Context:

There's a discrepancy based on whether the Object-derived types are passed directly as an argument to diff or nested. For example:

const diffArgument = diff(new Date(), { data: 'test' });
// Returned: [ { type: 'CREATE', path: ['data'], value: 'test' } ]

const diffObjValue = diff({ data: new Date() }, { data: { val: 'test' } });
// Returned: [ { type: 'CHANGE', path: ['data'], value: { val: 'test' }, oldValue: '2023-11-06T02:40:05.198Z' }]

It is not clear if this behavior is intentional or an oversight. Clarification in the documentation would be beneficial.

delaneyb avatar Nov 06 '23 02:11 delaneyb