APP-72Recommended
Test that copies end up equal in any order
Run a property test that makes random edits on three copies and delivers the changes in every order, twice over. All copies must end equal. Run at least 1,000 cases in CI.
How to do it
The library promises that copies converge, but your own code around it can break that. Loading, saving, compacting and filtering messages are common places. Test that code with property tests. Feed the changes through your own storage and server functions, not only the library. Longer sequences of joins and drops fit Test sequences of actions against a simple model.
Examples
TypeScript example
const ORDERS = [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]];
test('copies end up equal in any delivery order', () => {
fc.assert(fc.property(fc.array(fc.tuple(fc.nat(2), fc.nat(50), fc.string({ maxLength: 5 })), { maxLength: 30 }), edits => {
const copies = [0, 1, 2].map(() => new Y.Doc());
for (const [copy, at, value] of edits) {
const text = copies[copy].getText('body');
text.insert(Math.min(at, text.length), value);
}
const changes = copies.map(doc => Y.encodeStateAsUpdate(doc));
const results = ORDERS.map(order => {
const doc = new Y.Doc();
for (const index of [...order, ...order]) Y.applyUpdate(doc, changes[index]);
return doc.getText('body').toString();
});
expect(new Set(results).size).toBe(1);
}), { numRuns: 1000 });
});
Python example
edits = st.lists(st.tuples(st.integers(0, 2), st.integers(0, 50), st.text(max_size=5)), max_size=30)
@settings(max_examples=1000)
@given(edits, st.randoms())
def test_copies_end_up_equal(edits, random):
copies = [Doc() for _ in range(3)]
for copy, at, value in edits:
text = copies[copy].get("body", type=Text)
text.insert(min(at, len(text)), value)
changes = [copy.get_update() for copy in copies]
results = set()
for _ in range(3):
order = changes * 2
random.shuffle(order)
merged = Doc()
for change in order:
merged.apply_update(change)
results.add(str(merged.get("body", type=Text)))
assert len(results) == 1
How to check
The convergence test runs 1,000 or more cases in CI and passes. Breaking the merge on purpose, such as by dropping one change, makes it fail.
Related rules
- TST-10 Check rules that hold for any input with property tests in Testing
- TST-49 Test sequences of actions against a simple model in Testing
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/app-ui/live-collaboration/convergence-tests">Agent Wranglers web app interface playbook</a>. In code you write, add a comment next to it with the same link.