fix(compare): emit replace when a root container type changes from an empty value - #333
Open
maximilliangrand wants to merge 1 commit into
Conversation
… empty value
`compare()`/`generate()` produced an empty (or corrupt) patch when one document
root was an empty container and the other was a container of the other type,
e.g. `compare([], {a:1})` returned `[]` and applying it left the document as
`[]`. The array/object substitution fix in Starcounter-Jack#205 only emitted the `replace`
from inside the old-keys loop, so it never ran when the source was empty.
Handle the array-vs-object mismatch once at the top of `_generate` (after
`toJSON`), emitting a single `replace` of the whole subtree (with a matching
`test` op under `invertible`). This also covers the non-empty case previously
handled in the loop, so the now-redundant branch is removed.
Fixes the case documented in Starcounter-Jack#31 (`compare([], {}) === []`) that Starcounter-Jack#205 left open.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
compare()/generate()produce an empty or corrupt patch when one document root is an empty container and the other is a container of the opposite kind:This is the exact case reported in #239 and called out earlier in #31 (
compare([], {}) === []). The array/object-substitution fix in #205 emits the correctivereplacefrom inside the loop over the source's existing keys, so it never runs when the source container is empty.Fix
Handle the array-vs-object mismatch once at the top of
_generate(aftertoJSON): emit a singlereplaceof the whole subtree (plus a matchingtestop underinvertible) and return. This also covers the non-empty case previously handled in the loop, so the now-redundant branch is removed. Because_generaterecurses, this also fixes the nested cases in #239 (e.g.compare({a:[]}, {a:{}})).Tests
Added
comparespecs for empty-array-root→object and empty-object-root→array (bothinvertiblevariants), each asserting the emitted patch and a round-trip viaapplyPatch. They fail onmasterand pass with this change; the rest of the suite is unchanged.Fixes #239. Also resolves the case documented in #31 that #205 left open.