fix all type issues

This commit is contained in:
Kevin Jahns
2026-01-06 20:35:18 +01:00
parent ec11ef6f08
commit 2053f7987a
14 changed files with 344 additions and 295 deletions

View File

@@ -213,7 +213,7 @@ export const testUserAttributionEncodingBenchmark = tc => {
idmap.insertIntoIdMap(attributions, idmap.createIdMapFromIdSet(tr.deleteSet, [createAttributionItem('delete', 'userX'), createAttributionItem('deleteAt', currentTime)]))
currentTime += 1
})
const ytext = ydoc.getText()
const ytext = ydoc.get()
const N = 10000
t.measureTime(`time to attribute ${N / 1000}k changes`, () => {
for (let i = 0; i < N; i++) {

View File

@@ -17,7 +17,7 @@ export const testArrayCompatibilityV1 = _tc => {
const oldVal = JSON.parse('[[1,2,3,4],472,472,{"someprop":44},472,[1,2,3,4],{"someprop":44},[1,2,3,4],[1,2,3,4],[1,2,3,4],{"someprop":44},449,448,[1,2,3,4],[1,2,3,4],{"someprop":44},452,{"someprop":44},[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4],452,[1,2,3,4],497,{"someprop":44},497,497,497,{"someprop":44},[1,2,3,4],522,522,452,470,{"someprop":44},[1,2,3,4],453,{"someprop":44},480,480,480,508,508,508,[1,2,3,4],[1,2,3,4],502,492,492,453,{"someprop":44},496,496,496,[1,2,3,4],496,493,495,495,495,495,493,[1,2,3,4],493,493,453,{"someprop":44},{"someprop":44},505,505,517,517,505,[1,2,3,4],{"someprop":44},509,{"someprop":44},521,521,521,509,477,{"someprop":44},{"someprop":44},485,485,{"someprop":44},515,{"someprop":44},451,{"someprop":44},[1,2,3,4],516,516,516,516,{"someprop":44},499,499,469,469,[1,2,3,4],[1,2,3,4],512,512,512,{"someprop":44},454,487,487,487,[1,2,3,4],[1,2,3,4],454,[1,2,3,4],[1,2,3,4],{"someprop":44},[1,2,3,4],459,[1,2,3,4],513,459,{"someprop":44},[1,2,3,4],482,{"someprop":44},[1,2,3,4],[1,2,3,4],459,[1,2,3,4],{"someprop":44},[1,2,3,4],484,454,510,510,510,510,468,{"someprop":44},468,[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4],467,[1,2,3,4],467,486,486,486,[1,2,3,4],489,451,[1,2,3,4],{"someprop":44},[1,2,3,4],[1,2,3,4],{"someprop":44},{"someprop":44},483,[1,2,3,4],{"someprop":44},{"someprop":44},{"someprop":44},{"someprop":44},519,519,519,519,506,506,[1,2,3,4],{"someprop":44},464,{"someprop":44},481,481,[1,2,3,4],{"someprop":44},[1,2,3,4],464,475,475,475,463,{"someprop":44},[1,2,3,4],518,[1,2,3,4],[1,2,3,4],463,455,498,498,498,466,471,471,471,501,[1,2,3,4],501,501,476,{"someprop":44},466,[1,2,3,4],{"someprop":44},503,503,503,466,455,490,474,{"someprop":44},457,494,494,{"someprop":44},457,479,{"someprop":44},[1,2,3,4],500,500,500,{"someprop":44},[1,2,3,4],[1,2,3,4],{"someprop":44},{"someprop":44},{"someprop":44},[1,2,3,4],[1,2,3,4],{"someprop":44},[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3],491,491,[1,2,3,4],504,504,504,504,465,[1,2,3,4],{"someprop":44},460,{"someprop":44},488,488,488,[1,2,3,4],[1,2,3,4],{"someprop":44},{"someprop":44},514,514,514,514,{"someprop":44},{"someprop":44},{"someprop":44},458,[1,2,3,4],[1,2,3,4],462,[1,2,3,4],[1,2,3,4],{"someprop":44},462,{"someprop":44},[1,2,3,4],{"someprop":44},[1,2,3,4],507,{"someprop":44},{"someprop":44},507,507,{"someprop":44},{"someprop":44},[1,2,3,4],{"someprop":44},461,{"someprop":44},473,461,[1,2,3,4],461,511,511,461,{"someprop":44},{"someprop":44},520,520,520,[1,2,3,4],458]')
const doc = new Y.Doc()
Y.applyUpdate(doc, buffer.fromBase64(oldDoc))
t.compare(doc.getArray('array').toJSON(), oldVal)
t.compare(doc.get('array').toJSON().children, oldVal)
}
/**
@@ -29,7 +29,7 @@ export const testMapDecodingCompatibilityV1 = _tc => {
const oldVal = /** @type {any} */ ({"one":[1,2,3,4],"two":{"deepkey":"deepvalue"}})
const doc = new Y.Doc()
Y.applyUpdate(doc, buffer.fromBase64(oldDoc))
t.compare(doc.getMap('map').toJSON(), oldVal)
t.compare(doc.get('map').toJSON().children, oldVal)
}
/**
@@ -41,5 +41,5 @@ export const testTextDecodingCompatibilityV1 = _tc => {
const oldVal = [{"insert":"1306rup"},{"insert":"uj","format":{"italic":true,"color":"#888"}},{"insert":"ikkcjnrcpsckw1319bccgkp\n"},{"insert":"\n1131","format":{"bold":true}},{"insert":"1326rpcznqahopcrtd","format":{"italic":true}},{"insert":"3axhkthhu","format":{"bold":true}},{"insert":"28"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"9"},{"insert":"04ku","format":{"italic":true}},{"insert":"1323nucvxsqlznwlfavmpc\nu"},{"insert":"tc","format":{"italic":true}},{"insert":"je1318jwskjabdndrdlmjae\n1293tj\nj1292qrmf"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"k\nuf"},{"insert":"14hs","format":{"italic":true}},{"insert":"13dccxdyxg"},{"insert":"zc","format":{"italic":true,"color":"#888"}},{"insert":"apo"},{"insert":"tn","format":{"bold":true}},{"insert":"r"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"gn\n"},{"insert":"z","format":{"italic":true}},{"insert":"\n121"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"291311kk9zjznywohpx"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"cnbrcaq\n"},{"insert":"1","format":{"italic":true,"color":"#888"}},{"insert":"1310g"},{"insert":"ws","format":{"italic":true,"color":"#888"}},{"insert":"hxwych"},{"insert":"kq","format":{"italic":true}},{"insert":"sdru1320cohbvcrkrpjngdoc\njqic\n"},{"insert":"2","format":{"italic":true,"color":"#888"}},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"90n1297zm"},{"insert":"v1309zlgvjx","format":{"bold":true}},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"g","format":{"bold":true}},{"insert":"1314pycavu","format":{"italic":true,"color":"#888"}},{"insert":"pkzqcj"},{"insert":"sa","format":{"italic":true,"color":"#888"}},{"insert":"sjy\n"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"xr\n"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"},{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}, {"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"1"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"1295qfrvlyfap201312qrwt"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"b1322rnbaokorixenvp\nrxq"},{"insert":"j","format":{"italic":true}},{"insert":"x","format":{"italic":true,"color":"#888"}},{"insert":"15mziwabzkrrmscvdovao\n0","format":{"italic":true}},{"insert":"hx","format":{"italic":true,"bold":true}},{"insert":"ojeetrjhxkr13031317pfcyhksrkpkt\nuhv1","format":{"italic":true}},{"insert":"32","format":{"italic":true,"color":"#888"}},{"insert":"4rorywthq1325iodbzizxhmlibvpyrxmq\n\nganln\nqne\n"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]},{"insert":"dvf"},{"insert":"ac","format":{"bold":true}},{"insert":"1302xciwa"},{"insert":"1305rl","format":{"bold":true}},{"insert":"08\n"},{"insert":"eyk","format":{"bold":true}},{"insert":"y1321apgivydqsjfsehhezukiqtt1307tvjiejlh"},{"insert":"1316zlpkmctoqomgfthbpg","format":{"bold":true}},{"insert":"gv"},{"insert":"lb","format":{"bold":true}},{"insert":"f\nhntk\njv1uu\n"},{"insert":[{"image":"https://user-images.githubusercontent.com/5553757/48975307-61efb100-f06d-11e8-9177-ee895e5916e5.png"}]}].map(x => ({ type: 'insert', ...x }))
const doc = new Y.Doc()
Y.applyUpdate(doc, buffer.fromBase64(oldDoc))
t.compare(doc.getText('text').getContent().toJSON().children, /** @type {any} */ (oldVal))
t.compare(doc.get('text').getContent().toJSON().children, /** @type {any} */ (oldVal))
}

View File

@@ -29,10 +29,9 @@ export const testFindTypeInOtherDoc = _tc => {
const ydocClone = new Y.Doc()
Y.applyUpdate(ydocClone, Y.encodeStateAsUpdate(ydoc))
/**
* @template {Y.Type} Type
* @param {Type} ytype
* @param {Y.Type} ytype
* @param {Y.Doc} otherYdoc
* @return {Type}
* @return {Y.Type}
*/
const findTypeInOtherYdoc = (ytype, otherYdoc) => {
const ydoc = /** @type {Y.Doc} */ (ytype.doc)
@@ -47,7 +46,7 @@ export const testFindTypeInOtherDoc = _tc => {
if (rootKey == null) {
throw new Error('type does not exist in other ydoc')
}
return /** @type {Type} */ (otherYdoc.get(rootKey, /** @type {import('../src/utils/ts.js').YTypeConstructors} */ (ytype.constructor)))
return otherYdoc.get(rootKey)
} else {
/**
* If it is a sub type, we use the item id to find the history type.
@@ -60,7 +59,7 @@ export const testFindTypeInOtherDoc = _tc => {
)
const otherItem = /** @type {Y.Item} */ (otherStructs[itemIndex])
const otherContent = /** @type {Y.ContentType} */ (otherItem.content)
return /** @type {Type} */ (otherContent.type)
return /** @type {Y.Type} */ (otherContent.type)
}
}
t.assert(findTypeInOtherYdoc(ymap, ydocClone) != null)
@@ -78,7 +77,7 @@ export const testClientIdDuplicateChange = _tc => {
const doc2 = new Y.Doc()
doc2.clientID = 0
t.assert(doc2.clientID === doc1.clientID)
doc1.getArray('a').insert(0, [1, 2])
doc1.get('a').insert(0, [1, 2])
Y.applyUpdate(doc2, Y.encodeStateAsUpdate(doc1))
t.assert(doc2.clientID !== doc1.clientID)
}
@@ -88,12 +87,12 @@ export const testClientIdDuplicateChange = _tc => {
*/
export const testGetTypeEmptyId = _tc => {
const doc1 = new Y.Doc()
doc1.getText('').insert(0, 'h')
doc1.getText().insert(1, 'i')
doc1.get('').insert(0, 'h')
doc1.get().insert(1, 'i')
const doc2 = new Y.Doc()
Y.applyUpdate(doc2, Y.encodeStateAsUpdate(doc1))
t.assert(doc2.getText().toString() === 'hi')
t.assert(doc2.getText('').toString() === 'hi')
t.assert(doc2.get().toString() === 'hi')
t.assert(doc2.get('').toString() === 'hi')
}
/**
@@ -103,14 +102,14 @@ export const testToJSON = _tc => {
const doc = new Y.Doc()
t.compare(doc.toJSON(), {}, 'doc.toJSON yields empty object')
const arr = doc.getArray('array')
const arr = doc.get('array')
arr.push(['test1'])
const map = doc.getMap('map')
map.set('k1', 'v1')
const map2 = new Y.Map()
map.set('k2', map2)
map2.set('m2k1', 'm2v1')
const map = doc.get('map')
map.setAttr('k1', 'v1')
const map2 = new Y.Type()
map.setAttr('k2', map2)
map2.setAttr('m2k1', 'm2v1')
t.compare(doc.toJSON(), {
array: ['test1'],
@@ -137,30 +136,30 @@ export const testSubdoc = _tc => {
doc.on('subdocs', subdocs => {
event = [Array.from(subdocs.added).map(x => x.guid), Array.from(subdocs.removed).map(x => x.guid), Array.from(subdocs.loaded).map(x => x.guid)]
})
const subdocs = doc.getMap('mysubdocs')
const subdocs = doc.get('mysubdocs')
const docA = new Y.Doc({ guid: 'a' })
docA.load()
subdocs.set('a', docA)
subdocs.setAttr('a', docA)
t.compare(event, [['a'], [], ['a']])
event = null
subdocs.get('a').load()
subdocs.getAttr('a').load()
t.assert(event === null)
event = null
subdocs.get('a').destroy()
subdocs.getAttr('a').destroy()
t.compare(event, [['a'], ['a'], []])
subdocs.get('a').load()
subdocs.getAttr('a').load()
t.compare(event, [[], [], ['a']])
subdocs.set('b', new Y.Doc({ guid: 'a', shouldLoad: false }))
subdocs.setAttr('b', new Y.Doc({ guid: 'a', shouldLoad: false }))
t.compare(event, [['a'], [], []])
subdocs.get('b').load()
subdocs.getAttr('b').load()
t.compare(event, [[], [], ['a']])
const docC = new Y.Doc({ guid: 'c' })
docC.load()
subdocs.set('c', docC)
subdocs.setAttr('c', docC)
t.compare(event, [['c'], [], ['c']])
t.compare(Array.from(doc.getSubdocGuids()), ['a', 'c'])
@@ -179,12 +178,12 @@ export const testSubdoc = _tc => {
Y.applyUpdate(doc2, Y.encodeStateAsUpdate(doc))
t.compare(event, [['a', 'a', 'c'], [], []])
doc2.getMap('mysubdocs').get('a').load()
doc2.get('mysubdocs').getAttr('a').load()
t.compare(event, [[], [], ['a']])
t.compare(Array.from(doc2.getSubdocGuids()), ['a', 'c'])
doc2.getMap('mysubdocs').delete('a')
doc2.get('mysubdocs').deleteAttr('a')
t.compare(event, [[], ['a'], []])
t.compare(Array.from(doc2.getSubdocGuids()), ['a', 'c'])
}
@@ -195,7 +194,7 @@ export const testSubdoc = _tc => {
*/
export const testSubdocLoadEdgeCases = _tc => {
const ydoc = new Y.Doc()
const yarray = ydoc.getArray()
const yarray = ydoc.get()
const subdoc1 = new Y.Doc()
/**
* @type {any}
@@ -225,7 +224,7 @@ export const testSubdocLoadEdgeCases = _tc => {
lastEvent = event
})
Y.applyUpdate(ydoc2, Y.encodeStateAsUpdate(ydoc))
const subdoc3 = ydoc2.getArray().get(0)
const subdoc3 = ydoc2.get().get(0)
t.assert(subdoc3.shouldLoad === false)
t.assert(subdoc3.autoLoad === false)
t.assert(lastEvent !== null && lastEvent.added.has(subdoc3))
@@ -242,7 +241,7 @@ export const testSubdocLoadEdgeCases = _tc => {
*/
export const testSubdocLoadEdgeCasesAutoload = _tc => {
const ydoc = new Y.Doc()
const yarray = ydoc.getArray()
const yarray = ydoc.get()
const subdoc1 = new Y.Doc({ autoLoad: true })
/**
* @type {any}
@@ -272,7 +271,7 @@ export const testSubdocLoadEdgeCasesAutoload = _tc => {
lastEvent = event
})
Y.applyUpdate(ydoc2, Y.encodeStateAsUpdate(ydoc))
const subdoc3 = ydoc2.getArray().get(0)
const subdoc3 = ydoc2.get().get(0)
t.assert(subdoc1.shouldLoad)
t.assert(subdoc1.autoLoad)
t.assert(lastEvent !== null && lastEvent.added.has(subdoc3))
@@ -284,7 +283,7 @@ export const testSubdocLoadEdgeCasesAutoload = _tc => {
*/
export const testSubdocsUndo = _tc => {
const ydoc = new Y.Doc()
const elems = ydoc.getXmlFragment()
const elems = ydoc.get()
const undoManager = new Y.UndoManager(elems)
const subdoc = new Y.Doc()
// @ts-ignore

View File

@@ -42,12 +42,12 @@ export const testDiffStateVectorOfUpdateIsEmpty = _tc => {
* @type {any}
*/
let sv = null
ydoc.getText().insert(0, 'a')
ydoc.get().insert(0, 'a')
ydoc.on('update', update => {
sv = Y.encodeStateVectorFromUpdate(update)
})
// should produce an update with an empty state vector (because previous ops are missing)
ydoc.getText().insert(0, 'a')
ydoc.get().insert(0, 'a')
t.assert(sv !== null && sv.byteLength === 1 && sv[0] === 0)
}
@@ -64,9 +64,9 @@ export const testDiffStateVectorOfUpdateIgnoresSkips = _tc => {
ydoc.on('update', update => {
updates.push(update)
})
ydoc.getText().insert(0, 'a')
ydoc.getText().insert(0, 'b')
ydoc.getText().insert(0, 'c')
ydoc.get().insert(0, 'a')
ydoc.get().insert(0, 'b')
ydoc.get().insert(0, 'c')
const update13 = Y.mergeUpdates([updates[0], updates[2]])
const sv = Y.encodeStateVectorFromUpdate(update13)
const state = Y.decodeStateVector(sv)

View File

@@ -2,7 +2,7 @@ import * as Y from '../src/index.js'
import * as t from 'lib0/testing'
/**
* @param {Y.Text} ytext
* @param {Y.Type<{text:true}>} ytext
*/
const checkRelativePositions = ytext => {
// test if all positions are encoded and restored correctly
@@ -20,11 +20,11 @@ const checkRelativePositions = ytext => {
}
/**
* @param {t.TestCase} tc
* @param {t.TestCase} _tc
*/
export const testRelativePositionCase1 = tc => {
export const testRelativePositionCase1 = _tc => {
const ydoc = new Y.Doc()
const ytext = ydoc.getText()
const ytext = ydoc.get()
ytext.insert(0, '1')
ytext.insert(0, 'abc')
ytext.insert(0, 'z')
@@ -34,21 +34,21 @@ export const testRelativePositionCase1 = tc => {
}
/**
* @param {t.TestCase} tc
* @param {t.TestCase} _tc
*/
export const testRelativePositionCase2 = tc => {
export const testRelativePositionCase2 = _tc => {
const ydoc = new Y.Doc()
const ytext = ydoc.getText()
const ytext = ydoc.get()
ytext.insert(0, 'abc')
checkRelativePositions(ytext)
}
/**
* @param {t.TestCase} tc
* @param {t.TestCase} _tc
*/
export const testRelativePositionCase3 = tc => {
export const testRelativePositionCase3 = _tc => {
const ydoc = new Y.Doc()
const ytext = ydoc.getText()
const ytext = ydoc.get()
ytext.insert(0, 'abc')
ytext.insert(0, '1')
ytext.insert(0, 'xyz')
@@ -56,43 +56,43 @@ export const testRelativePositionCase3 = tc => {
}
/**
* @param {t.TestCase} tc
* @param {t.TestCase} _tc
*/
export const testRelativePositionCase4 = tc => {
export const testRelativePositionCase4 = _tc => {
const ydoc = new Y.Doc()
const ytext = ydoc.getText()
const ytext = ydoc.get()
ytext.insert(0, '1')
checkRelativePositions(ytext)
}
/**
* @param {t.TestCase} tc
* @param {t.TestCase} _tc
*/
export const testRelativePositionCase5 = tc => {
export const testRelativePositionCase5 = _tc => {
const ydoc = new Y.Doc()
const ytext = ydoc.getText()
const ytext = ydoc.get()
ytext.insert(0, '2')
ytext.insert(0, '1')
checkRelativePositions(ytext)
}
/**
* @param {t.TestCase} tc
* @param {t.TestCase} _tc
*/
export const testRelativePositionCase6 = tc => {
export const testRelativePositionCase6 = _tc => {
const ydoc = new Y.Doc()
const ytext = ydoc.getText()
const ytext = ydoc.get()
checkRelativePositions(ytext)
}
/**
* Testing https://github.com/yjs/yjs/issues/657
*
* @param {t.TestCase} tc
* @param {t.TestCase} _tc
*/
export const testRelativePositionCase7 = tc => {
export const testRelativePositionCase7 = _tc => {
const docA = new Y.Doc()
const textA = docA.getText('text')
const textA = docA.get('text')
textA.insert(0, 'abcde')
// Create a relative position at index 2 in 'textA'
const relativePosition = Y.createRelativePositionFromTypeIndex(textA, 2)
@@ -106,11 +106,11 @@ export const testRelativePositionCase7 = tc => {
}
/**
* @param {t.TestCase} tc
* @param {t.TestCase} _tc
*/
export const testRelativePositionAssociationDifference = tc => {
export const testRelativePositionAssociationDifference = _tc => {
const ydoc = new Y.Doc()
const ytext = ydoc.getText()
const ytext = ydoc.get()
ytext.insert(0, '2')
ytext.insert(0, '1')
const rposRight = Y.createRelativePositionFromTypeIndex(ytext, 1, 0)
@@ -123,11 +123,11 @@ export const testRelativePositionAssociationDifference = tc => {
}
/**
* @param {t.TestCase} tc
* @param {t.TestCase} _tc
*/
export const testRelativePositionWithUndo = tc => {
export const testRelativePositionWithUndo = _tc => {
const ydoc = new Y.Doc()
const ytext = ydoc.getText()
const ytext = ydoc.get()
ytext.insert(0, 'hello world')
const rpos = Y.createRelativePositionFromTypeIndex(ytext, 1)
const um = new Y.UndoManager(ytext)

View File

@@ -1,17 +1,18 @@
import * as Y from '../src/index.js'
import * as t from 'lib0/testing'
import { init } from './testHelper.js'
import * as delta from 'lib0/delta'
/**
* @param {t.TestCase} _tc
*/
export const testBasic = _tc => {
const ydoc = new Y.Doc({ gc: false })
ydoc.getText().insert(0, 'world!')
ydoc.get().insert(0, 'world!')
const snapshot = Y.snapshot(ydoc)
ydoc.getText().insert(0, 'hello ')
ydoc.get().insert(0, 'hello ')
const restored = Y.createDocFromSnapshot(ydoc, snapshot)
t.assert(restored.getText().toString() === 'world!')
t.assert(restored.get().getContent().equals(delta.create().insert('world!')))
}
/**
@@ -19,7 +20,7 @@ export const testBasic = _tc => {
*/
export const testBasicXmlAttributes = _tc => {
const ydoc = new Y.Doc({ gc: false })
const yxml = ydoc.getMap().set('el', new Y.XmlElement('div'))
const yxml = ydoc.get().setAttr('el', new Y.Type('div'))
const snapshot1 = Y.snapshot(ydoc)
yxml.setAttribute('a', '1')
const snapshot2 = Y.snapshot(ydoc)
@@ -34,14 +35,14 @@ export const testBasicXmlAttributes = _tc => {
*/
export const testBasicRestoreSnapshot = _tc => {
const doc = new Y.Doc({ gc: false })
doc.getArray('array').insert(0, ['hello'])
doc.get('array').insert(0, ['hello'])
const snap = Y.snapshot(doc)
doc.getArray('array').insert(1, ['world'])
doc.get('array').insert(1, ['world'])
const docRestored = Y.createDocFromSnapshot(doc, snap)
t.compare(docRestored.getArray('array').toArray(), ['hello'])
t.compare(doc.getArray('array').toArray(), ['hello', 'world'])
t.compare(docRestored.get('array').toArray(), ['hello'])
t.compare(doc.get('array').toJSON().children, ['hello', 'world'])
}
/**
@@ -51,17 +52,17 @@ export const testEmptyRestoreSnapshot = _tc => {
const doc = new Y.Doc({ gc: false })
const snap = Y.snapshot(doc)
snap.sv.set(9999, 0)
doc.getArray().insert(0, ['world'])
doc.get().insert(0, ['world'])
const docRestored = Y.createDocFromSnapshot(doc, snap)
t.compare(docRestored.getArray().toArray(), [])
t.compare(doc.getArray().toArray(), ['world'])
t.compare(docRestored.get().toArray(), [])
t.compare(doc.get().toArray(), ['world'])
// now this snapshot reflects the latest state. It should still work.
const snap2 = Y.snapshot(doc)
const docRestored2 = Y.createDocFromSnapshot(doc, snap2)
t.compare(docRestored2.getArray().toArray(), ['world'])
t.compare(docRestored2.get().toArray(), ['world'])
}
/**
@@ -69,8 +70,8 @@ export const testEmptyRestoreSnapshot = _tc => {
*/
export const testRestoreSnapshotWithSubType = _tc => {
const doc = new Y.Doc({ gc: false })
doc.getArray('array').insert(0, [new Y.Map()])
const subMap = doc.getArray('array').get(0)
doc.get('array').insert(0, [new Y.Type()])
const subMap = doc.get('array').get(0)
subMap.set('key1', 'value1')
const snap = Y.snapshot(doc)
@@ -78,10 +79,10 @@ export const testRestoreSnapshotWithSubType = _tc => {
const docRestored = Y.createDocFromSnapshot(doc, snap)
t.compare(docRestored.getArray('array').toJSON(), [{
t.compare(docRestored.get('array').toJSON().children, [{
key1: 'value1'
}])
t.compare(doc.getArray('array').toJSON(), [{
t.compare(doc.get('array').toJSON().children, [{
key1: 'value1',
key2: 'value2'
}])
@@ -92,15 +93,15 @@ export const testRestoreSnapshotWithSubType = _tc => {
*/
export const testRestoreDeletedItem1 = _tc => {
const doc = new Y.Doc({ gc: false })
doc.getArray('array').insert(0, ['item1', 'item2'])
doc.get('array').insert(0, ['item1', 'item2'])
const snap = Y.snapshot(doc)
doc.getArray('array').delete(0)
doc.get('array').delete(0)
const docRestored = Y.createDocFromSnapshot(doc, snap)
t.compare(docRestored.getArray('array').toArray(), ['item1', 'item2'])
t.compare(doc.getArray('array').toArray(), ['item2'])
t.compare(docRestored.get('array').toArray(), ['item1', 'item2'])
t.compare(doc.get('array').toArray(), ['item2'])
}
/**
@@ -108,17 +109,17 @@ export const testRestoreDeletedItem1 = _tc => {
*/
export const testRestoreLeftItem = _tc => {
const doc = new Y.Doc({ gc: false })
doc.getArray('array').insert(0, ['item1'])
doc.getMap('map').set('test', 1)
doc.getArray('array').insert(0, ['item0'])
doc.get('array').insert(0, ['item1'])
doc.get('map').setAttr('test', 1)
doc.get('array').insert(0, ['item0'])
const snap = Y.snapshot(doc)
doc.getArray('array').delete(1)
doc.get('array').delete(1)
const docRestored = Y.createDocFromSnapshot(doc, snap)
t.compare(docRestored.getArray('array').toArray(), ['item0', 'item1'])
t.compare(doc.getArray('array').toArray(), ['item0'])
t.compare(docRestored.get('array').toArray(), ['item0', 'item1'])
t.compare(doc.get('array').toArray(), ['item0'])
}
/**
@@ -126,15 +127,15 @@ export const testRestoreLeftItem = _tc => {
*/
export const testDeletedItemsBase = _tc => {
const doc = new Y.Doc({ gc: false })
doc.getArray('array').insert(0, ['item1'])
doc.getArray('array').delete(0)
doc.get('array').insert(0, ['item1'])
doc.get('array').delete(0)
const snap = Y.snapshot(doc)
doc.getArray('array').insert(0, ['item0'])
doc.get('array').insert(0, ['item0'])
const docRestored = Y.createDocFromSnapshot(doc, snap)
t.compare(docRestored.getArray('array').toArray(), [])
t.compare(doc.getArray('array').toArray(), ['item0'])
t.compare(docRestored.get('array').toArray(), [])
t.compare(doc.get('array').toArray(), ['item0'])
}
/**
@@ -142,15 +143,15 @@ export const testDeletedItemsBase = _tc => {
*/
export const testDeletedItems2 = _tc => {
const doc = new Y.Doc({ gc: false })
doc.getArray('array').insert(0, ['item1', 'item2', 'item3'])
doc.getArray('array').delete(1)
doc.get('array').insert(0, ['item1', 'item2', 'item3'])
doc.get('array').delete(1)
const snap = Y.snapshot(doc)
doc.getArray('array').insert(0, ['item0'])
doc.get('array').insert(0, ['item0'])
const docRestored = Y.createDocFromSnapshot(doc, snap)
t.compare(docRestored.getArray('array').toArray(), ['item1', 'item3'])
t.compare(doc.getArray('array').toArray(), ['item0', 'item1', 'item3'])
t.compare(docRestored.get('array').toArray(), ['item1', 'item3'])
t.compare(doc.get('array').toArray(), ['item0', 'item1', 'item3'])
}
/**
@@ -191,10 +192,10 @@ export const testDependentChanges = tc => {
testConnector.syncAll()
const docRestored0 = Y.createDocFromSnapshot(array0.doc, snap)
t.compare(docRestored0.getArray('array').toArray(), ['user1item1', 'user2item1'])
t.compare(docRestored0.get('array').toArray(), ['user1item1', 'user2item1'])
const docRestored1 = Y.createDocFromSnapshot(array1.doc, snap)
t.compare(docRestored1.getArray('array').toArray(), ['user1item1', 'user2item1'])
t.compare(docRestored1.get('array').toArray(), ['user1item1', 'user2item1'])
}
/**
@@ -209,7 +210,7 @@ export const testContainsUpdate = _tc => {
ydoc.on('update', update => {
updates.push(update)
})
const yarr = ydoc.getArray()
const yarr = ydoc.get()
const snapshot1 = Y.snapshot(ydoc)
yarr.insert(0, [1])
const snapshot2 = Y.snapshot(ydoc)

View File

@@ -468,8 +468,6 @@ export const compare = users => {
t.assert(u.store.pendingDs === null)
t.assert(u.store.pendingStructs === null)
}
// Test Array iterator
t.compare(users[0].get('array').toArray(), Array.from(users[0].get('array')))
// Test Map iterator
const ymapkeys = Array.from(users[0].get('map').attrKeys())
t.assert(ymapkeys.length === Object.keys(userMapValues[0]).length)
@@ -478,8 +476,10 @@ export const compare = users => {
* @type {Object<string,any>}
*/
const mapRes = {}
for (const [k, v] of users[0].get('map')) {
mapRes[k] = v instanceof Y.AbstractType ? v.toJSON() : v
const attrs0 = users[0].get('map').getAttrs()
for (const k in attrs0) {
const v = attrs0[k]
mapRes[k] = v instanceof Y.Type ? v.toJSON() : v
}
t.compare(userMapValues[0], mapRes)
// Compare all users

View File

@@ -8,14 +8,14 @@ export const testInconsistentFormat = () => {
* @param {Y.Doc} ydoc
*/
const testYjsMerge = ydoc => {
const content = /** @type {Y.XmlText} */ (ydoc.get('text', Y.XmlText))
const content = ydoc.get('text')
content.format(0, 6, { bold: null })
content.format(6, 4, { type: 'text' })
t.compare(content.getContent(), delta.create().insert('Merge Test', { type: 'text' }).insert(' After', { type: 'text', italic: true }).done())
}
const initializeYDoc = () => {
const yDoc = new Y.Doc({ gc: false })
const content = /** @type {Y.XmlText} */ (yDoc.get('text', Y.XmlText))
const content = yDoc.get('text')
content.insert(0, ' After', { type: 'text', italic: true })
content.insert(0, 'Test', { type: 'text' })
content.insert(0, 'Merge ', { type: 'text', bold: true })
@@ -99,7 +99,7 @@ export const testUndoText = tc => {
export const testEmptyTypeScope = _tc => {
const ydoc = new Y.Doc()
const um = new Y.UndoManager([], { doc: ydoc })
const yarray = ydoc.getArray()
const yarray = ydoc.get()
um.addToScope(yarray)
yarray.insert(0, [1])
um.undo()
@@ -111,15 +111,15 @@ export const testEmptyTypeScope = _tc => {
*/
export const testRejectUpdateExample = _tc => {
const tmpydoc1 = new Y.Doc()
tmpydoc1.getArray('restricted').insert(0, [1])
tmpydoc1.getArray('public').insert(0, [1])
tmpydoc1.get('restricted').insert(0, [1])
tmpydoc1.get('public').insert(0, [1])
const update1 = Y.encodeStateAsUpdate(tmpydoc1)
const tmpydoc2 = new Y.Doc()
tmpydoc2.getArray('public').insert(0, [2])
tmpydoc2.get('public').insert(0, [2])
const update2 = Y.encodeStateAsUpdate(tmpydoc2)
const ydoc = new Y.Doc()
const restrictedType = ydoc.getArray('restricted')
const restrictedType = ydoc.get('restricted')
/**
* Assume this function handles incoming updates via a communication channel like websockets.
@@ -156,7 +156,7 @@ export const testRejectUpdateExample = _tc => {
updateHandler(update1)
updateHandler(update2)
t.assert(restrictedType.length === 0)
t.assert(ydoc.getArray('public').length === 2)
t.assert(ydoc.get('public').length === 2)
}
/**
@@ -166,7 +166,7 @@ export const testRejectUpdateExample = _tc => {
export const testGlobalScope = _tc => {
const ydoc = new Y.Doc()
const um = new Y.UndoManager(ydoc)
const yarray = ydoc.getArray()
const yarray = ydoc.get()
yarray.insert(0, [1])
um.undo()
t.assert(yarray.length === 0)
@@ -178,7 +178,7 @@ export const testGlobalScope = _tc => {
*/
export const testDoubleUndo = _tc => {
const doc = new Y.Doc()
const text = doc.getText()
const text = doc.get()
text.insert(0, '1221')
const manager = new Y.UndoManager(text)
@@ -199,39 +199,39 @@ export const testDoubleUndo = _tc => {
*/
export const testUndoMap = tc => {
const { testConnector, map0, map1 } = init(tc, { users: 2 })
map0.set('a', 0)
map0.setAttr('a', 0)
const undoManager = new Y.UndoManager(map0)
map0.set('a', 1)
map0.setAttr('a', 1)
undoManager.undo()
t.assert(map0.get('a') === 0)
t.assert(map0.getAttr('a') === 0)
undoManager.redo()
t.assert(map0.get('a') === 1)
t.assert(map0.getAttr('a') === 1)
// testing sub-types and if it can restore a whole type
const subType = new Y.Map()
map0.set('a', subType)
subType.set('x', 42)
const subType = new Y.Type()
map0.setAttr('a', subType)
subType.setAttr('x', 42)
t.compare(map0.toJSON(), /** @type {any} */ ({ a: { x: 42 } }))
undoManager.undo()
t.assert(map0.get('a') === 1)
t.assert(map0.getAttr('a') === 1)
undoManager.redo()
t.compare(map0.toJSON(), /** @type {any} */ ({ a: { x: 42 } }))
testConnector.syncAll()
// if content is overwritten by another user, undo operations should be skipped
map1.set('a', 44)
map1.setAttr('a', 44)
testConnector.syncAll()
undoManager.undo()
t.assert(map0.get('a') === 44)
t.assert(map0.getAttr('a') === 44)
undoManager.redo()
t.assert(map0.get('a') === 44)
t.assert(map0.getAttr('a') === 44)
// test setting value multiple times
map0.set('b', 'initial')
map0.setAttr('b', 'initial')
undoManager.stopCapturing()
map0.set('b', 'val1')
map0.set('b', 'val2')
map0.setAttr('b', 'val1')
map0.setAttr('b', 'val2')
undoManager.stopCapturing()
undoManager.undo()
t.assert(map0.get('b') === 'initial')
t.assert(map0.getAttr('b') === 'initial')
}
/**
@@ -257,32 +257,32 @@ export const testUndoArray = tc => {
t.compare(array0.toArray(), [2, 3, 4, 5, 6])
array0.delete(0, 5)
// test nested structure
const ymap = new Y.Map()
const ymap = new Y.Type()
array0.insert(0, [ymap])
t.compare(array0.toJSON(), [{}])
t.compare(array0.toJSON().children, [{}])
undoManager.stopCapturing()
ymap.set('a', 1)
t.compare(array0.toJSON(), [{ a: 1 }])
ymap.setAttr('a', 1)
t.compare(array0.toJSON().children, [{ a: 1 }])
undoManager.undo()
t.compare(array0.toJSON(), [{}])
t.compare(array0.toJSON().children, [{}])
undoManager.undo()
t.compare(array0.toJSON(), [2, 3, 4, 5, 6])
t.compare(array0.toJSON().children, [2, 3, 4, 5, 6])
undoManager.redo()
t.compare(array0.toJSON(), [{}])
t.compare(array0.toJSON().children, [{}])
undoManager.redo()
t.compare(array0.toJSON(), [{ a: 1 }])
t.compare(array0.toJSON().children, [{ a: 1 }])
testConnector.syncAll()
array1.get(0).set('b', 2)
testConnector.syncAll()
t.compare(array0.toJSON(), [{ a: 1, b: 2 }])
t.compare(array0.toJSON().children, [{ a: 1, b: 2 }])
undoManager.undo()
t.compare(array0.toJSON(), [{ b: 2 }])
t.compare(array0.toJSON().children, [{ b: 2 }])
undoManager.undo()
t.compare(array0.toJSON(), [2, 3, 4, 5, 6])
t.compare(array0.toJSON().children, [2, 3, 4, 5, 6])
undoManager.redo()
t.compare(array0.toJSON(), [{ b: 2 }])
t.compare(array0.toJSON().children, [{ b: 2 }])
undoManager.redo()
t.compare(array0.toJSON(), [{ a: 1, b: 2 }])
t.compare(array0.toJSON().children, [{ a: 1, b: 2 }])
}
/**
@@ -291,11 +291,10 @@ export const testUndoArray = tc => {
export const testUndoXml = tc => {
const { xml0 } = init(tc, { users: 3 })
const undoManager = new Y.UndoManager(xml0)
const child = new Y.XmlElement('p')
const child = new Y.Type('p')
xml0.insert(0, [child])
const textchild = new Y.XmlText('content')
const textchild = new Y.Type('content')
child.insert(0, [textchild])
t.assert(xml0.toString() === '<undefined><p>content</p></undefined>')
// format textchild and revert that change
undoManager.stopCapturing()
textchild.format(3, 4, { bold: true })
@@ -358,8 +357,8 @@ export const testTrackClass = tc => {
export const testTypeScope = tc => {
const { array0 } = init(tc, { users: 3 })
// only track origins that are numbers
const text0 = new Y.Text()
const text1 = new Y.Text()
const text0 = new Y.Type()
const text1 = new Y.Type()
array0.insert(0, [text0, text1])
const undoManager = new Y.UndoManager(text0)
const undoManagerBoth = new Y.UndoManager([text0, text1])
@@ -379,9 +378,9 @@ export const testTypeScope = tc => {
export const testUndoInEmbed = tc => {
const { text0 } = init(tc, { users: 3 })
const undoManager = new Y.UndoManager(text0)
const nestedText = new Y.Text('initial text')
const nestedText = new Y.Type('initial text')
undoManager.stopCapturing()
text0.insertEmbed(0, nestedText, { bold: true })
text0.insert(0, [nestedText], { bold: true })
t.assert(nestedText.toString() === 'initial text')
undoManager.stopCapturing()
nestedText.delete(0, nestedText.length)
@@ -397,14 +396,11 @@ export const testUndoInEmbed = tc => {
* @param {t.TestCase} tc
*/
export const testUndoDeleteFilter = tc => {
/**
* @type {Y.Array<any>}
*/
const array0 = /** @type {any} */ (init(tc, { users: 3 }).array0)
const array0 = init(tc, { users: 3 }).array0
const undoManager = new Y.UndoManager(array0, { deleteFilter: item => !(item instanceof Y.Item) || (item.content instanceof Y.ContentType && item.content.type._map.size === 0) })
const map0 = new Y.Map()
map0.set('hi', 1)
const map1 = new Y.Map()
const map0 = new Y.Type()
map0.setAttr('hi', 1)
const map1 = new Y.Type()
array0.insert(0, [map0, map1])
undoManager.undo()
t.assert(array0.length === 1)
@@ -422,25 +418,25 @@ export const testUndoUntilChangePerformed = _tc => {
doc.on('update', update => Y.applyUpdate(doc2, update))
doc2.on('update', update => Y.applyUpdate(doc, update))
const yArray = doc.getArray('array')
const yArray2 = doc2.getArray('array')
const yMap = new Y.Map()
yMap.set('hello', 'world')
const yArray = doc.get('array')
const yArray2 = doc2.get('array')
const yMap = new Y.Type()
yMap.setAttr('hello', 'world')
yArray.push([yMap])
const yMap2 = new Y.Map()
yMap2.set('key', 'value')
const yMap2 = new Y.Type()
yMap2.setAttr('key', 'value')
yArray.push([yMap2])
const undoManager = new Y.UndoManager([yArray], { trackedOrigins: new Set([doc.clientID]) })
const undoManager2 = new Y.UndoManager([doc2.get('array')], { trackedOrigins: new Set([doc2.clientID]) })
Y.transact(doc, () => yMap2.set('key', 'value modified'), doc.clientID)
Y.transact(doc, () => yMap2.setAttr('key', 'value modified'), doc.clientID)
undoManager.stopCapturing()
Y.transact(doc, () => yMap.set('hello', 'world modified'), doc.clientID)
Y.transact(doc, () => yMap.setAttr('hello', 'world modified'), doc.clientID)
Y.transact(doc2, () => yArray2.delete(0), doc2.clientID)
undoManager2.undo()
undoManager.undo()
t.compareStrings(yMap2.get('key'), 'value')
t.compareStrings(yMap2.getAttr('key'), 'value')
}
/**
@@ -449,53 +445,50 @@ export const testUndoUntilChangePerformed = _tc => {
*/
export const testUndoNestedUndoIssue = _tc => {
const doc = new Y.Doc({ gc: false })
const design = doc.getMap()
const design = doc.get()
const undoManager = new Y.UndoManager(design, { captureTimeout: 0 })
/**
* @type {Y.Map<any>}
*/
const text = new Y.Map()
const text = new Y.Type()
const blocks1 = new Y.Array()
const blocks1block = new Y.Map()
const blocks1 = new Y.Type()
const blocks1block = new Y.Type()
doc.transact(() => {
blocks1block.set('text', 'Type Something')
blocks1block.setAttr('text', 'Type Something')
blocks1.push([blocks1block])
text.set('blocks', blocks1block)
design.set('text', text)
text.setAttr('blocks', blocks1block)
design.setAttr('text', text)
})
const blocks2 = new Y.Array()
const blocks2block = new Y.Map()
const blocks2 = new Y.Type()
const blocks2block = new Y.Type()
doc.transact(() => {
blocks2block.set('text', 'Something')
blocks2block.setAttr('text', 'Something')
blocks2.push([blocks2block])
text.set('blocks', blocks2block)
text.setAttr('blocks', blocks2block)
})
const blocks3 = new Y.Array()
const blocks3block = new Y.Map()
const blocks3 = new Y.Type()
const blocks3block = new Y.Type()
doc.transact(() => {
blocks3block.set('text', 'Something Else')
blocks3block.setAttr('text', 'Something Else')
blocks3.push([blocks3block])
text.set('blocks', blocks3block)
text.setAttr('blocks', blocks3block)
})
t.compare(design.toJSON(), { text: { blocks: { text: 'Something Else' } } })
t.compare(design.toJSON().attrs, { text: { blocks: { text: 'Something Else' } } })
undoManager.undo()
t.compare(design.toJSON(), { text: { blocks: { text: 'Something' } } })
t.compare(design.toJSON().attrs, { text: { blocks: { text: 'Something' } } })
undoManager.undo()
t.compare(design.toJSON(), { text: { blocks: { text: 'Type Something' } } })
t.compare(design.toJSON().attrs, { text: { blocks: { text: 'Type Something' } } })
undoManager.undo()
t.compare(design.toJSON(), { })
t.compare(design.toJSON().attrs, { })
undoManager.redo()
t.compare(design.toJSON(), { text: { blocks: { text: 'Type Something' } } })
t.compare(design.toJSON().attrs, { text: { blocks: { text: 'Type Something' } } })
undoManager.redo()
t.compare(design.toJSON(), { text: { blocks: { text: 'Something' } } })
t.compare(design.toJSON().attrs, { text: { blocks: { text: 'Something' } } })
undoManager.redo()
t.compare(design.toJSON(), { text: { blocks: { text: 'Something Else' } } })
t.compare(design.toJSON().attrs, { text: { blocks: { text: 'Something Else' } } })
}
/**
@@ -505,48 +498,48 @@ export const testUndoNestedUndoIssue = _tc => {
*/
export const testConsecutiveRedoBug = _tc => {
const doc = new Y.Doc()
const yRoot = doc.getMap()
const yRoot = doc.get()
const undoMgr = new Y.UndoManager(yRoot)
let yPoint = new Y.Map()
yPoint.set('x', 0)
yPoint.set('y', 0)
yRoot.set('a', yPoint)
let yPoint = new Y.Type()
yPoint.setAttr('x', 0)
yPoint.setAttr('y', 0)
yRoot.setAttr('a', yPoint)
undoMgr.stopCapturing()
yPoint.set('x', 100)
yPoint.set('y', 100)
yPoint.setAttr('x', 100)
yPoint.setAttr('y', 100)
undoMgr.stopCapturing()
yPoint.set('x', 200)
yPoint.set('y', 200)
yPoint.setAttr('x', 200)
yPoint.setAttr('y', 200)
undoMgr.stopCapturing()
yPoint.set('x', 300)
yPoint.set('y', 300)
yPoint.setAttr('x', 300)
yPoint.setAttr('y', 300)
undoMgr.stopCapturing()
t.compare(yPoint.toJSON(), { x: 300, y: 300 })
t.compare(yPoint.toJSON().attrs, { x: 300, y: 300 })
undoMgr.undo() // x=200, y=200
t.compare(yPoint.toJSON(), { x: 200, y: 200 })
t.compare(yPoint.toJSON().attrs, { x: 200, y: 200 })
undoMgr.undo() // x=100, y=100
t.compare(yPoint.toJSON(), { x: 100, y: 100 })
t.compare(yPoint.toJSON().attrs, { x: 100, y: 100 })
undoMgr.undo() // x=0, y=0
t.compare(yPoint.toJSON(), { x: 0, y: 0 })
t.compare(yPoint.toJSON().attrs, { x: 0, y: 0 })
undoMgr.undo() // nil
t.compare(yRoot.get('a'), undefined)
t.compare(yRoot.getAttr('a'), undefined)
undoMgr.redo() // x=0, y=0
yPoint = yRoot.get('a')
yPoint = yRoot.getAttr('a')
t.compare(yPoint.toJSON(), { x: 0, y: 0 })
t.compare(yPoint.toJSON().attrs, { x: 0, y: 0 })
undoMgr.redo() // x=100, y=100
t.compare(yPoint.toJSON(), { x: 100, y: 100 })
t.compare(yPoint.toJSON().attrs, { x: 100, y: 100 })
undoMgr.redo() // x=200, y=200
t.compare(yPoint.toJSON(), { x: 200, y: 200 })
t.compare(yPoint.toJSON().attrs, { x: 200, y: 200 })
undoMgr.redo() // expected x=300, y=300, actually nil
t.compare(yPoint.toJSON(), { x: 300, y: 300 })
t.compare(yPoint.toJSON().attrs, { x: 300, y: 300 })
}
/**
@@ -557,7 +550,7 @@ export const testConsecutiveRedoBug = _tc => {
export const testUndoXmlBug = _tc => {
const origin = 'origin'
const doc = new Y.Doc()
const fragment = doc.getXmlFragment('t')
const fragment = doc.get('t')
const undoManager = new Y.UndoManager(fragment, {
captureTimeout: 0,
trackedOrigins: new Set([origin])
@@ -565,9 +558,9 @@ export const testUndoXmlBug = _tc => {
// create element
doc.transact(() => {
const e = new Y.XmlElement('test-node')
e.setAttribute('a', '100')
e.setAttribute('b', '0')
const e = new Y.Type('test-node')
e.setAttr('a', '100')
e.setAttr('b', '0')
fragment.insert(fragment.length, [e])
}, origin)
@@ -601,44 +594,44 @@ export const testUndoXmlBug = _tc => {
*/
export const testUndoBlockBug = _tc => {
const doc = new Y.Doc({ gc: false })
const design = doc.getMap()
const design = doc.get()
const undoManager = new Y.UndoManager(design, { captureTimeout: 0 })
const text = new Y.Map()
const text = new Y.Type()
const blocks1 = new Y.Array()
const blocks1block = new Y.Map()
const blocks1 = new Y.Type()
const blocks1block = new Y.Type()
doc.transact(() => {
blocks1block.set('text', '1')
blocks1block.setAttr('text', '1')
blocks1.push([blocks1block])
text.set('blocks', blocks1block)
design.set('text', text)
text.setAttr('blocks', blocks1block)
design.setAttr('text', text)
})
const blocks2 = new Y.Array()
const blocks2block = new Y.Map()
const blocks2 = new Y.Type()
const blocks2block = new Y.Type()
doc.transact(() => {
blocks2block.set('text', '2')
blocks2block.setAttr('text', '2')
blocks2.push([blocks2block])
text.set('blocks', blocks2block)
text.setAttr('blocks', blocks2block)
})
const blocks3 = new Y.Array()
const blocks3block = new Y.Map()
const blocks3 = new Y.Type()
const blocks3block = new Y.Type()
doc.transact(() => {
blocks3block.set('text', '3')
blocks3block.setAttr('text', '3')
blocks3.push([blocks3block])
text.set('blocks', blocks3block)
text.setAttr('blocks', blocks3block)
})
const blocks4 = new Y.Array()
const blocks4block = new Y.Map()
const blocks4 = new Y.Type()
const blocks4block = new Y.Type()
doc.transact(() => {
blocks4block.set('text', '4')
blocks4block.setAttr('text', '4')
blocks4.push([blocks4block])
text.set('blocks', blocks4block)
text.setAttr('blocks', blocks4block)
})
// {"text":{"blocks":{"text":"4"}}}
@@ -650,7 +643,7 @@ export const testUndoBlockBug = _tc => {
undoManager.redo() // {"text":{"blocks":{"text":"2"}}}
undoManager.redo() // {"text":{"blocks":{"text":"3"}}}
undoManager.redo() // {"text":{}}
t.compare(design.toJSON(), { text: { blocks: { text: '4' } } })
t.compare(design.toJSON().attrs, { text: { blocks: { text: '4' } } })
}
/**
@@ -661,10 +654,10 @@ export const testUndoBlockBug = _tc => {
*/
export const testUndoDeleteTextFormat = _tc => {
const doc = new Y.Doc()
const text = doc.getText()
const text = doc.get()
text.insert(0, 'Attack ships on fire off the shoulder of Orion.')
const doc2 = new Y.Doc()
const text2 = doc2.getText()
const text2 = doc2.get()
Y.applyUpdate(doc2, Y.encodeStateAsUpdate(doc))
const undoManager = new Y.UndoManager(text)
@@ -698,16 +691,16 @@ export const testBehaviorOfIgnoreremotemapchangesProperty = _tc => {
const doc2 = new Y.Doc()
doc.on('update', update => Y.applyUpdate(doc2, update, doc))
doc2.on('update', update => Y.applyUpdate(doc, update, doc2))
const map1 = doc.getMap()
const map2 = doc2.getMap()
const map1 = doc.get()
const map2 = doc2.get()
const um1 = new Y.UndoManager(map1, { ignoreRemoteMapChanges: true })
map1.set('x', 1)
map2.set('x', 2)
map1.set('x', 3)
map2.set('x', 4)
map1.setAttr('x', 1)
map2.setAttr('x', 2)
map1.setAttr('x', 3)
map2.setAttr('x', 4)
um1.undo()
t.assert(map1.get('x') === 2)
t.assert(map2.get('x') === 2)
t.assert(map1.getAttr('x') === 2)
t.assert(map2.getAttr('x') === 2)
}
/**
@@ -719,12 +712,12 @@ export const testBehaviorOfIgnoreremotemapchangesProperty = _tc => {
export const testSpecialDeletionCase = _tc => {
const origin = 'undoable'
const doc = new Y.Doc()
const fragment = doc.getXmlFragment()
const fragment = doc.get()
const undoManager = new Y.UndoManager(fragment, { trackedOrigins: new Set([origin]) })
doc.transact(() => {
const e = new Y.XmlElement('test')
e.setAttribute('a', '1')
e.setAttribute('b', '2')
const e = new Y.Type('test')
e.setAttr('a', '1')
e.setAttr('b', '2')
fragment.insert(0, [e])
})
t.compareStrings(fragment.toString(), '<test a="1" b="2"></test>')
@@ -748,26 +741,26 @@ export const testSpecialDeletionCase = _tc => {
export const testUndoDeleteInMap = (tc) => {
const { map0 } = init(tc, { users: 3 })
const undoManager = new Y.UndoManager(map0, { captureTimeout: 0 })
map0.set('a', 'a')
map0.delete('a')
map0.set('a', 'b')
map0.delete('a')
map0.set('a', 'c')
map0.delete('a')
map0.set('a', 'd')
t.compare(map0.toJSON(), { a: 'd' })
map0.setAttr('a', 'a')
map0.deleteAttr('a')
map0.setAttr('a', 'b')
map0.deleteAttr('a')
map0.setAttr('a', 'c')
map0.deleteAttr('a')
map0.setAttr('a', 'd')
t.compare(map0.toJSON().attrs, { a: 'd' })
undoManager.undo()
t.compare(map0.toJSON(), {})
t.compare(map0.toJSON().attrs, {})
undoManager.undo()
t.compare(map0.toJSON(), { a: 'c' })
t.compare(map0.toJSON().attrs, { a: 'c' })
undoManager.undo()
t.compare(map0.toJSON(), {})
t.compare(map0.toJSON().attrs, {})
undoManager.undo()
t.compare(map0.toJSON(), { a: 'b' })
t.compare(map0.toJSON().attrs, { a: 'b' })
undoManager.undo()
t.compare(map0.toJSON(), {})
t.compare(map0.toJSON().attrs, {})
undoManager.undo()
t.compare(map0.toJSON(), { a: 'a' })
t.compare(map0.toJSON().attrs, { a: 'a' })
}
/**
@@ -777,7 +770,7 @@ export const testUndoDeleteInMap = (tc) => {
*/
export const testUndoDoingStackItem = async (_tc) => {
const doc = new Y.Doc()
const text = doc.getText('text')
const text = doc.get('text')
const undoManager = new Y.UndoManager([text])
undoManager.on('stack-item-added', /** @param {any} event */ event => {
event.stackItem.meta.set('str', '42')

View File

@@ -3,7 +3,6 @@ import * as t from 'lib0/testing'
import * as prng from 'lib0/prng'
import * as math from 'lib0/math'
import * as delta from 'lib0/delta'
import * as list from 'lib0/list'
import { createIdMapFromIdSet, noAttributionsManager, TwosetAttributionManager, createAttributionManagerFromSnapshots } from 'yjs/internals'
const { init, compare } = Y
@@ -1215,7 +1214,7 @@ export const testDeltaBug2 = _tc => {
})
ytext.applyDelta(changeEvent)
const d = ytext.getContent()
t.compare(list.toArray(d.children)[40].toJSON(), {
t.compare(d.toJSON().children?.[40], {
type: 'insert',
insert: '\n',
format: {