import * as t from 'lib0/testing' import * as d from '../src/utils/IdSet.js' import { compareIdSets, createRandomIdSet, ID } from './testHelper.js' /** * @param {Array<[number, number, number]>} ops */ const simpleConstructIdSet = ops => { const idset = d.createIdSet() ops.forEach(op => { d.addToIdSet(idset, op[0], op[1], op[2]) }) return idset } /** * @param {t.TestCase} _tc */ export const testIdsetMerge = _tc => { t.group('filter out empty items (1))', () => { compareIdSets( simpleConstructIdSet([[0, 1, 0]]), simpleConstructIdSet([]) ) }) t.group('filter out empty items (2))', () => { compareIdSets( simpleConstructIdSet([[0, 1, 0], [0, 2, 0]]), simpleConstructIdSet([]) ) }) t.group('filter out empty items (3 - end))', () => { compareIdSets( simpleConstructIdSet([[0, 1, 1], [0, 2, 0]]), simpleConstructIdSet([[0, 1, 1]]) ) }) t.group('filter out empty items (4 - middle))', () => { compareIdSets( simpleConstructIdSet([[0, 1, 1], [0, 2, 0], [0, 3, 1]]), simpleConstructIdSet([[0, 1, 1], [0, 3, 1]]) ) }) t.group('filter out empty items (5 - beginning))', () => { compareIdSets( simpleConstructIdSet([[0, 1, 0], [0, 2, 1], [0, 3, 1]]), simpleConstructIdSet([[0, 2, 1], [0, 3, 1]]) ) }) t.group('merge of overlapping id ranges', () => { compareIdSets( simpleConstructIdSet([[0, 1, 2], [0, 0, 2]]), simpleConstructIdSet([[0, 0, 3]]) ) }) t.group('construct without hole', () => { compareIdSets( simpleConstructIdSet([[0, 1, 2], [0, 3, 1]]), simpleConstructIdSet([[0, 1, 3]]) ) }) } /** * @param {t.TestCase} _tc */ export const testDiffing = _tc => { t.group('simple case (1))', () => { compareIdSets( d.diffIdSet( simpleConstructIdSet([[0, 1, 1], [0, 3, 1]]), simpleConstructIdSet([[0, 3, 1]]) ), simpleConstructIdSet([[0, 1, 1]]) ) }) t.group('subset left', () => { compareIdSets( d.diffIdSet( simpleConstructIdSet([[0, 1, 3]]), simpleConstructIdSet([[0, 1, 1]]) ), simpleConstructIdSet([[0, 2, 2]]) ) }) t.group('subset right', () => { compareIdSets( d.diffIdSet( simpleConstructIdSet([[0, 1, 3]]), simpleConstructIdSet([[0, 3, 1]]) ), simpleConstructIdSet([[0, 1, 2]]) ) }) t.group('subset middle', () => { compareIdSets( d.diffIdSet( simpleConstructIdSet([[0, 1, 3]]), simpleConstructIdSet([[0, 2, 1]]) ), simpleConstructIdSet([[0, 1, 1], [0, 3, 1]]) ) }) t.group('overlapping left', () => { compareIdSets( d.diffIdSet( simpleConstructIdSet([[0, 1, 3]]), simpleConstructIdSet([[0, 0, 2]]) ), simpleConstructIdSet([[0, 2, 2]]) ) }) t.group('overlapping right', () => { compareIdSets( d.diffIdSet( simpleConstructIdSet([[0, 1, 3]]), simpleConstructIdSet([[0, 3, 5]]) ), simpleConstructIdSet([[0, 1, 2]]) ) }) t.group('overlapping completely', () => { compareIdSets( d.diffIdSet( simpleConstructIdSet([[0, 1, 3]]), simpleConstructIdSet([[0, 0, 5]]) ), simpleConstructIdSet([]) ) }) t.group('overlapping into new range', () => { compareIdSets( d.diffIdSet( simpleConstructIdSet([[0, 1, 3], [0, 5, 2]]), simpleConstructIdSet([[0, 0, 6]]) ), simpleConstructIdSet([[0, 6, 1]]) ) }) } /** * @param {t.TestCase} tc */ export const testRepeatRandomDiffing = tc => { const clients = 4 const clockRange = 100 const ds1 = createRandomIdSet(tc.prng, clients, clockRange) const ds2 = createRandomIdSet(tc.prng, clients, clockRange) const merged = d.mergeIdSets([ds1, ds2]) const e1 = d.diffIdSet(ds1, ds2) const e2 = d.diffIdSet(merged, ds2) compareIdSets(e1, e2) } /** * @param {t.TestCase} tc */ export const testRepeatMergingMultipleIdsets = tc => { const clients = 4 const clockRange = 100 /** * @type {Array} */ const idss = [] for (let i = 0; i < 3; i++) { idss.push(createRandomIdSet(tc.prng, clients, clockRange)) } const merged = d.mergeIdSets(idss) const mergedReverse = d.mergeIdSets(idss.reverse()) compareIdSets(merged, mergedReverse) const composed = d.createIdSet() for (let iclient = 0; iclient < clients; iclient++) { for (let iclock = 0; iclock < clockRange + 42; iclock++) { const mergedHas = merged.has(new ID(iclient, iclock)) const oneHas = idss.some(ids => ids.has(new ID(iclient, iclock))) t.assert(mergedHas === oneHas) if (oneHas) { d.addToIdSet(composed, iclient, iclock, 1) } } } compareIdSets(merged, composed) } /** * @param {t.TestCase} tc */ export const testRepeatRandomDiffing2 = tc => { const clients = 4 const clockRange = 100 const ids1 = createRandomIdSet(tc.prng, clients, clockRange) const ids2 = createRandomIdSet(tc.prng, clients, clockRange) const idsExclude = createRandomIdSet(tc.prng, clients, clockRange) const merged = d.mergeIdSets([ids1, ids2]) const mergedExcluded = d.diffIdSet(merged, idsExclude) const e1 = d.diffIdSet(ids1, idsExclude) const e2 = d.diffIdSet(ids2, idsExclude) const excludedMerged = d.mergeIdSets([e1, e2]) compareIdSets(mergedExcluded, excludedMerged) }