more type fixes and rethinking writeStructs

This commit is contained in:
Kevin Jahns
2019-04-02 23:08:58 +02:00
parent 73c28952c2
commit e23582b1cd
35 changed files with 952 additions and 695 deletions

View File

@@ -6,9 +6,8 @@ import * as array from './y-array.tests.js'
import * as map from './y-map.tests.js'
import * as text from './y-text.tests.js'
import * as xml from './y-xml.tests.js'
import * as perf from './perf.js'
if (isBrowser) {
log.createVConsole(document.body)
}
runTests({ map, array, text, xml, perf })
runTests({ map, array, text, xml })

View File

@@ -1,99 +0,0 @@
import * as t from 'lib0/testing.js'
class Item {
constructor (c) {
this.c = c
}
}
const objectsToCreate = 10000000
export const testItemHoldsAll = tc => {
const items = []
for (let i = 0; i < objectsToCreate; i++) {
switch (i % 3) {
case 0:
items.push(new Item(i))
break
case 1:
items.push(new Item(i + ''))
break
case 2:
items.push(new Item({ x: i }))
break
default:
throw new Error()
}
}
const call = []
items.forEach(item => {
switch (item.c.constructor) {
case Number:
call.push(item.c + '')
break
case String:
call.push(item.c)
break
case Object:
call.push(item.c.x + '')
break
default:
throw new Error()
}
})
}
class CItem { }
class CItemNumber {
constructor (i) {
this.c = i
}
toString () {
return this.c + ''
}
}
class CItemString {
constructor (s) {
this.c = s
}
toString () {
return this.c
}
}
class CItemObject {
constructor (o) {
this.c = o
}
toString () {
return this.c.x
}
}
/*
export const testDifferentItems = tc => {
const items = []
for (let i = 0; i < objectsToCreate; i++) {
switch (i % 3) {
case 0:
items.push(new CItemNumber(i))
break
case 1:
items.push(new CItemString(i + ''))
break
case 2:
items.push(new CItemObject({ x: i }))
break
default:
throw new Error()
}
}
const call = []
items.forEach(item => {
call.push(item.toString())
})
}
*/

View File

@@ -5,7 +5,6 @@ import { createMutex } from 'lib0/mutex.js'
import * as encoding from 'lib0/encoding.js'
import * as decoding from 'lib0/decoding.js'
import * as syncProtocol from 'y-protocols/sync.js'
import { defragmentItemContent } from '../src/utils/defragmentItemContent.js'
/**
* @param {TestYInstance} y
@@ -13,11 +12,9 @@ import { defragmentItemContent } from '../src/utils/defragmentItemContent.js'
*/
const afterTransaction = (y, transaction) => {
y.mMux(() => {
if (transaction.encodedStructsLen > 0) {
const encoder = encoding.createEncoder()
syncProtocol.writeUpdate(encoder, transaction.encodedStructsLen, transaction.encodedStructs)
broadcastMessage(y, encoding.toBuffer(encoder))
}
const encoder = encoding.createEncoder()
syncProtocol.writeUpdate(encoder, transaction.updateMessage)
broadcastMessage(y, encoding.toBuffer(encoder))
})
}
@@ -217,6 +214,7 @@ export class TestConnector {
/**
* @param {t.TestCase} tc
* @param {{users?:number}} conf
* @return {{testConnector:TestConnector,users:Array<TestYInstance>,array0:Y.Array<any>,array1:Y.Array<any>,array2:Y.Array<any>,map0:Y.Map,map1:Y.Map,map2:Y.Map,text0:Y.Text,text1:Y.Text,text2:Y.Text,xml0:YXmlFragment,xml1:YXmlFragment,xml2:YXmlFragment}}
*/
export const init = (tc, { users = 5 } = {}) => {
/**
@@ -231,50 +229,27 @@ export const init = (tc, { users = 5 } = {}) => {
for (let i = 0; i < users; i++) {
const y = testConnector.createY(i)
result.users.push(y)
result['array' + i] = y.define('array', Y.Array)
result['map' + i] = y.define('map', Y.Map)
result['xml' + i] = y.define('xml', Y.XmlElement)
result['text' + i] = y.define('text', Y.Text)
result['array' + i] = y.get('array', Y.Array)
result['map' + i] = y.get('map', Y.Map)
result['xml' + i] = y.get('xml', Y.XmlElement)
result['text' + i] = y.get('text', Y.Text)
}
testConnector.syncAll()
// @ts-ignore
return result
}
/**
* Convert DS to a proper DeleteSet of Map.
*
* @param {Y.Y} y
* @return {Object<number, Array<[number, number, boolean]>>}
* @param {any} constructor
* @param {ID} a
* @param {ID} b
* @param {string} path
* @param {any} next
*/
const getDeleteSet = y => {
/**
* @type {Object<number, Array<[number, number, boolean]>>}
*/
var ds = {}
y.ds.iterate(null, null, n => {
var user = n._id.user
var counter = n._id.clock
var len = n.len
var gc = n.gc
var dv = ds[user]
if (dv === void 0) {
dv = []
ds[user] = dv
}
dv.push([counter, len, gc])
})
return ds
}
const customOSCompare = (constructor, a, b, path, next) => {
switch (constructor) {
case Y.ID:
case Y.RootID:
if (a.equals(b)) {
return true
} else {
return false
}
return compareIDs(a, b)
}
return next(constructor, a, b, path, next)
}

View File

@@ -3,6 +3,9 @@ import * as Y from '../src/index.js'
import * as t from 'lib0/testing.js'
import * as prng from 'lib0/prng.js'
/**
* @param {t.TestCase} tc
*/
export const testDeleteInsert = tc => {
const { users, array0 } = init(tc, { users: 2 })
array0.delete(0, 0)
@@ -16,6 +19,9 @@ export const testDeleteInsert = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testInsertThreeElementsTryRegetProperty = tc => {
const { testConnector, users, array0, array1 } = init(tc, { users: 2 })
array0.insert(0, [1, 2, 3])
@@ -25,6 +31,9 @@ export const testInsertThreeElementsTryRegetProperty = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testConcurrentInsertWithThreeConflicts = tc => {
var { users, array0, array1, array2 } = init(tc, { users: 3 })
array0.insert(0, [0])
@@ -33,6 +42,9 @@ export const testConcurrentInsertWithThreeConflicts = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testConcurrentInsertDeleteWithThreeConflicts = tc => {
const { testConnector, users, array0, array1, array2 } = init(tc, { users: 3 })
array0.insert(0, ['x', 'y', 'z'])
@@ -44,6 +56,9 @@ export const testConcurrentInsertDeleteWithThreeConflicts = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testInsertionsInLateSync = tc => {
const { testConnector, users, array0, array1, array2 } = init(tc, { users: 3 })
array0.insert(0, ['x', 'y'])
@@ -59,6 +74,9 @@ export const testInsertionsInLateSync = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testDisconnectReallyPreventsSendingMessages = tc => {
var { testConnector, users, array0, array1 } = init(tc, { users: 3 })
array0.insert(0, ['x', 'y'])
@@ -74,6 +92,9 @@ export const testDisconnectReallyPreventsSendingMessages = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testDeletionsInLateSync = tc => {
const { testConnector, users, array0, array1 } = init(tc, { users: 2 })
array0.insert(0, ['x', 'y'])
@@ -85,6 +106,9 @@ export const testDeletionsInLateSync = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testInsertThenMergeDeleteOnSync = tc => {
const { testConnector, users, array0, array1 } = init(tc, { users: 2 })
array0.insert(0, ['x', 'y', 'z'])
@@ -105,6 +129,9 @@ const compareEvent = (is, should) => {
}
}
/**
* @param {t.TestCase} tc
*/
export const testInsertAndDeleteEvents = tc => {
const { array0, users } = init(tc, { users: 2 })
let event
@@ -126,6 +153,9 @@ export const testInsertAndDeleteEvents = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testInsertAndDeleteEventsForTypes = tc => {
const { array0, users } = init(tc, { users: 2 })
let event
@@ -143,6 +173,9 @@ export const testInsertAndDeleteEventsForTypes = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testInsertAndDeleteEventsForTypes2 = tc => {
const { array0, users } = init(tc, { users: 2 })
let events = []
@@ -162,6 +195,9 @@ export const testInsertAndDeleteEventsForTypes2 = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testGarbageCollector = tc => {
const { testConnector, users, array0 } = init(tc, { users: 3 })
array0.insert(0, ['x', 'y', 'z'])
@@ -173,6 +209,9 @@ export const testGarbageCollector = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testEventTargetIsSetCorrectlyOnLocal = tc => {
const { array0, users } = init(tc, { users: 3 })
/**
@@ -187,6 +226,9 @@ export const testEventTargetIsSetCorrectlyOnLocal = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testEventTargetIsSetCorrectlyOnRemote = tc => {
const { testConnector, array0, array1, users } = init(tc, { users: 3 })
/**
@@ -205,6 +247,9 @@ export const testEventTargetIsSetCorrectlyOnRemote = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testIteratingArrayContainingTypes = tc => {
const y = new Y.Y()
const arr = y.define('arr', Y.Array)
@@ -276,61 +321,106 @@ const arrayTransactions = [
}
]
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYarrayTests20 = tc => {
applyRandomTests(tc, arrayTransactions, 20)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYarrayTests40 = tc => {
applyRandomTests(tc, arrayTransactions, 40)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYarrayTests42 = tc => {
applyRandomTests(tc, arrayTransactions, 42)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYarrayTests43 = tc => {
applyRandomTests(tc, arrayTransactions, 43)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYarrayTests44 = tc => {
applyRandomTests(tc, arrayTransactions, 44)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYarrayTests45 = tc => {
applyRandomTests(tc, arrayTransactions, 45)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYarrayTests46 = tc => {
applyRandomTests(tc, arrayTransactions, 46)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYarrayTests300 = tc => {
applyRandomTests(tc, arrayTransactions, 300)
}
/* TODO: implement something like difficutly in lib0
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYarrayTests400 = tc => {
t.skip(!t.production)
applyRandomTests(tc, arrayTransactions, 400)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYarrayTests500 = tc => {
t.skip(!t.production)
applyRandomTests(tc, arrayTransactions, 500)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYarrayTests600 = tc => {
t.skip(!t.production)
applyRandomTests(tc, arrayTransactions, 600)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYarrayTests1000 = tc => {
t.skip(!t.production)
applyRandomTests(tc, arrayTransactions, 1000)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYarrayTests1800 = tc => {
t.skip(!t.production)
applyRandomTests(tc, arrayTransactions, 1800)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYarrayTests10000 = tc => {
t.skip(!t.production)
applyRandomTests(tc, arrayTransactions, 10000)
}
*/

View File

@@ -3,6 +3,9 @@ import * as Y from '../src/index.js'
import * as t from 'lib0/testing.js'
import * as prng from 'lib0/prng.js'
/**
* @param {t.TestCase} tc
*/
export const testBasicMapTests = tc => {
const { testConnector, users, map0, map1, map2 } = init(tc, { users: 3 })
users[2].disconnect()
@@ -38,6 +41,9 @@ export const testBasicMapTests = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testGetAndSetOfMapProperty = tc => {
const { testConnector, users, map0 } = init(tc, { users: 2 })
map0.set('stuff', 'stuffy')
@@ -56,6 +62,9 @@ export const testGetAndSetOfMapProperty = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testYmapSetsYmap = tc => {
const { users, map0 } = init(tc, { users: 2 })
const map = map0.set('Map', new Y.Map())
@@ -65,6 +74,9 @@ export const testYmapSetsYmap = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testYmapSetsYarray = tc => {
const { users, map0 } = init(tc, { users: 2 })
const array = map0.set('Array', new Y.Array())
@@ -74,6 +86,9 @@ export const testYmapSetsYarray = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testGetAndSetOfMapPropertySyncs = tc => {
const { testConnector, users, map0 } = init(tc, { users: 2 })
map0.set('stuff', 'stuffy')
@@ -86,6 +101,9 @@ export const testGetAndSetOfMapPropertySyncs = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testGetAndSetOfMapPropertyWithConflict = tc => {
const { testConnector, users, map0, map1 } = init(tc, { users: 3 })
map0.set('stuff', 'c0')
@@ -98,6 +116,9 @@ export const testGetAndSetOfMapPropertyWithConflict = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testGetAndSetAndDeleteOfMapProperty = tc => {
const { testConnector, users, map0, map1 } = init(tc, { users: 3 })
map0.set('stuff', 'c0')
@@ -111,6 +132,9 @@ export const testGetAndSetAndDeleteOfMapProperty = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testGetAndSetOfMapPropertyWithThreeConflicts = tc => {
const { testConnector, users, map0, map1, map2 } = init(tc, { users: 3 })
map0.set('stuff', 'c0')
@@ -125,6 +149,9 @@ export const testGetAndSetOfMapPropertyWithThreeConflicts = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testGetAndSetAndDeleteOfMapPropertyWithThreeConflicts = tc => {
const { testConnector, users, map0, map1, map2, map3 } = init(tc, { users: 4 })
map0.set('stuff', 'c0')
@@ -145,6 +172,9 @@ export const testGetAndSetAndDeleteOfMapPropertyWithThreeConflicts = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testObserveDeepProperties = tc => {
const { testConnector, users, map1, map2, map3 } = init(tc, { users: 4 })
const _map1 = map1.set('map', new Y.Map())
@@ -176,6 +206,9 @@ export const testObserveDeepProperties = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testObserversUsingObservedeep = tc => {
const { users, map0 } = init(tc, { users: 2 })
const pathes = []
@@ -201,6 +234,9 @@ const compareEvent = (t, is, should) => {
}
}
/**
* @param {t.TestCase} tc
*/
export const testThrowsAddAndUpdateAndDeleteEvents = tc => {
const { users, map0 } = init(tc, { users: 2 })
let event
@@ -229,6 +265,9 @@ export const testThrowsAddAndUpdateAndDeleteEvents = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testYmapEventHasCorrectValueWhenSettingAPrimitive = tc => {
const { users, map0 } = init(tc, { users: 3 })
let event
@@ -240,6 +279,9 @@ export const testYmapEventHasCorrectValueWhenSettingAPrimitive = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testYmapEventHasCorrectValueWhenSettingAPrimitiveFromOtherUser = tc => {
const { users, map0, map1, testConnector } = init(tc, { users: 3 })
let event
@@ -274,61 +316,106 @@ const mapTransactions = [
}
]
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYmapTests20 = tc => {
applyRandomTests(tc, mapTransactions, 20)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYmapTests40 = tc => {
applyRandomTests(tc, mapTransactions, 40)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYmapTests42 = tc => {
applyRandomTests(tc, mapTransactions, 42)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYmapTests43 = tc => {
applyRandomTests(tc, mapTransactions, 43)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYmapTests44 = tc => {
applyRandomTests(tc, mapTransactions, 44)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYmapTests45 = tc => {
applyRandomTests(tc, mapTransactions, 45)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYmapTests46 = tc => {
applyRandomTests(tc, mapTransactions, 46)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYmapTests300 = tc => {
applyRandomTests(tc, mapTransactions, 300)
}
/* TODO: implement something like difficutly in lib0
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYmapTests400 = tc => {
t.skip(!t.production)
applyRandomTests(tc, mapTransactions, 400)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYmapTests500 = tc => {
t.skip(!t.production)
applyRandomTests(tc, mapTransactions, 500)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYmapTests600 = tc => {
t.skip(!t.production)
applyRandomTests(tc, mapTransactions, 600)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYmapTests1000 = tc => {
t.skip(!t.production)
applyRandomTests(tc, mapTransactions, 1000)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYmapTests1800 = tc => {
t.skip(!t.production)
applyRandomTests(tc, mapTransactions, 1800)
}
/**
* @param {t.TestCase} tc
*/
export const testRepeatGeneratingYmapTests10000 = tc => {
t.skip(!t.production)
applyRandomTests(tc, mapTransactions, 10000)
}
*/

View File

@@ -1,6 +1,9 @@
import { init, compare } from './testHelper.js'
import * as t from 'lib0/testing.js'
/**
* @param {t.TestCase} tc
*/
export const testBasicInsertAndDelete = tc => {
const { users, text0 } = init(tc, { users: 2 })
let delta
@@ -26,6 +29,9 @@ export const testBasicInsertAndDelete = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testBasicFormat = tc => {
const { users, text0 } = init(tc, { users: 2 })
let delta

View File

@@ -2,6 +2,9 @@ import { init, compare } from './testHelper.js'
import * as Y from '../src/index.js'
import * as t from 'lib0/testing.js'
/**
* @param {t.TestCase} tc
*/
export const testSetProperty = tc => {
const { testConnector, users, xml0, xml1 } = init(tc, { users: 2 })
xml0.setAttribute('height', '10')
@@ -11,6 +14,9 @@ export const testSetProperty = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testEvents = tc => {
const { testConnector, users, xml0, xml1 } = init(tc, { users: 2 })
let event = { attributesChanged: new Set() }
@@ -48,6 +54,9 @@ export const testEvents = tc => {
compare(users)
}
/**
* @param {t.TestCase} tc
*/
export const testTreewalker = tc => {
const { users, xml0 } = init(tc, { users: 3 })
let paragraph1 = new Y.XmlElement('p')