2025-05-21 16:04:55 +02:00
|
|
|
/**
|
|
|
|
|
* Testing if encoding/decoding compatibility and integration compatibility is given.
|
|
|
|
|
* We expect that the document always looks the same, even if we upgrade the integration algorithm, or add additional encoding approaches.
|
|
|
|
|
*
|
|
|
|
|
* The v1 documents were generated with Yjs v13.2.0 based on the randomisized tests.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import * as Y from '../src/index.js'
|
|
|
|
|
import * as t from 'lib0/testing'
|
2025-10-20 02:14:02 +02:00
|
|
|
import * as delta from 'lib0/delta'
|
2025-05-21 16:04:55 +02:00
|
|
|
|
2025-05-29 21:47:29 +02:00
|
|
|
/**
|
|
|
|
|
* @param {t.TestCase} _tc
|
|
|
|
|
*/
|
|
|
|
|
export const testRelativePositions = _tc => {
|
|
|
|
|
const ydoc = new Y.Doc()
|
|
|
|
|
const ytext = ydoc.getText()
|
|
|
|
|
ytext.insert(0, 'hello world')
|
|
|
|
|
const v1 = Y.cloneDoc(ydoc)
|
|
|
|
|
ytext.delete(1, 6)
|
2025-06-05 14:52:55 +02:00
|
|
|
ytext.insert(1, 'x')
|
2025-05-29 21:47:29 +02:00
|
|
|
const am = Y.createAttributionManagerFromDiff(v1, ydoc)
|
|
|
|
|
const rel = Y.createRelativePositionFromTypeIndex(ytext, 9, 1, am) // pos after "hello wo"
|
|
|
|
|
const abs1 = Y.createAbsolutePositionFromRelativePosition(rel, ydoc, true, am)
|
|
|
|
|
const abs2 = Y.createAbsolutePositionFromRelativePosition(rel, ydoc, true)
|
|
|
|
|
t.assert(abs1?.index === 9)
|
|
|
|
|
t.assert(abs2?.index === 3)
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-21 16:04:55 +02:00
|
|
|
/**
|
|
|
|
|
* @param {t.TestCase} _tc
|
|
|
|
|
*/
|
|
|
|
|
export const testAttributedEvents = _tc => {
|
|
|
|
|
const ydoc = new Y.Doc()
|
|
|
|
|
const ytext = ydoc.getText()
|
|
|
|
|
ytext.insert(0, 'hello world')
|
|
|
|
|
const v1 = Y.cloneDoc(ydoc)
|
|
|
|
|
ydoc.transact(() => {
|
|
|
|
|
ytext.delete(6, 5)
|
|
|
|
|
})
|
2025-05-24 01:14:21 +02:00
|
|
|
const am = Y.createAttributionManagerFromDiff(v1, ydoc)
|
2025-07-19 16:17:05 +02:00
|
|
|
const c1 = ytext.getContent(am)
|
2025-10-20 02:14:02 +02:00
|
|
|
t.compare(c1, delta.text().insert('hello ').insert('world', null, { delete: [] }))
|
2025-05-21 16:04:55 +02:00
|
|
|
let calledObserver = false
|
|
|
|
|
ytext.observe(event => {
|
|
|
|
|
const d = event.getDelta(am)
|
2025-10-20 02:14:02 +02:00
|
|
|
t.compare(d, delta.text().retain(11).insert('!', null, { insert: [] }))
|
2025-05-21 16:04:55 +02:00
|
|
|
calledObserver = true
|
|
|
|
|
})
|
|
|
|
|
ytext.insert(11, '!')
|
|
|
|
|
t.assert(calledObserver)
|
|
|
|
|
}
|
2025-05-21 22:11:28 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param {t.TestCase} _tc
|
|
|
|
|
*/
|
|
|
|
|
export const testInsertionsMindingAttributedContent = _tc => {
|
|
|
|
|
const ydoc = new Y.Doc()
|
|
|
|
|
const ytext = ydoc.getText()
|
|
|
|
|
ytext.insert(0, 'hello world')
|
|
|
|
|
const v1 = Y.cloneDoc(ydoc)
|
|
|
|
|
ydoc.transact(() => {
|
|
|
|
|
ytext.delete(6, 5)
|
|
|
|
|
})
|
2025-05-24 01:14:21 +02:00
|
|
|
const am = Y.createAttributionManagerFromDiff(v1, ydoc)
|
2025-07-19 16:17:05 +02:00
|
|
|
const c1 = ytext.getContent(am)
|
2025-10-20 02:14:02 +02:00
|
|
|
t.compare(c1, delta.text().insert('hello ').insert('world', null, { delete: [] }))
|
|
|
|
|
ytext.applyDelta(delta.text().retain(11).insert('content'), am)
|
2025-05-21 22:11:28 +02:00
|
|
|
t.assert(ytext.toString() === 'hello content')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param {t.TestCase} _tc
|
|
|
|
|
*/
|
|
|
|
|
export const testInsertionsIntoAttributedContent = _tc => {
|
|
|
|
|
const ydoc = new Y.Doc()
|
|
|
|
|
const ytext = ydoc.getText()
|
|
|
|
|
ytext.insert(0, 'hello ')
|
|
|
|
|
const v1 = Y.cloneDoc(ydoc)
|
|
|
|
|
ydoc.transact(() => {
|
|
|
|
|
ytext.insert(6, 'word')
|
|
|
|
|
})
|
2025-05-24 01:14:21 +02:00
|
|
|
const am = Y.createAttributionManagerFromDiff(v1, ydoc)
|
2025-07-19 16:17:05 +02:00
|
|
|
const c1 = ytext.getContent(am)
|
2025-10-20 02:14:02 +02:00
|
|
|
t.compare(c1, delta.text().insert('hello ').insert('word', null, { insert: [] }))
|
|
|
|
|
ytext.applyDelta(delta.text().retain(9).insert('l'), am)
|
2025-05-21 22:11:28 +02:00
|
|
|
t.assert(ytext.toString() === 'hello world')
|
|
|
|
|
}
|