Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent diff Behavior for Object-derived Type Changes #38

Closed
delaneyb opened this issue Nov 6, 2023 · 2 comments
Closed

Inconsistent diff Behavior for Object-derived Type Changes #38

delaneyb opened this issue Nov 6, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@delaneyb
Copy link

delaneyb commented Nov 6, 2023

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 delaneyb added the bug Something isn't working label Nov 6, 2023
@AsyncBanana
Copy link
Owner

AsyncBanana commented Mar 19, 2024

Microdiff expects a top-level object, and certain object derived types like Date are interpreted as opaque by microdiff (they are diffed like primitives). This is intended behavior, and is what causes the discrepancy for top-level object derived types.

The first issue is unintended though. I will work on a fix.

@AsyncBanana
Copy link
Owner

Fixed in 1.4.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants