diff --git a/src/types/AbstractType.js b/src/types/AbstractType.js index a4e32afc..bacf96c1 100644 --- a/src/types/AbstractType.js +++ b/src/types/AbstractType.js @@ -679,6 +679,8 @@ export const typeListInsertGenericsAfter = (transaction, parent, referenceItem, packJsonContent() } +const lengthExceeded = error.create('Length exceeded!') + /** * @param {Transaction} transaction * @param {AbstractType} parent @@ -689,6 +691,9 @@ export const typeListInsertGenericsAfter = (transaction, parent, referenceItem, * @function */ export const typeListInsertGenerics = (transaction, parent, index, content) => { + if (index > parent._length) { + throw lengthExceeded + } if (index === 0) { if (parent._searchMarker) { updateMarkerChanges(parent._searchMarker, index, content.length) @@ -766,7 +771,7 @@ export const typeListDelete = (transaction, parent, index, length) => { n = n.right } if (length > 0) { - throw error.create('array length exceeded') + throw lengthExceeded } if (parent._searchMarker) { updateMarkerChanges(parent._searchMarker, startIndex, -startLength + length /* in case we remove the above exception */) diff --git a/src/types/YXmlElement.js b/src/types/YXmlElement.js index a0369c92..452841ac 100644 --- a/src/types/YXmlElement.js +++ b/src/types/YXmlElement.js @@ -169,7 +169,7 @@ export class YXmlElement extends YXmlFragment { * * @public */ - hasAttribute (attributeName) { + hasAttribute (attributeName) { return /** @type {any} */ (typeMapHas(this, attributeName)) } diff --git a/tests/y-array.tests.js b/tests/y-array.tests.js index 23931f4d..8c70aa64 100644 --- a/tests/y-array.tests.js +++ b/tests/y-array.tests.js @@ -61,6 +61,49 @@ export const testLengthIssue = tc => { t.assert(arr.length === arr.toArray().length) } +/** + * Debugging yjs#314 + * + * @param {t.TestCase} tc + */ +export const testLengthIssue2 = tc => { + const doc = new Y.Doc() + const next = doc.getArray() + doc.transact(() => { + next.insert(0, ['group2']) + }) + doc.transact(() => { + next.insert(1, ['rectangle3']) + }) + doc.transact(() => { + next.delete(0) + next.insert(0, ['rectangle3']) + }) + next.delete(1) + doc.transact(() => { + next.insert(1, ['ellipse4']) + }) + doc.transact(() => { + next.insert(2, ['ellipse3']) + }) + doc.transact(() => { + next.insert(3, ['ellipse2']) + }) + doc.transact(() => { + doc.transact(() => { + t.fails(() => { + next.insert(5, ['rectangle2']) + }) + next.insert(4, ['rectangle2']) + }) + doc.transact(() => { + // this should not throw an error message + next.delete(4) + }) + }) + console.log(next.toArray()) +} + /** * @param {t.TestCase} tc */ diff --git a/tests/y-xml.tests.js b/tests/y-xml.tests.js index da460c70..e68b5489 100644 --- a/tests/y-xml.tests.js +++ b/tests/y-xml.tests.js @@ -18,7 +18,7 @@ export const testSetProperty = tc => { /** * @param {t.TestCase} tc */ - export const testHasProperty = tc => { +export const testHasProperty = tc => { const { testConnector, users, xml0, xml1 } = init(tc, { users: 2 }) xml0.setAttribute('height', '10') t.assert(xml0.hasAttribute('height'), 'Simple set+has works')