mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-04-24 01:16:15 -04:00
Feat/frontend vitest (#6469)
* Added vitest tests. * Added Settings tests to vitest - not working * Added attributes and attributemap to vitest. * Added more tests. * Also run the vitest tests. * Also run withoutPlugins * Fixed pnpm lock
This commit is contained in:
parent
babfaab4df
commit
c7a2dea4d1
21 changed files with 1092 additions and 552 deletions
|
@ -1,178 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const AttributeMap = require('../../../static/js/AttributeMap');
|
||||
const AttributePool = require('../../../static/js/AttributePool');
|
||||
const attributes = require('../../../static/js/attributes');
|
||||
|
||||
describe('AttributeMap', function () {
|
||||
const attribs = [
|
||||
['foo', 'bar'],
|
||||
['baz', 'bif'],
|
||||
['emptyValue', ''],
|
||||
];
|
||||
let pool;
|
||||
|
||||
const getPoolSize = () => {
|
||||
let n = 0;
|
||||
pool.eachAttrib(() => ++n);
|
||||
return n;
|
||||
};
|
||||
|
||||
beforeEach(async function () {
|
||||
pool = new AttributePool();
|
||||
for (let i = 0; i < attribs.length; ++i) expect(pool.putAttrib(attribs[i])).to.equal(i);
|
||||
});
|
||||
|
||||
it('fromString works', async function () {
|
||||
const got = AttributeMap.fromString('*0*1*2', pool);
|
||||
for (const [k, v] of attribs) expect(got.get(k)).to.equal(v);
|
||||
// Maps iterate in insertion order, so [...got] should be in the same order as attribs.
|
||||
expect(JSON.stringify([...got])).to.equal(JSON.stringify(attribs));
|
||||
});
|
||||
|
||||
describe('set', function () {
|
||||
it('stores the value', async function () {
|
||||
const m = new AttributeMap(pool);
|
||||
expect(m.size).to.equal(0);
|
||||
m.set('k', 'v');
|
||||
expect(m.size).to.equal(1);
|
||||
expect(m.get('k')).to.equal('v');
|
||||
});
|
||||
|
||||
it('reuses attributes in the pool', async function () {
|
||||
expect(getPoolSize()).to.equal(attribs.length);
|
||||
const m = new AttributeMap(pool);
|
||||
const [k0, v0] = attribs[0];
|
||||
m.set(k0, v0);
|
||||
expect(getPoolSize()).to.equal(attribs.length);
|
||||
expect(m.size).to.equal(1);
|
||||
expect(m.toString()).to.equal('*0');
|
||||
});
|
||||
|
||||
it('inserts new attributes into the pool', async function () {
|
||||
const m = new AttributeMap(pool);
|
||||
expect(getPoolSize()).to.equal(attribs.length);
|
||||
m.set('k', 'v');
|
||||
expect(getPoolSize()).to.equal(attribs.length + 1);
|
||||
expect(JSON.stringify(pool.getAttrib(attribs.length))).to.equal(JSON.stringify(['k', 'v']));
|
||||
});
|
||||
|
||||
describe('coerces key and value to string', function () {
|
||||
const testCases = [
|
||||
['object (with toString)', {toString: () => 'obj'}, 'obj'],
|
||||
['undefined', undefined, ''],
|
||||
['null', null, ''],
|
||||
['boolean', true, 'true'],
|
||||
['number', 1, '1'],
|
||||
];
|
||||
for (const [desc, input, want] of testCases) {
|
||||
describe(desc, function () {
|
||||
it('key is coerced to string', async function () {
|
||||
const m = new AttributeMap(pool);
|
||||
m.set(input, 'value');
|
||||
expect(m.get(want)).to.equal('value');
|
||||
});
|
||||
|
||||
it('value is coerced to string', async function () {
|
||||
const m = new AttributeMap(pool);
|
||||
m.set('key', input);
|
||||
expect(m.get('key')).to.equal(want);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it('returns the map', async function () {
|
||||
const m = new AttributeMap(pool);
|
||||
expect(m.set('k', 'v')).to.equal(m);
|
||||
});
|
||||
});
|
||||
|
||||
describe('toString', function () {
|
||||
it('sorts attributes', async function () {
|
||||
const m = new AttributeMap(pool).update(attribs);
|
||||
const got = [...attributes.attribsFromString(m.toString(), pool)];
|
||||
const want = attributes.sort([...attribs]);
|
||||
// Verify that attribs is not already sorted so that this test doesn't accidentally pass.
|
||||
expect(JSON.stringify(want)).to.not.equal(JSON.stringify(attribs));
|
||||
expect(JSON.stringify(got)).to.equal(JSON.stringify(want));
|
||||
});
|
||||
|
||||
it('returns all entries', async function () {
|
||||
const m = new AttributeMap(pool);
|
||||
expect(m.toString()).to.equal('');
|
||||
m.set(...attribs[0]);
|
||||
expect(m.toString()).to.equal('*0');
|
||||
m.delete(attribs[0][0]);
|
||||
expect(m.toString()).to.equal('');
|
||||
m.set(...attribs[1]);
|
||||
expect(m.toString()).to.equal('*1');
|
||||
m.set(attribs[1][0], 'new value');
|
||||
expect(m.toString()).to.equal(attributes.encodeAttribString([attribs.length]));
|
||||
m.set(...attribs[2]);
|
||||
expect(m.toString()).to.equal(attributes.attribsToString(
|
||||
attributes.sort([attribs[2], [attribs[1][0], 'new value']]), pool));
|
||||
});
|
||||
});
|
||||
|
||||
for (const funcName of ['update', 'updateFromString']) {
|
||||
const callUpdateFn = (m, ...args) => {
|
||||
if (funcName === 'updateFromString') {
|
||||
args[0] = attributes.attribsToString(attributes.sort([...args[0]]), pool);
|
||||
}
|
||||
return AttributeMap.prototype[funcName].call(m, ...args);
|
||||
};
|
||||
|
||||
describe(funcName, function () {
|
||||
it('works', async function () {
|
||||
const m = new AttributeMap(pool);
|
||||
m.set(attribs[2][0], 'value to be overwritten');
|
||||
callUpdateFn(m, attribs);
|
||||
for (const [k, v] of attribs) expect(m.get(k)).to.equal(v);
|
||||
expect(m.size).to.equal(attribs.length);
|
||||
const wantStr = attributes.attribsToString(attributes.sort([...attribs]), pool);
|
||||
expect(m.toString()).to.equal(wantStr);
|
||||
callUpdateFn(m, []);
|
||||
expect(m.toString()).to.equal(wantStr);
|
||||
});
|
||||
|
||||
it('inserts new attributes into the pool', async function () {
|
||||
const m = new AttributeMap(pool);
|
||||
callUpdateFn(m, [['k', 'v']]);
|
||||
expect(m.size).to.equal(1);
|
||||
expect(m.get('k')).to.equal('v');
|
||||
expect(getPoolSize()).to.equal(attribs.length + 1);
|
||||
expect(m.toString()).to.equal(attributes.encodeAttribString([attribs.length]));
|
||||
});
|
||||
|
||||
it('returns the map', async function () {
|
||||
const m = new AttributeMap(pool);
|
||||
expect(callUpdateFn(m, [])).to.equal(m);
|
||||
});
|
||||
|
||||
describe('emptyValueIsDelete=false inserts empty values', function () {
|
||||
for (const emptyVal of ['', null, undefined]) {
|
||||
it(emptyVal == null ? String(emptyVal) : JSON.stringify(emptyVal), async function () {
|
||||
const m = new AttributeMap(pool);
|
||||
m.set('k', 'v');
|
||||
callUpdateFn(m, [['k', emptyVal]]);
|
||||
expect(m.size).to.equal(1);
|
||||
expect(m.toString()).to.equal(attributes.attribsToString([['k', '']], pool));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('emptyValueIsDelete=true deletes entries', function () {
|
||||
for (const emptyVal of ['', null, undefined]) {
|
||||
it(emptyVal == null ? String(emptyVal) : JSON.stringify(emptyVal), async function () {
|
||||
const m = new AttributeMap(pool);
|
||||
m.set('k', 'v');
|
||||
callUpdateFn(m, [['k', emptyVal]], true);
|
||||
expect(m.size).to.equal(0);
|
||||
expect(m.toString()).to.equal('');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
|
@ -1,343 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const AttributePool = require('../../../static/js/AttributePool');
|
||||
const attributes = require('../../../static/js/attributes');
|
||||
|
||||
describe('attributes', function () {
|
||||
const attribs = [['foo', 'bar'], ['baz', 'bif']];
|
||||
let pool;
|
||||
|
||||
beforeEach(async function () {
|
||||
pool = new AttributePool();
|
||||
for (let i = 0; i < attribs.length; ++i) expect(pool.putAttrib(attribs[i])).to.equal(i);
|
||||
});
|
||||
|
||||
describe('decodeAttribString', function () {
|
||||
it('is a generator function', async function () {
|
||||
expect(attributes.decodeAttribString).to.be.a((function* () {}).constructor);
|
||||
});
|
||||
|
||||
describe('rejects invalid attribute strings', function () {
|
||||
const testCases = ['x', '*0+1', '*A', '*0$', '*', '0', '*-1'];
|
||||
for (const tc of testCases) {
|
||||
it(JSON.stringify(tc), async function () {
|
||||
expect(() => [...attributes.decodeAttribString(tc)])
|
||||
.to.throwException(/invalid character/);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('accepts valid attribute strings', function () {
|
||||
const testCases = [
|
||||
['', []],
|
||||
['*0', [0]],
|
||||
['*a', [10]],
|
||||
['*z', [35]],
|
||||
['*10', [36]],
|
||||
[
|
||||
'*0*1*2*3*4*5*6*7*8*9*a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*10',
|
||||
[...Array(37).keys()],
|
||||
],
|
||||
];
|
||||
for (const [input, want] of testCases) {
|
||||
it(`${JSON.stringify(input)} -> ${JSON.stringify(want)}`, async function () {
|
||||
const got = [...attributes.decodeAttribString(input)];
|
||||
expect(JSON.stringify(got)).to.equal(JSON.stringify(want));
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('encodeAttribString', function () {
|
||||
describe('accepts any kind of iterable', function () {
|
||||
const testCases = [
|
||||
['generator', (function* () { yield 0; yield 1; })()],
|
||||
['list', [0, 1]],
|
||||
['set', new Set([0, 1])],
|
||||
];
|
||||
for (const [desc, input] of testCases) {
|
||||
it(desc, async function () {
|
||||
expect(attributes.encodeAttribString(input)).to.equal('*0*1');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('rejects invalid inputs', function () {
|
||||
const testCases = [
|
||||
[null, /.*/], // Different browsers may have different error messages.
|
||||
[[-1], /is negative/],
|
||||
[['0'], /not a number/],
|
||||
[[null], /not a number/],
|
||||
[[0.5], /not an integer/],
|
||||
[[{}], /not a number/],
|
||||
[[true], /not a number/],
|
||||
];
|
||||
for (const [input, wantErr] of testCases) {
|
||||
it(JSON.stringify(input), async function () {
|
||||
expect(() => attributes.encodeAttribString(input)).to.throwException(wantErr);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('accepts valid inputs', function () {
|
||||
const testCases = [
|
||||
[[], ''],
|
||||
[[0], '*0'],
|
||||
[[10], '*a'],
|
||||
[[35], '*z'],
|
||||
[[36], '*10'],
|
||||
[
|
||||
[...Array(37).keys()],
|
||||
'*0*1*2*3*4*5*6*7*8*9*a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*10',
|
||||
],
|
||||
];
|
||||
for (const [input, want] of testCases) {
|
||||
it(`${JSON.stringify(input)} -> ${JSON.stringify(want)}`, async function () {
|
||||
expect(attributes.encodeAttribString(input)).to.equal(want);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('attribsFromNums', function () {
|
||||
it('is a generator function', async function () {
|
||||
expect(attributes.attribsFromNums).to.be.a((function* () {}).constructor);
|
||||
});
|
||||
|
||||
describe('accepts any kind of iterable', function () {
|
||||
const testCases = [
|
||||
['generator', (function* () { yield 0; yield 1; })()],
|
||||
['list', [0, 1]],
|
||||
['set', new Set([0, 1])],
|
||||
];
|
||||
|
||||
for (const [desc, input] of testCases) {
|
||||
it(desc, async function () {
|
||||
const gotAttribs = [...attributes.attribsFromNums(input, pool)];
|
||||
expect(JSON.stringify(gotAttribs)).to.equal(JSON.stringify(attribs));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('rejects invalid inputs', function () {
|
||||
const testCases = [
|
||||
[null, /.*/], // Different browsers may have different error messages.
|
||||
[[-1], /is negative/],
|
||||
[['0'], /not a number/],
|
||||
[[null], /not a number/],
|
||||
[[0.5], /not an integer/],
|
||||
[[{}], /not a number/],
|
||||
[[true], /not a number/],
|
||||
[[9999], /does not exist in pool/],
|
||||
];
|
||||
for (const [input, wantErr] of testCases) {
|
||||
it(JSON.stringify(input), async function () {
|
||||
expect(() => [...attributes.attribsFromNums(input, pool)]).to.throwException(wantErr);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('accepts valid inputs', function () {
|
||||
const testCases = [
|
||||
[[], []],
|
||||
[[0], [attribs[0]]],
|
||||
[[1], [attribs[1]]],
|
||||
[[0, 1], [attribs[0], attribs[1]]],
|
||||
[[1, 0], [attribs[1], attribs[0]]],
|
||||
];
|
||||
for (const [input, want] of testCases) {
|
||||
it(`${JSON.stringify(input)} -> ${JSON.stringify(want)}`, async function () {
|
||||
const gotAttribs = [...attributes.attribsFromNums(input, pool)];
|
||||
expect(JSON.stringify(gotAttribs)).to.equal(JSON.stringify(want));
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('attribsToNums', function () {
|
||||
it('is a generator function', async function () {
|
||||
expect(attributes.attribsToNums).to.be.a((function* () {}).constructor);
|
||||
});
|
||||
|
||||
describe('accepts any kind of iterable', function () {
|
||||
const testCases = [
|
||||
['generator', (function* () { yield attribs[0]; yield attribs[1]; })()],
|
||||
['list', [attribs[0], attribs[1]]],
|
||||
['set', new Set([attribs[0], attribs[1]])],
|
||||
];
|
||||
|
||||
for (const [desc, input] of testCases) {
|
||||
it(desc, async function () {
|
||||
const gotNums = [...attributes.attribsToNums(input, pool)];
|
||||
expect(JSON.stringify(gotNums)).to.equal(JSON.stringify([0, 1]));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('rejects invalid inputs', function () {
|
||||
const testCases = [null, [null]];
|
||||
for (const input of testCases) {
|
||||
it(JSON.stringify(input), async function () {
|
||||
expect(() => [...attributes.attribsToNums(input, pool)]).to.throwException();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('reuses existing pool entries', function () {
|
||||
const testCases = [
|
||||
[[], []],
|
||||
[[attribs[0]], [0]],
|
||||
[[attribs[1]], [1]],
|
||||
[[attribs[0], attribs[1]], [0, 1]],
|
||||
[[attribs[1], attribs[0]], [1, 0]],
|
||||
];
|
||||
for (const [input, want] of testCases) {
|
||||
it(`${JSON.stringify(input)} -> ${JSON.stringify(want)}`, async function () {
|
||||
const got = [...attributes.attribsToNums(input, pool)];
|
||||
expect(JSON.stringify(got)).to.equal(JSON.stringify(want));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('inserts new attributes into the pool', function () {
|
||||
const testCases = [
|
||||
[[['k', 'v']], [attribs.length]],
|
||||
[[attribs[0], ['k', 'v']], [0, attribs.length]],
|
||||
[[['k', 'v'], attribs[0]], [attribs.length, 0]],
|
||||
];
|
||||
for (const [input, want] of testCases) {
|
||||
it(`${JSON.stringify(input)} -> ${JSON.stringify(want)}`, async function () {
|
||||
const got = [...attributes.attribsToNums(input, pool)];
|
||||
expect(JSON.stringify(got)).to.equal(JSON.stringify(want));
|
||||
expect(JSON.stringify(pool.getAttrib(attribs.length)))
|
||||
.to.equal(JSON.stringify(['k', 'v']));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('coerces key and value to string', function () {
|
||||
const testCases = [
|
||||
['object (with toString)', {toString: () => 'obj'}, 'obj'],
|
||||
['undefined', undefined, ''],
|
||||
['null', null, ''],
|
||||
['boolean', true, 'true'],
|
||||
['number', 1, '1'],
|
||||
];
|
||||
for (const [desc, inputVal, wantVal] of testCases) {
|
||||
describe(desc, function () {
|
||||
for (const [desc, inputAttribs, wantAttribs] of [
|
||||
['key is coerced to string', [[inputVal, 'value']], [[wantVal, 'value']]],
|
||||
['value is coerced to string', [['key', inputVal]], [['key', wantVal]]],
|
||||
]) {
|
||||
it(desc, async function () {
|
||||
const gotNums = [...attributes.attribsToNums(inputAttribs, pool)];
|
||||
// Each attrib in inputAttribs is expected to be new to the pool.
|
||||
const wantNums = [...Array(attribs.length + 1).keys()].slice(attribs.length);
|
||||
expect(JSON.stringify(gotNums)).to.equal(JSON.stringify(wantNums));
|
||||
const gotAttribs = gotNums.map((n) => pool.getAttrib(n));
|
||||
expect(JSON.stringify(gotAttribs)).to.equal(JSON.stringify(wantAttribs));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('attribsFromString', function () {
|
||||
it('is a generator function', async function () {
|
||||
expect(attributes.attribsFromString).to.be.a((function* () {}).constructor);
|
||||
});
|
||||
|
||||
describe('rejects invalid attribute strings', function () {
|
||||
const testCases = [
|
||||
['x', /invalid character/],
|
||||
['*0+1', /invalid character/],
|
||||
['*A', /invalid character/],
|
||||
['*0$', /invalid character/],
|
||||
['*', /invalid character/],
|
||||
['0', /invalid character/],
|
||||
['*-1', /invalid character/],
|
||||
['*9999', /does not exist in pool/],
|
||||
];
|
||||
for (const [input, wantErr] of testCases) {
|
||||
it(JSON.stringify(input), async function () {
|
||||
expect(() => [...attributes.attribsFromString(input, pool)]).to.throwException(wantErr);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('accepts valid inputs', function () {
|
||||
const testCases = [
|
||||
['', []],
|
||||
['*0', [attribs[0]]],
|
||||
['*1', [attribs[1]]],
|
||||
['*0*1', [attribs[0], attribs[1]]],
|
||||
['*1*0', [attribs[1], attribs[0]]],
|
||||
];
|
||||
for (const [input, want] of testCases) {
|
||||
it(`${JSON.stringify(input)} -> ${JSON.stringify(want)}`, async function () {
|
||||
const gotAttribs = [...attributes.attribsFromString(input, pool)];
|
||||
expect(JSON.stringify(gotAttribs)).to.equal(JSON.stringify(want));
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('attribsToString', function () {
|
||||
describe('accepts any kind of iterable', function () {
|
||||
const testCases = [
|
||||
['generator', (function* () { yield attribs[0]; yield attribs[1]; })()],
|
||||
['list', [attribs[0], attribs[1]]],
|
||||
['set', new Set([attribs[0], attribs[1]])],
|
||||
];
|
||||
|
||||
for (const [desc, input] of testCases) {
|
||||
it(desc, async function () {
|
||||
const got = attributes.attribsToString(input, pool);
|
||||
expect(got).to.equal('*0*1');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('rejects invalid inputs', function () {
|
||||
const testCases = [null, [null]];
|
||||
for (const input of testCases) {
|
||||
it(JSON.stringify(input), async function () {
|
||||
expect(() => attributes.attribsToString(input, pool)).to.throwException();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('reuses existing pool entries', function () {
|
||||
const testCases = [
|
||||
[[], ''],
|
||||
[[attribs[0]], '*0'],
|
||||
[[attribs[1]], '*1'],
|
||||
[[attribs[0], attribs[1]], '*0*1'],
|
||||
[[attribs[1], attribs[0]], '*1*0'],
|
||||
];
|
||||
for (const [input, want] of testCases) {
|
||||
it(`${JSON.stringify(input)} -> ${JSON.stringify(want)}`, async function () {
|
||||
const got = attributes.attribsToString(input, pool);
|
||||
expect(got).to.equal(want);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('inserts new attributes into the pool', function () {
|
||||
const testCases = [
|
||||
[[['k', 'v']], `*${attribs.length}`],
|
||||
[[attribs[0], ['k', 'v']], `*0*${attribs.length}`],
|
||||
[[['k', 'v'], attribs[0]], `*${attribs.length}*0`],
|
||||
];
|
||||
for (const [input, want] of testCases) {
|
||||
it(`${JSON.stringify(input)} -> ${JSON.stringify(want)}`, async function () {
|
||||
const got = attributes.attribsToString(input, pool);
|
||||
expect(got).to.equal(want);
|
||||
expect(JSON.stringify(pool.getAttrib(attribs.length)))
|
||||
.to.equal(JSON.stringify(['k', 'v']));
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
|
@ -4,11 +4,19 @@ const Changeset = require('../../../static/js/Changeset');
|
|||
const {padutils} = require('../../../static/js/pad_utils');
|
||||
const {poolOrArray} = require('../easysync-helper.js');
|
||||
|
||||
import {describe, it, expect} from 'vitest'
|
||||
|
||||
|
||||
describe('easysync-assembler', function () {
|
||||
it('opAssembler', async function () {
|
||||
const x = '-c*3*4+6|3=az*asdf0*1*2*3+1=1-1+1*0+1=1-1+1|c=c-1';
|
||||
const assem = Changeset.opAssembler();
|
||||
for (const op of Changeset.deserializeOps(x)) assem.append(op);
|
||||
var opLength = 0
|
||||
for (const op of Changeset.deserializeOps(x)){
|
||||
console.log(op)
|
||||
assem.append(op);
|
||||
opLength++
|
||||
}
|
||||
expect(assem.toString()).to.equal(x);
|
||||
});
|
||||
|
||||
|
@ -145,14 +153,23 @@ describe('easysync-assembler', function () {
|
|||
next() { const v = this._n.value; this._n = ops.next(); return v; },
|
||||
};
|
||||
const assem = Changeset.smartOpAssembler();
|
||||
assem.append(iter.next());
|
||||
assem.append(iter.next());
|
||||
assem.append(iter.next());
|
||||
var iter1 = iter.next()
|
||||
assem.append(iter1);
|
||||
var iter2 = iter.next()
|
||||
assem.append(iter2);
|
||||
var iter3 = iter.next()
|
||||
assem.append(iter3);
|
||||
console.log(assem.toString());
|
||||
assem.clear();
|
||||
assem.append(iter.next());
|
||||
assem.append(iter.next());
|
||||
console.log(assem.toString());
|
||||
assem.clear();
|
||||
while (iter.hasNext()) assem.append(iter.next());
|
||||
let counter = 0;
|
||||
while (iter.hasNext()) {
|
||||
console.log(counter++)
|
||||
assem.append(iter.next());
|
||||
}
|
||||
assem.endDocument();
|
||||
expect(assem.toString()).to.equal('-1+1*0+1=1-1+1|c=c-1');
|
||||
});
|
|
@ -4,6 +4,8 @@ const Changeset = require('../../../static/js/Changeset');
|
|||
const AttributePool = require('../../../static/js/AttributePool');
|
||||
const {randomMultiline, poolOrArray} = require('../easysync-helper.js');
|
||||
const {padutils} = require('../../../static/js/pad_utils');
|
||||
import {describe, it, expect} from 'vitest'
|
||||
|
||||
|
||||
describe('easysync-other', function () {
|
||||
describe('filter attribute numbers', function () {
|
||||
|
@ -66,7 +68,8 @@ describe('easysync-other', function () {
|
|||
|
||||
it('testMakeSplice', async function () {
|
||||
const t = 'a\nb\nc\n';
|
||||
const t2 = Changeset.applyToText(Changeset.makeSplice(t, 5, 0, 'def'), t);
|
||||
let splice = Changeset.makeSplice(t, 5, 0, 'def')
|
||||
const t2 = Changeset.applyToText(splice, t);
|
||||
expect(t2).to.equal('a\nb\ncdef\n');
|
||||
});
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const SkipList = require('ep_etherpad-lite/static/js/skiplist');
|
||||
|
||||
describe('skiplist.js', function () {
|
||||
it('rejects null keys', async function () {
|
||||
const skiplist = new SkipList();
|
||||
for (const key of [undefined, null]) {
|
||||
expect(() => skiplist.push({key})).to.throwError();
|
||||
}
|
||||
});
|
||||
|
||||
it('rejects duplicate keys', async function () {
|
||||
const skiplist = new SkipList();
|
||||
skiplist.push({key: 'foo'});
|
||||
expect(() => skiplist.push({key: 'foo'})).to.throwError();
|
||||
});
|
||||
|
||||
it('atOffset() returns last entry that touches offset', async function () {
|
||||
const skiplist = new SkipList();
|
||||
const entries = [];
|
||||
let nextId = 0;
|
||||
const makeEntry = (width) => {
|
||||
const entry = {key: `id${nextId++}`, width};
|
||||
entries.push(entry);
|
||||
return entry;
|
||||
};
|
||||
|
||||
skiplist.push(makeEntry(5));
|
||||
expect(skiplist.atOffset(4)).to.be(entries[0]);
|
||||
expect(skiplist.atOffset(5)).to.be(entries[0]);
|
||||
expect(() => skiplist.atOffset(6)).to.throwError();
|
||||
|
||||
skiplist.push(makeEntry(0));
|
||||
expect(skiplist.atOffset(4)).to.be(entries[0]);
|
||||
expect(skiplist.atOffset(5)).to.be(entries[1]);
|
||||
expect(() => skiplist.atOffset(6)).to.throwError();
|
||||
|
||||
skiplist.push(makeEntry(0));
|
||||
expect(skiplist.atOffset(4)).to.be(entries[0]);
|
||||
expect(skiplist.atOffset(5)).to.be(entries[2]);
|
||||
expect(() => skiplist.atOffset(6)).to.throwError();
|
||||
|
||||
skiplist.splice(2, 0, [makeEntry(0)]);
|
||||
expect(skiplist.atOffset(4)).to.be(entries[0]);
|
||||
expect(skiplist.atOffset(5)).to.be(entries[2]);
|
||||
expect(() => skiplist.atOffset(6)).to.throwError();
|
||||
|
||||
skiplist.push(makeEntry(3));
|
||||
expect(skiplist.atOffset(4)).to.be(entries[0]);
|
||||
expect(skiplist.atOffset(5)).to.be(entries[4]);
|
||||
expect(skiplist.atOffset(6)).to.be(entries[4]);
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue