Repository navigation
test(loro.js): add a Rust differential suite for MovableList - #1132
Merged
Merged
Conversation
Drive the Rust WASM build and loro.js with the same random multi-peer edits, crossing engines on every sync, and require equal values, versions, per-element metadata and events. Profiles that diverge on the current MovableList model are recorded as known divergences. Design and findings: context/loro-js-movable-list.md. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Contributor
WASM Size Report
|
Event deltas that differ only in shape are checked by effect; reverts whose op order Rust leaves to hash order are checked by value and replicated from Rust; peers that both engines reject are retired; peer IDs are never reused; undo stays unchained; the minimizer keeps those rules. See context/loro-js-movable-list.md. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This was referenced Sep 27, 2026
This was referenced Sep 29, 2026
…list-differential # Conflicts: # AGENTS.md
…undo unchained Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…se diff shape differs Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…allow root Both follow Rust issues listed in context/loro-js-movable-list.md. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ust reference Load Rust through tests/support/rust-reference.ts like the other differential suites, so it runs in `pnpm test` (and in CI's test-loro-js) and skips without a WASM build. Drop the separate workflow and scripts. insert/delete now converges on main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…diff() A child created in the range whose keys were all set and deleted again is listed by Rust and omitted by loro.js, also on main and for any parent; see context/loro-js-movable-list.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Sep 29, 2026
The changeset named a test:differential script that does not exist. Rust's diff() can list a sequence with an empty delta where loro.js omits it (context/loro-js-movable-list.md). Co-Authored-By: Claude Opus 5.5 <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.
Summary
First PR of the stack that makes the loro.js
MovableListbehave like Rust. This PR only adds tests and the design; the published package does not change.loro-js/tests/differential/is a randomized differential suite. Each simulated peer is a pair of docs with the same peer ID, the Rust WASM build and loro.js. The scenarios cover:update,updates-in-range,snapshotand multi-blobimportBatch;diff,revertTo, and single-peer undo/redo.Syncs randomly cross engines: Rust imports loro.js bytes and loro.js imports Rust bytes. After every step both halves must agree on the value, oplog version, frontiers, reachable container IDs,
getCreatorAt/getLastEditorAt/getLastMoverAt, and canonicalized events.diff()results must match too.A failing seed writes its trace to the temp dir.
LORO_JS_DIFF_REPLAY=<file>replays it andLORO_JS_DIFF_MINIMIZE=1shrinks it.The suite loads Rust through the shared
tests/support/rust-reference.ts, like the other differential suites:crates/loro-wasm/nodejs, orLORO_WASM_NODEJS. It runs insidepnpm test, skips without a WASM build, and runs in CI throughpnpm test-loro-jsafterrelease-wasm. No separate workflow or script.context/loro-js-movable-list.mdcovers:Findings on
mainMovableList, fixed by the follow-up PRs:
["a","c"]in loro.js and["a","c","B"]in Rust.["b","a"]instead of["b"].getLastEditorAt/getLastMoverAtreturn the creator.diffandrevertToselect different winners than Rust.setis skipped (Rust records it).The insert/delete-only profile converges on
mainsince the Fugue fixes in #1136/#1139, so the other seven profiles are markedKNOWN_DIVERGENT. Each asserts that it does diverge, and the model PR empties the set.The suite normalizes a few differences of form and works around two Rust issues; each is commented in
harness.ts/fuzz.tsand listed in the context doc:revertTowhose op order Rust leaves toFxHashMaporder, or whosediff()shape differs, is checked by value, and Rust's ops are replicated.getLastEditorAton shallow documents after a diff across the root, so editors are not compared there.updates-in-rangefrom a shallow doc exports nothing for a span that starts before the root, so spans start at the root.Validation
pnpm -C loro-js check: passes (511 tests; 3 Rust-engine variants of loro.js-only tests skipped). Against a reference built from currentmain, the suite's 8 profiles all pass: one converges, seven diverge as expected.pnpm test-loro-js.Merge order
KNOWN_DIVERGENT).import/importBatch.Each later PR targets the previous PR's branch.
🤖 Generated with Claude Code