367 lines
11 KiB
JavaScript
367 lines
11 KiB
JavaScript
import { initArrays, compareUsers, applyRandomTests } from './helper.js'
|
|
import * as Y from '../src/index.js'
|
|
import { test, proxyConsole } from 'cutest'
|
|
import * as random from 'funlib/prng/prng.js'
|
|
|
|
proxyConsole()
|
|
|
|
test('basic map tests', async function map0 (t) {
|
|
let { testConnector, users, map0, map1, map2 } = await initArrays(t, { users: 3 })
|
|
users[2].disconnect()
|
|
|
|
map0.set('number', 1)
|
|
map0.set('string', 'hello Y')
|
|
map0.set('object', { key: { key2: 'value' } })
|
|
map0.set('y-map', new Y.Map())
|
|
let map = map0.get('y-map')
|
|
map.set('y-array', new Y.Array())
|
|
let array = map.get('y-array')
|
|
array.insert(0, [0])
|
|
array.insert(0, [-1])
|
|
|
|
t.assert(map0.get('number') === 1, 'client 0 computed the change (number)')
|
|
t.assert(map0.get('string') === 'hello Y', 'client 0 computed the change (string)')
|
|
t.compare(map0.get('object'), { key: { key2: 'value' } }, 'client 0 computed the change (object)')
|
|
t.assert(map0.get('y-map').get('y-array').get(0) === -1, 'client 0 computed the change (type)')
|
|
|
|
await users[2].connect()
|
|
testConnector.flushAllMessages()
|
|
|
|
t.assert(map1.get('number') === 1, 'client 1 received the update (number)')
|
|
t.assert(map1.get('string') === 'hello Y', 'client 1 received the update (string)')
|
|
t.compare(map1.get('object'), { key: { key2: 'value' } }, 'client 1 received the update (object)')
|
|
t.assert(map1.get('y-map').get('y-array').get(0) === -1, 'client 1 received the update (type)')
|
|
|
|
// compare disconnected user
|
|
t.assert(map2.get('number') === 1, 'client 2 received the update (number) - was disconnected')
|
|
t.assert(map2.get('string') === 'hello Y', 'client 2 received the update (string) - was disconnected')
|
|
t.compare(map2.get('object'), { key: { key2: 'value' } }, 'client 2 received the update (object) - was disconnected')
|
|
t.assert(map2.get('y-map').get('y-array').get(0) === -1, 'client 2 received the update (type) - was disconnected')
|
|
await compareUsers(t, users)
|
|
})
|
|
|
|
test('Basic get&set of Map property (converge via sync)', async function map1 (t) {
|
|
let { testConnector, users, map0 } = await initArrays(t, { users: 2 })
|
|
map0.set('stuff', 'stuffy')
|
|
map0.set('undefined', undefined)
|
|
map0.set('null', null)
|
|
t.compare(map0.get('stuff'), 'stuffy')
|
|
|
|
testConnector.flushAllMessages()
|
|
|
|
for (let user of users) {
|
|
var u = user.define('map', Y.Map)
|
|
t.compare(u.get('stuff'), 'stuffy')
|
|
t.assert(u.get('undefined') === undefined, 'undefined')
|
|
t.compare(u.get('null'), null, 'null')
|
|
}
|
|
await compareUsers(t, users)
|
|
})
|
|
|
|
test('Map can set custom types (Map)', async function map2 (t) {
|
|
let { users, map0 } = await initArrays(t, { users: 2 })
|
|
var map = map0.set('Map', new Y.Map())
|
|
map.set('one', 1)
|
|
map = map0.get('Map')
|
|
t.compare(map.get('one'), 1)
|
|
await compareUsers(t, users)
|
|
})
|
|
|
|
test('Map can set custom types (Map) - get also returns the type', async function map3 (t) {
|
|
let { users, map0 } = await initArrays(t, { users: 2 })
|
|
map0.set('Map', new Y.Map())
|
|
var map = map0.get('Map')
|
|
map.set('one', 1)
|
|
map = map0.get('Map')
|
|
t.compare(map.get('one'), 1)
|
|
await compareUsers(t, users)
|
|
})
|
|
|
|
test('Map can set custom types (Array)', async function map4 (t) {
|
|
let { users, map0 } = await initArrays(t, { users: 2 })
|
|
var array = map0.set('Array', new Y.Array())
|
|
array.insert(0, [1, 2, 3])
|
|
array = map0.get('Array')
|
|
t.compare(array.toArray(), [1, 2, 3])
|
|
await compareUsers(t, users)
|
|
})
|
|
|
|
test('Basic get&set of Map property (converge via update)', async function map5 (t) {
|
|
let { testConnector, users, map0 } = await initArrays(t, { users: 2 })
|
|
map0.set('stuff', 'stuffy')
|
|
t.compare(map0.get('stuff'), 'stuffy')
|
|
|
|
testConnector.flushAllMessages()
|
|
|
|
for (let user of users) {
|
|
var u = user.define('map', Y.Map)
|
|
t.compare(u.get('stuff'), 'stuffy')
|
|
}
|
|
await compareUsers(t, users)
|
|
})
|
|
|
|
test('Basic get&set of Map property (handle conflict)', async function map6 (t) {
|
|
let { testConnector, users, map0, map1 } = await initArrays(t, { users: 3 })
|
|
map0.set('stuff', 'c0')
|
|
map1.set('stuff', 'c1')
|
|
|
|
testConnector.flushAllMessages()
|
|
|
|
for (let user of users) {
|
|
var u = user.define('map', Y.Map)
|
|
t.compare(u.get('stuff'), 'c0')
|
|
}
|
|
await compareUsers(t, users)
|
|
})
|
|
|
|
test('Basic get&set&delete of Map property (handle conflict)', async function map7 (t) {
|
|
let { testConnector, users, map0, map1 } = await initArrays(t, { users: 3 })
|
|
map0.set('stuff', 'c0')
|
|
map0.delete('stuff')
|
|
map1.set('stuff', 'c1')
|
|
testConnector.flushAllMessages()
|
|
for (let user of users) {
|
|
var u = user.define('map', Y.Map)
|
|
t.assert(u.get('stuff') === undefined)
|
|
}
|
|
await compareUsers(t, users)
|
|
})
|
|
|
|
test('Basic get&set of Map property (handle three conflicts)', async function map8 (t) {
|
|
let { testConnector, users, map0, map1, map2 } = await initArrays(t, { users: 3 })
|
|
map0.set('stuff', 'c0')
|
|
map1.set('stuff', 'c1')
|
|
map1.set('stuff', 'c2')
|
|
map2.set('stuff', 'c3')
|
|
testConnector.flushAllMessages()
|
|
for (let user of users) {
|
|
var u = user.define('map', Y.Map)
|
|
t.compare(u.get('stuff'), 'c0')
|
|
}
|
|
await compareUsers(t, users)
|
|
})
|
|
|
|
test('Basic get&set&delete of Map property (handle three conflicts)', async function map9 (t) {
|
|
let { testConnector, users, map0, map1, map2, map3 } = await initArrays(t, { users: 4 })
|
|
map0.set('stuff', 'c0')
|
|
map1.set('stuff', 'c1')
|
|
map1.set('stuff', 'c2')
|
|
map2.set('stuff', 'c3')
|
|
testConnector.flushAllMessages()
|
|
map0.set('stuff', 'deleteme')
|
|
map0.delete('stuff')
|
|
map1.set('stuff', 'c1')
|
|
map2.set('stuff', 'c2')
|
|
map3.set('stuff', 'c3')
|
|
testConnector.flushAllMessages()
|
|
for (let user of users) {
|
|
var u = user.define('map', Y.Map)
|
|
t.assert(u.get('stuff') === undefined)
|
|
}
|
|
await compareUsers(t, users)
|
|
})
|
|
|
|
/* TODO reimplement observePath
|
|
test('observePath properties', async function map10 (t) {
|
|
let { users, map0, map1, map2 } = await initArrays(t, { users: 3 })
|
|
let map
|
|
map0.observePath(['map'], map => {
|
|
if (map != null) {
|
|
map.set('yay', 4)
|
|
}
|
|
})
|
|
map1.set('map', new Y.Map())
|
|
testConnector.flushAllMessages()
|
|
map = map2.get('map')
|
|
t.compare(map.get('yay'), 4)
|
|
await compareUsers(t, users)
|
|
})
|
|
*/
|
|
|
|
test('observe deep properties', async function map11 (t) {
|
|
let { testConnector, users, map1, map2, map3 } = await initArrays(t, { users: 4 })
|
|
var _map1 = map1.set('map', new Y.Map())
|
|
var calls = 0
|
|
var dmapid
|
|
map1.observeDeep(events => {
|
|
events.forEach(event => {
|
|
calls++
|
|
t.assert(event.keysChanged.has('deepmap'))
|
|
t.assert(event.path.length === 1)
|
|
t.assert(event.path[0] === 'map')
|
|
dmapid = event.target.get('deepmap')._id
|
|
})
|
|
})
|
|
testConnector.flushAllMessages()
|
|
var _map3 = map3.get('map')
|
|
_map3.set('deepmap', new Y.Map())
|
|
testConnector.flushAllMessages()
|
|
var _map2 = map2.get('map')
|
|
_map2.set('deepmap', new Y.Map())
|
|
testConnector.flushAllMessages()
|
|
var dmap1 = _map1.get('deepmap')
|
|
var dmap2 = _map2.get('deepmap')
|
|
var dmap3 = _map3.get('deepmap')
|
|
t.assert(calls > 0)
|
|
t.assert(dmap1._id.equals(dmap2._id))
|
|
t.assert(dmap1._id.equals(dmap3._id))
|
|
t.assert(dmap1._id.equals(dmapid))
|
|
await compareUsers(t, users)
|
|
})
|
|
|
|
test('observes using observeDeep', async function map12 (t) {
|
|
let { users, map0 } = await initArrays(t, { users: 2 })
|
|
var pathes = []
|
|
var calls = 0
|
|
map0.observeDeep(events => {
|
|
events.forEach(event => {
|
|
pathes.push(event.path)
|
|
})
|
|
calls++
|
|
})
|
|
map0.set('map', new Y.Map())
|
|
map0.get('map').set('array', new Y.Array())
|
|
map0.get('map').get('array').insert(0, ['content'])
|
|
t.assert(calls === 3)
|
|
t.compare(pathes, [[], ['map'], ['map', 'array']])
|
|
await compareUsers(t, users)
|
|
})
|
|
|
|
/* TODO: Test events in Y.Map
|
|
function compareEvent (t, is, should) {
|
|
for (var key in should) {
|
|
t.assert(should[key] === is[key])
|
|
}
|
|
}
|
|
|
|
test('throws add & update & delete events (with type and primitive content)', async function map13 (t) {
|
|
let { users, map0 } = await initArrays(t, { users: 2 })
|
|
var event
|
|
await flushAll(t, users)
|
|
map0.observe(e => {
|
|
event = e // just put it on event, should be thrown synchronously anyway
|
|
})
|
|
map0.set('stuff', 4)
|
|
compareEvent(t, event, {
|
|
type: 'add',
|
|
object: map0,
|
|
name: 'stuff'
|
|
})
|
|
// update, oldValue is in contents
|
|
map0.set('stuff', new Y.Array())
|
|
compareEvent(t, event, {
|
|
type: 'update',
|
|
object: map0,
|
|
name: 'stuff',
|
|
oldValue: 4
|
|
})
|
|
var replacedArray = map0.get('stuff')
|
|
// update, oldValue is in opContents
|
|
map0.set('stuff', 5)
|
|
var array = event.oldValue
|
|
t.compare(array._model, replacedArray._model)
|
|
// delete
|
|
map0.delete('stuff')
|
|
compareEvent(t, event, {
|
|
type: 'delete',
|
|
name: 'stuff',
|
|
object: map0,
|
|
oldValue: 5
|
|
})
|
|
await compareUsers(t, users)
|
|
})
|
|
*/
|
|
|
|
/* reimplement event.value somehow (probably with ss vector)
|
|
test('event has correct value when setting a primitive on a YMap (same user)', async function map14 (t) {
|
|
let { users, map0 } = await initArrays(t, { users: 3 })
|
|
var event
|
|
await flushAll(t, users)
|
|
map0.observe(e => {
|
|
event = e
|
|
})
|
|
map0.set('stuff', 2)
|
|
t.compare(event.value, event.target.get(event.name))
|
|
await compareUsers(t, users)
|
|
})
|
|
|
|
test('event has correct value when setting a primitive on a YMap (received from another user)', async function map15 (t) {
|
|
let { users, map0, map1 } = await initArrays(t, { users: 3 })
|
|
var event
|
|
await flushAll(t, users)
|
|
map0.observe(e => {
|
|
event = e
|
|
})
|
|
map1.set('stuff', 2)
|
|
await flushAll(t, users)
|
|
t.compare(event.value, event.target.get(event.name))
|
|
await compareUsers(t, users)
|
|
})
|
|
*/
|
|
|
|
var mapTransactions = [
|
|
function set (t, user, prng) {
|
|
let key = random.oneOf(prng, ['one', 'two'])
|
|
var value = random.utf16String(prng)
|
|
user.define('map', Y.Map).set(key, value)
|
|
},
|
|
function setType (t, user, prng) {
|
|
let key = random.oneOf(prng, ['one', 'two'])
|
|
var type = random.oneOf(prng, [new Y.Array(), new Y.Map()])
|
|
user.define('map', Y.Map).set(key, type)
|
|
if (type instanceof Y.Array) {
|
|
type.insert(0, [1, 2, 3, 4])
|
|
} else {
|
|
type.set('deepkey', 'deepvalue')
|
|
}
|
|
},
|
|
function _delete (t, user, prng) {
|
|
let key = random.oneOf(prng, ['one', 'two'])
|
|
user.define('map', Y.Map).delete(key)
|
|
}
|
|
]
|
|
|
|
test('y-map: Random tests (42)', async function randomMap42 (t) {
|
|
await applyRandomTests(t, mapTransactions, 42)
|
|
})
|
|
|
|
test('y-map: Random tests (43)', async function randomMap43 (t) {
|
|
await applyRandomTests(t, mapTransactions, 43)
|
|
})
|
|
|
|
test('y-map: Random tests (44)', async function randomMap44 (t) {
|
|
await applyRandomTests(t, mapTransactions, 44)
|
|
})
|
|
|
|
test('y-map: Random tests (45)', async function randomMap45 (t) {
|
|
await applyRandomTests(t, mapTransactions, 45)
|
|
})
|
|
|
|
test('y-map: Random tests (46)', async function randomMap46 (t) {
|
|
await applyRandomTests(t, mapTransactions, 46)
|
|
})
|
|
|
|
test('y-map: Random tests (47)', async function randomMap47 (t) {
|
|
await applyRandomTests(t, mapTransactions, 47)
|
|
})
|
|
|
|
test('y-map: Random tests (200)', async function randomMap200 (t) {
|
|
await applyRandomTests(t, mapTransactions, 200)
|
|
})
|
|
|
|
test('y-map: Random tests (300)', async function randomMap300 (t) {
|
|
await applyRandomTests(t, mapTransactions, 300)
|
|
})
|
|
|
|
test('y-map: Random tests (500)', async function randomMap500 (t) {
|
|
await applyRandomTests(t, mapTransactions, 500)
|
|
})
|
|
|
|
test('y-map: Random tests (1000)', async function randomMap1000 (t) {
|
|
await applyRandomTests(t, mapTransactions, 1000)
|
|
})
|
|
|
|
test('y-map: Random tests (1800)', async function randomMap1800 (t) {
|
|
await applyRandomTests(t, mapTransactions, 1800)
|
|
})
|