Changeset: Unexport unnecessarily exported functions

These functions aren't used outside of this file.
This commit is contained in:
Richard Hansen 2021-03-21 14:13:50 -04:00
parent 085bc8cbb3
commit 4a65c2c8ff
3 changed files with 75 additions and 64 deletions

View file

@ -43,6 +43,10 @@
* Changes to the `src/static/js/Changeset.js` library: * Changes to the `src/static/js/Changeset.js` library:
* `opIterator()`: The unused start index parameter has been removed, as has * `opIterator()`: The unused start index parameter has been removed, as has
the unused `lastIndex()` method on the returned object. the unused `lastIndex()` method on the returned object.
* Several functions that should have never been public are no longer
exported: `applyZip()`, `assert()`, `clearOp()`, `cloneOp()`, `copyOp()`,
`error()`, `followAttributes()`, `opString()`, `stringOp()`,
`textLinesMutator()`, `toBaseTen()`, `toSplices()`.
### Notable enhancements ### Notable enhancements

View file

@ -35,7 +35,7 @@ const AttributePool = require('./AttributePool');
* *
* @param {string} msg - Just some message * @param {string} msg - Just some message
*/ */
exports.error = (msg) => { const error = (msg) => {
const e = new Error(msg); const e = new Error(msg);
e.easysync = true; e.easysync = true;
throw e; throw e;
@ -49,8 +49,8 @@ exports.error = (msg) => {
* @param {string} msg - error message to include in the exception * @param {string} msg - error message to include in the exception
* @type {(b: boolean, msg: string) => asserts b} * @type {(b: boolean, msg: string) => asserts b}
*/ */
exports.assert = (b, msg) => { const assert = (b, msg) => {
if (!b) exports.error(`Failed assertion: ${msg}`); if (!b) error(`Failed assertion: ${msg}`);
}; };
/** /**
@ -147,7 +147,7 @@ exports.opIterator = (opsStr) => {
const nextRegexMatch = () => { const nextRegexMatch = () => {
const result = regex.exec(opsStr); const result = regex.exec(opsStr);
if (result[0] === '?') { if (result[0] === '?') {
exports.error('Hit error opcode in op stream'); error('Hit error opcode in op stream');
} }
return result; return result;
@ -163,7 +163,7 @@ exports.opIterator = (opsStr) => {
op.chars = exports.parseNum(regexResult[4]); op.chars = exports.parseNum(regexResult[4]);
regexResult = nextRegexMatch(); regexResult = nextRegexMatch();
} else { } else {
exports.clearOp(op); clearOp(op);
} }
return op; return op;
}; };
@ -181,7 +181,7 @@ exports.opIterator = (opsStr) => {
* *
* @param {Op} op - object to clear * @param {Op} op - object to clear
*/ */
exports.clearOp = (op) => { const clearOp = (op) => {
op.opcode = ''; op.opcode = '';
op.chars = 0; op.chars = 0;
op.lines = 0; op.lines = 0;
@ -207,7 +207,7 @@ exports.newOp = (optOpcode) => ({
* @param {Op} op1 - src Op * @param {Op} op1 - src Op
* @param {Op} op2 - dest Op * @param {Op} op2 - dest Op
*/ */
exports.copyOp = (op1, op2) => { const copyOp = (op1, op2) => {
op2.opcode = op1.opcode; op2.opcode = op1.opcode;
op2.chars = op1.chars; op2.chars = op1.chars;
op2.lines = op1.lines; op2.lines = op1.lines;
@ -280,13 +280,13 @@ exports.checkRep = (cs) => {
break; break;
case '-': case '-':
oldPos += o.chars; oldPos += o.chars;
exports.assert(oldPos <= oldLen, `${oldPos} > ${oldLen} in ${cs}`); assert(oldPos <= oldLen, `${oldPos} > ${oldLen} in ${cs}`);
break; break;
case '+': case '+':
{ {
calcNewLen += o.chars; calcNewLen += o.chars;
numInserted += o.chars; numInserted += o.chars;
exports.assert(calcNewLen <= newLen, `${calcNewLen} > ${newLen} in ${cs}`); assert(calcNewLen <= newLen, `${calcNewLen} > ${newLen} in ${cs}`);
break; break;
} }
} }
@ -301,7 +301,7 @@ exports.checkRep = (cs) => {
assem.endDocument(); assem.endDocument();
const normalized = exports.pack(oldLen, calcNewLen, assem.toString(), charBank); const normalized = exports.pack(oldLen, calcNewLen, assem.toString(), charBank);
exports.assert(normalized === cs, 'Invalid changeset (checkRep failed)'); assert(normalized === cs, 'Invalid changeset (checkRep failed)');
return cs; return cs;
}; };
@ -458,7 +458,7 @@ exports.mergingOpAssembler = () => {
} }
} else { } else {
flush(); flush();
exports.copyOp(op, bufOp); copyOp(op, bufOp);
} }
} }
}; };
@ -474,7 +474,7 @@ exports.mergingOpAssembler = () => {
const clear = () => { const clear = () => {
assem.clear(); assem.clear();
exports.clearOp(bufOp); clearOp(bufOp);
}; };
return { return {
append, append,
@ -536,7 +536,7 @@ exports.stringIterator = (str) => {
const getnewLines = () => newLines; const getnewLines = () => newLines;
const assertRemaining = (n) => { const assertRemaining = (n) => {
exports.assert(n <= remaining(), `!(${n} <= ${remaining()})`); assert(n <= remaining(), `!(${n} <= ${remaining()})`);
}; };
const take = (n) => { const take = (n) => {
@ -633,7 +633,7 @@ exports.stringAssembler = () => {
* @param {(string[]|StringArrayLike)} lines - Lines to mutate (in place). * @param {(string[]|StringArrayLike)} lines - Lines to mutate (in place).
* @returns {TextLinesMutator} * @returns {TextLinesMutator}
*/ */
exports.textLinesMutator = (lines) => { const textLinesMutator = (lines) => {
/** /**
* curSplice holds values that will be passed as arguments to lines.splice() to insert, delete, or * curSplice holds values that will be passed as arguments to lines.splice() to insert, delete, or
* change lines: * change lines:
@ -990,7 +990,7 @@ exports.textLinesMutator = (lines) => {
* other out), `opOut.opcode` MUST be set to the empty string. * other out), `opOut.opcode` MUST be set to the empty string.
* @returns {string} the integrated changeset * @returns {string} the integrated changeset
*/ */
exports.applyZip = (in1, in2, func) => { const applyZip = (in1, in2, func) => {
const iter1 = exports.opIterator(in1); const iter1 = exports.opIterator(in1);
const iter2 = exports.opIterator(in2); const iter2 = exports.opIterator(in2);
const assem = exports.smartOpAssembler(); const assem = exports.smartOpAssembler();
@ -1020,7 +1020,7 @@ exports.unpack = (cs) => {
const headerRegex = /Z:([0-9a-z]+)([><])([0-9a-z]+)|/; const headerRegex = /Z:([0-9a-z]+)([><])([0-9a-z]+)|/;
const headerMatch = headerRegex.exec(cs); const headerMatch = headerRegex.exec(cs);
if ((!headerMatch) || (!headerMatch[0])) { if ((!headerMatch) || (!headerMatch[0])) {
exports.error(`Not a exports: ${cs}`); error(`Not a exports: ${cs}`);
} }
const oldLen = exports.parseNum(headerMatch[1]); const oldLen = exports.parseNum(headerMatch[1]);
const changeSign = (headerMatch[2] === '>') ? 1 : -1; const changeSign = (headerMatch[2] === '>') ? 1 : -1;
@ -1064,8 +1064,7 @@ exports.pack = (oldLen, newLen, opsStr, bank) => {
*/ */
exports.applyToText = (cs, str) => { exports.applyToText = (cs, str) => {
const unpacked = exports.unpack(cs); const unpacked = exports.unpack(cs);
exports.assert( assert(str.length === unpacked.oldLen, `mismatched apply: ${str.length} / ${unpacked.oldLen}`);
str.length === unpacked.oldLen, `mismatched apply: ${str.length} / ${unpacked.oldLen}`);
const csIter = exports.opIterator(unpacked.ops); const csIter = exports.opIterator(unpacked.ops);
const bankIter = exports.stringIterator(unpacked.charBank); const bankIter = exports.stringIterator(unpacked.charBank);
const strIter = exports.stringIterator(str); const strIter = exports.stringIterator(str);
@ -1113,7 +1112,7 @@ exports.mutateTextLines = (cs, lines) => {
const unpacked = exports.unpack(cs); const unpacked = exports.unpack(cs);
const csIter = exports.opIterator(unpacked.ops); const csIter = exports.opIterator(unpacked.ops);
const bankIter = exports.stringIterator(unpacked.charBank); const bankIter = exports.stringIterator(unpacked.charBank);
const mut = exports.textLinesMutator(lines); const mut = textLinesMutator(lines);
while (csIter.hasNext()) { while (csIter.hasNext()) {
const op = csIter.next(); const op = csIter.next();
switch (op.opcode) { switch (op.opcode) {
@ -1205,12 +1204,12 @@ exports.composeAttributes = (att1, att2, resultIsMutation, pool) => {
* @param {Op} opOut - Mutated to hold the result of applying `csOp` to `attOp`. * @param {Op} opOut - Mutated to hold the result of applying `csOp` to `attOp`.
* @param {AttributePool} pool - Can be null if definitely not needed. * @param {AttributePool} pool - Can be null if definitely not needed.
*/ */
exports._slicerZipperFunc = (attOp, csOp, opOut, pool) => { const slicerZipperFunc = (attOp, csOp, opOut, pool) => {
if (attOp.opcode === '-') { if (attOp.opcode === '-') {
exports.copyOp(attOp, opOut); copyOp(attOp, opOut);
attOp.opcode = ''; attOp.opcode = '';
} else if (!attOp.opcode) { } else if (!attOp.opcode) {
exports.copyOp(csOp, opOut); copyOp(csOp, opOut);
csOp.opcode = ''; csOp.opcode = '';
} else { } else {
switch (csOp.opcode) { switch (csOp.opcode) {
@ -1247,7 +1246,7 @@ exports._slicerZipperFunc = (attOp, csOp, opOut, pool) => {
case '+': case '+':
{ {
// insert // insert
exports.copyOp(csOp, opOut); copyOp(csOp, opOut);
csOp.opcode = ''; csOp.opcode = '';
break; break;
} }
@ -1281,7 +1280,7 @@ exports._slicerZipperFunc = (attOp, csOp, opOut, pool) => {
} }
case '': case '':
{ {
exports.copyOp(attOp, opOut); copyOp(attOp, opOut);
attOp.opcode = ''; attOp.opcode = '';
break; break;
} }
@ -1300,8 +1299,8 @@ exports._slicerZipperFunc = (attOp, csOp, opOut, pool) => {
exports.applyToAttribution = (cs, astr, pool) => { exports.applyToAttribution = (cs, astr, pool) => {
const unpacked = exports.unpack(cs); const unpacked = exports.unpack(cs);
return exports.applyZip(astr, unpacked.ops, return applyZip(astr, unpacked.ops,
(op1, op2, opOut) => exports._slicerZipperFunc(op1, op2, opOut, pool)); (op1, op2, opOut) => slicerZipperFunc(op1, op2, opOut, pool));
}; };
exports.mutateAttributionLines = (cs, lines, pool) => { exports.mutateAttributionLines = (cs, lines, pool) => {
@ -1310,7 +1309,7 @@ exports.mutateAttributionLines = (cs, lines, pool) => {
const csBank = unpacked.charBank; const csBank = unpacked.charBank;
let csBankIndex = 0; let csBankIndex = 0;
// treat the attribution lines as text lines, mutating a line at a time // treat the attribution lines as text lines, mutating a line at a time
const mut = exports.textLinesMutator(lines); const mut = textLinesMutator(lines);
/** @type {?OpIter} */ /** @type {?OpIter} */
let lineIter = null; let lineIter = null;
@ -1336,7 +1335,7 @@ exports.mutateAttributionLines = (cs, lines, pool) => {
} }
lineAssem.append(op); lineAssem.append(op);
if (op.lines > 0) { if (op.lines > 0) {
exports.assert(op.lines === 1, `Can't have op.lines of ${op.lines} in attribution lines`); assert(op.lines === 1, `Can't have op.lines of ${op.lines} in attribution lines`);
// ship it to the mut // ship it to the mut
mut.insert(lineAssem.toString(), 1); mut.insert(lineAssem.toString(), 1);
lineAssem = null; lineAssem = null;
@ -1360,13 +1359,13 @@ exports.mutateAttributionLines = (cs, lines, pool) => {
} else if (csOp.opcode === '+') { } else if (csOp.opcode === '+') {
if (csOp.lines > 1) { if (csOp.lines > 1) {
const firstLineLen = csBank.indexOf('\n', csBankIndex) + 1 - csBankIndex; const firstLineLen = csBank.indexOf('\n', csBankIndex) + 1 - csBankIndex;
exports.copyOp(csOp, opOut); copyOp(csOp, opOut);
csOp.chars -= firstLineLen; csOp.chars -= firstLineLen;
csOp.lines--; csOp.lines--;
opOut.lines = 1; opOut.lines = 1;
opOut.chars = firstLineLen; opOut.chars = firstLineLen;
} else { } else {
exports.copyOp(csOp, opOut); copyOp(csOp, opOut);
csOp.opcode = ''; csOp.opcode = '';
} }
outputMutOp(opOut); outputMutOp(opOut);
@ -1376,7 +1375,7 @@ exports.mutateAttributionLines = (cs, lines, pool) => {
if ((!attOp.opcode) && isNextMutOp()) { if ((!attOp.opcode) && isNextMutOp()) {
nextMutOp(attOp); nextMutOp(attOp);
} }
exports._slicerZipperFunc(attOp, csOp, opOut, pool); slicerZipperFunc(attOp, csOp, opOut, pool);
if (opOut.opcode) { if (opOut.opcode) {
outputMutOp(opOut); outputMutOp(opOut);
opOut.opcode = ''; opOut.opcode = '';
@ -1384,7 +1383,7 @@ exports.mutateAttributionLines = (cs, lines, pool) => {
} }
} }
exports.assert(!lineAssem, `line assembler not finished:${cs}`); assert(!lineAssem, `line assembler not finished:${cs}`);
mut.close(); mut.close();
}; };
@ -1427,7 +1426,7 @@ exports.splitAttributionLines = (attrOps, text) => {
let numLines = op.lines; let numLines = op.lines;
while (numLines > 1) { while (numLines > 1) {
const newlineEnd = text.indexOf('\n', pos) + 1; const newlineEnd = text.indexOf('\n', pos) + 1;
exports.assert(newlineEnd > 0, 'newlineEnd <= 0 in splitAttributionLines'); assert(newlineEnd > 0, 'newlineEnd <= 0 in splitAttributionLines');
op.chars = newlineEnd - pos; op.chars = newlineEnd - pos;
op.lines = 1; op.lines = 1;
appendOp(op); appendOp(op);
@ -1465,19 +1464,19 @@ exports.compose = (cs1, cs2, pool) => {
const unpacked2 = exports.unpack(cs2); const unpacked2 = exports.unpack(cs2);
const len1 = unpacked1.oldLen; const len1 = unpacked1.oldLen;
const len2 = unpacked1.newLen; const len2 = unpacked1.newLen;
exports.assert(len2 === unpacked2.oldLen, 'mismatched composition of two changesets'); assert(len2 === unpacked2.oldLen, 'mismatched composition of two changesets');
const len3 = unpacked2.newLen; const len3 = unpacked2.newLen;
const bankIter1 = exports.stringIterator(unpacked1.charBank); const bankIter1 = exports.stringIterator(unpacked1.charBank);
const bankIter2 = exports.stringIterator(unpacked2.charBank); const bankIter2 = exports.stringIterator(unpacked2.charBank);
const bankAssem = exports.stringAssembler(); const bankAssem = exports.stringAssembler();
const newOps = exports.applyZip(unpacked1.ops, unpacked2.ops, (op1, op2, opOut) => { const newOps = applyZip(unpacked1.ops, unpacked2.ops, (op1, op2, opOut) => {
const op1code = op1.opcode; const op1code = op1.opcode;
const op2code = op2.opcode; const op2code = op2.opcode;
if (op1code === '+' && op2code === '-') { if (op1code === '+' && op2code === '-') {
bankIter1.skip(Math.min(op1.chars, op2.chars)); bankIter1.skip(Math.min(op1.chars, op2.chars));
} }
exports._slicerZipperFunc(op1, op2, opOut, pool); slicerZipperFunc(op1, op2, opOut, pool);
if (opOut.opcode === '+') { if (opOut.opcode === '+') {
if (op2code === '+') { if (op2code === '+') {
bankAssem.append(bankIter2.take(opOut.chars)); bankAssem.append(bankIter2.take(opOut.chars));
@ -1560,7 +1559,7 @@ exports.makeSplice = (oldFullText, spliceStart, numRemoved, newText, optNewTextA
* @param {string} cs - Changeset * @param {string} cs - Changeset
* @returns {[number, number, string][]} * @returns {[number, number, string][]}
*/ */
exports.toSplices = (cs) => { const toSplices = (cs) => {
const unpacked = exports.unpack(cs); const unpacked = exports.unpack(cs);
/** @type {[number, number, string][]} */ /** @type {[number, number, string][]} */
const splices = []; const splices = [];
@ -1601,7 +1600,7 @@ exports.toSplices = (cs) => {
exports.characterRangeFollow = (cs, startChar, endChar, insertionsAfter) => { exports.characterRangeFollow = (cs, startChar, endChar, insertionsAfter) => {
let newStartChar = startChar; let newStartChar = startChar;
let newEndChar = endChar; let newEndChar = endChar;
const splices = exports.toSplices(cs); const splices = toSplices(cs);
let lengthChangeSoFar = 0; let lengthChangeSoFar = 0;
for (let i = 0; i < splices.length; i++) { for (let i = 0; i < splices.length; i++) {
const splice = splices[i]; const splice = splices[i];
@ -1796,7 +1795,9 @@ exports.cloneAText = (atext) => {
text: atext.text, text: atext.text,
attribs: atext.attribs, attribs: atext.attribs,
}; };
} else { exports.error('atext is null'); } } else {
error('atext is null');
}
}; };
/** /**
@ -2040,7 +2041,7 @@ exports.subattribution = (astr, start, optEnd) => {
csOp.lines++; csOp.lines++;
} }
exports._slicerZipperFunc(attOp, csOp, opOut, null); slicerZipperFunc(attOp, csOp, opOut, null);
if (opOut.opcode) { if (opOut.opcode) {
assem.append(opOut); assem.append(opOut);
opOut.opcode = ''; opOut.opcode = '';
@ -2240,7 +2241,7 @@ exports.follow = (cs1, cs2, reverseInsertOrder, pool) => {
const unpacked2 = exports.unpack(cs2); const unpacked2 = exports.unpack(cs2);
const len1 = unpacked1.oldLen; const len1 = unpacked1.oldLen;
const len2 = unpacked2.oldLen; const len2 = unpacked2.oldLen;
exports.assert(len1 === len2, 'mismatched follow - cannot transform cs1 on top of cs2'); assert(len1 === len2, 'mismatched follow - cannot transform cs1 on top of cs2');
const chars1 = exports.stringIterator(unpacked1.charBank); const chars1 = exports.stringIterator(unpacked1.charBank);
const chars2 = exports.stringIterator(unpacked2.charBank); const chars2 = exports.stringIterator(unpacked2.charBank);
@ -2250,7 +2251,7 @@ exports.follow = (cs1, cs2, reverseInsertOrder, pool) => {
const hasInsertFirst = exports.attributeTester(['insertorder', 'first'], pool); const hasInsertFirst = exports.attributeTester(['insertorder', 'first'], pool);
const newOps = exports.applyZip(unpacked1.ops, unpacked2.ops, (op1, op2, opOut) => { const newOps = applyZip(unpacked1.ops, unpacked2.ops, (op1, op2, opOut) => {
if (op1.opcode === '+' || op2.opcode === '+') { if (op1.opcode === '+' || op2.opcode === '+') {
let whichToDo; let whichToDo;
if (op2.opcode !== '+') { if (op2.opcode !== '+') {
@ -2289,7 +2290,7 @@ exports.follow = (cs1, cs2, reverseInsertOrder, pool) => {
} else { } else {
// whichToDo == 2 // whichToDo == 2
chars2.skip(op2.chars); chars2.skip(op2.chars);
exports.copyOp(op2, opOut); copyOp(op2, opOut);
op2.opcode = ''; op2.opcode = '';
} }
} else if (op1.opcode === '-') { } else if (op1.opcode === '-') {
@ -2308,7 +2309,7 @@ exports.follow = (cs1, cs2, reverseInsertOrder, pool) => {
op2.opcode = ''; op2.opcode = '';
} }
} else if (op2.opcode === '-') { } else if (op2.opcode === '-') {
exports.copyOp(op2, opOut); copyOp(op2, opOut);
if (!op1.opcode) { if (!op1.opcode) {
op2.opcode = ''; op2.opcode = '';
} else if (op2.chars <= op1.chars) { } else if (op2.chars <= op1.chars) {
@ -2328,17 +2329,17 @@ exports.follow = (cs1, cs2, reverseInsertOrder, pool) => {
op1.opcode = ''; op1.opcode = '';
} }
} else if (!op1.opcode) { } else if (!op1.opcode) {
exports.copyOp(op2, opOut); copyOp(op2, opOut);
op2.opcode = ''; op2.opcode = '';
} else if (!op2.opcode) { } else if (!op2.opcode) {
// @NOTE: Critical bugfix for EPL issue #1625. We do not copy op1 here // @NOTE: Critical bugfix for EPL issue #1625. We do not copy op1 here
// in order to prevent attributes from leaking into result changesets. // in order to prevent attributes from leaking into result changesets.
// exports.copyOp(op1, opOut); // copyOp(op1, opOut);
op1.opcode = ''; op1.opcode = '';
} else { } else {
// both keeps // both keeps
opOut.opcode = '='; opOut.opcode = '=';
opOut.attribs = exports.followAttributes(op1.attribs, op2.attribs, pool); opOut.attribs = followAttributes(op1.attribs, op2.attribs, pool);
if (op1.chars <= op2.chars) { if (op1.chars <= op2.chars) {
opOut.chars = op1.chars; opOut.chars = op1.chars;
opOut.lines = op1.lines; opOut.lines = op1.lines;
@ -2374,7 +2375,7 @@ exports.follow = (cs1, cs2, reverseInsertOrder, pool) => {
return exports.pack(oldLen, newLen, newOps, unpacked2.charBank); return exports.pack(oldLen, newLen, newOps, unpacked2.charBank);
}; };
exports.followAttributes = (att1, att2, pool) => { const followAttributes = (att1, att2, pool) => {
// The merge of two sets of attribute changes to the same text // The merge of two sets of attribute changes to the same text
// takes the lexically-earlier value if there are two values // takes the lexically-earlier value if there are two values
// for the same key. Otherwise, all key/value changes from // for the same key. Otherwise, all key/value changes from
@ -2416,19 +2417,19 @@ exports.composeWithDeletions = (cs1, cs2, pool) => {
const unpacked2 = exports.unpack(cs2); const unpacked2 = exports.unpack(cs2);
const len1 = unpacked1.oldLen; const len1 = unpacked1.oldLen;
const len2 = unpacked1.newLen; const len2 = unpacked1.newLen;
exports.assert(len2 === unpacked2.oldLen, 'mismatched composition of two changesets'); assert(len2 === unpacked2.oldLen, 'mismatched composition of two changesets');
const len3 = unpacked2.newLen; const len3 = unpacked2.newLen;
const bankIter1 = exports.stringIterator(unpacked1.charBank); const bankIter1 = exports.stringIterator(unpacked1.charBank);
const bankIter2 = exports.stringIterator(unpacked2.charBank); const bankIter2 = exports.stringIterator(unpacked2.charBank);
const bankAssem = exports.stringAssembler(); const bankAssem = exports.stringAssembler();
const newOps = exports.applyZip(unpacked1.ops, unpacked2.ops, (op1, op2, opOut) => { const newOps = applyZip(unpacked1.ops, unpacked2.ops, (op1, op2, opOut) => {
const op1code = op1.opcode; const op1code = op1.opcode;
const op2code = op2.opcode; const op2code = op2.opcode;
if (op1code === '+' && op2code === '-') { if (op1code === '+' && op2code === '-') {
bankIter1.skip(Math.min(op1.chars, op2.chars)); bankIter1.skip(Math.min(op1.chars, op2.chars));
} }
exports._slicerZipperFuncWithDeletions(op1, op2, opOut, pool); slicerZipperFuncWithDeletions(op1, op2, opOut, pool);
if (opOut.opcode === '+') { if (opOut.opcode === '+') {
if (op2code === '+') { if (op2code === '+') {
bankAssem.append(bankIter2.take(opOut.chars)); bankAssem.append(bankIter2.take(opOut.chars));
@ -2441,19 +2442,19 @@ exports.composeWithDeletions = (cs1, cs2, pool) => {
return exports.pack(len1, len3, newOps, bankAssem.toString()); return exports.pack(len1, len3, newOps, bankAssem.toString());
}; };
// This function is 95% like _slicerZipperFunc, we just changed two lines to // This function is 95% like slicerZipperFunc, we just changed two lines to
// ensure it merges the attribs of deletions properly. // ensure it merges the attribs of deletions properly.
// This is necassary for correct paddiff. But to ensure these changes doesn't // This is necassary for correct paddiff. But to ensure these changes doesn't
// affect anything else, we've created a seperate function only used for paddiffs // affect anything else, we've created a seperate function only used for paddiffs
exports._slicerZipperFuncWithDeletions = (attOp, csOp, opOut, pool) => { const slicerZipperFuncWithDeletions = (attOp, csOp, opOut, pool) => {
// attOp is the op from the sequence that is being operated on, either an // attOp is the op from the sequence that is being operated on, either an
// attribution string or the earlier of two exportss being composed. // attribution string or the earlier of two exportss being composed.
// pool can be null if definitely not needed. // pool can be null if definitely not needed.
if (attOp.opcode === '-') { if (attOp.opcode === '-') {
exports.copyOp(attOp, opOut); copyOp(attOp, opOut);
attOp.opcode = ''; attOp.opcode = '';
} else if (!attOp.opcode) { } else if (!attOp.opcode) {
exports.copyOp(csOp, opOut); copyOp(csOp, opOut);
csOp.opcode = ''; csOp.opcode = '';
} else { } else {
switch (csOp.opcode) { switch (csOp.opcode) {
@ -2490,7 +2491,7 @@ exports._slicerZipperFuncWithDeletions = (attOp, csOp, opOut, pool) => {
case '+': case '+':
{ {
// insert // insert
exports.copyOp(csOp, opOut); copyOp(csOp, opOut);
csOp.opcode = ''; csOp.opcode = '';
break; break;
} }
@ -2524,10 +2525,16 @@ exports._slicerZipperFuncWithDeletions = (attOp, csOp, opOut, pool) => {
} }
case '': case '':
{ {
exports.copyOp(attOp, opOut); copyOp(attOp, opOut);
attOp.opcode = ''; attOp.opcode = '';
break; break;
} }
} }
} }
}; };
exports.exportedForTestingOnly = {
followAttributes,
textLinesMutator,
toSplices,
};

View file

@ -92,7 +92,7 @@ describe('easysync', function () {
const runMutationTest = (testId, origLines, muts, correct) => { const runMutationTest = (testId, origLines, muts, correct) => {
it(`runMutationTest#${testId}`, async function () { it(`runMutationTest#${testId}`, async function () {
let lines = origLines.slice(); let lines = origLines.slice();
const mu = Changeset.textLinesMutator(lines); const mu = Changeset.exportedForTestingOnly.textLinesMutator(lines);
applyMutations(mu, muts); applyMutations(mu, muts);
mu.close(); mu.close();
expect(lines).to.eql(correct); expect(lines).to.eql(correct);
@ -211,7 +211,7 @@ describe('easysync', function () {
const lines = ['1\n', '2\n', '3\n', '4\n']; const lines = ['1\n', '2\n', '3\n', '4\n'];
let mu; let mu;
mu = Changeset.textLinesMutator(lines); mu = Changeset.exportedForTestingOnly.textLinesMutator(lines);
expect(mu.hasMore()).to.be(true); expect(mu.hasMore()).to.be(true);
mu.skip(8, 4); mu.skip(8, 4);
expect(mu.hasMore()).to.be(false); expect(mu.hasMore()).to.be(false);
@ -219,7 +219,7 @@ describe('easysync', function () {
expect(mu.hasMore()).to.be(false); expect(mu.hasMore()).to.be(false);
// still 1,2,3,4 // still 1,2,3,4
mu = Changeset.textLinesMutator(lines); mu = Changeset.exportedForTestingOnly.textLinesMutator(lines);
expect(mu.hasMore()).to.be(true); expect(mu.hasMore()).to.be(true);
mu.remove(2, 1); mu.remove(2, 1);
expect(mu.hasMore()).to.be(true); expect(mu.hasMore()).to.be(true);
@ -235,7 +235,7 @@ describe('easysync', function () {
expect(mu.hasMore()).to.be(false); expect(mu.hasMore()).to.be(false);
// 2,3,4,5 now // 2,3,4,5 now
mu = Changeset.textLinesMutator(lines); mu = Changeset.exportedForTestingOnly.textLinesMutator(lines);
expect(mu.hasMore()).to.be(true); expect(mu.hasMore()).to.be(true);
mu.remove(6, 3); mu.remove(6, 3);
expect(mu.hasMore()).to.be(true); expect(mu.hasMore()).to.be(true);
@ -610,8 +610,8 @@ describe('easysync', function () {
const testFollow = (a, b, afb, bfa, merge) => { const testFollow = (a, b, afb, bfa, merge) => {
it(`testFollow manual #${++n}`, async function () { it(`testFollow manual #${++n}`, async function () {
expect(Changeset.followAttributes(a, b, p)).to.equal(afb); expect(Changeset.exportedForTestingOnly.followAttributes(a, b, p)).to.equal(afb);
expect(Changeset.followAttributes(b, a, p)).to.equal(bfa); expect(Changeset.exportedForTestingOnly.followAttributes(b, a, p)).to.equal(bfa);
expect(Changeset.composeAttributes(a, afb, true, p)).to.equal(merge); expect(Changeset.composeAttributes(a, afb, true, p)).to.equal(merge);
expect(Changeset.composeAttributes(b, bfa, true, p)).to.equal(merge); expect(Changeset.composeAttributes(b, bfa, true, p)).to.equal(merge);
}); });
@ -701,7 +701,7 @@ describe('easysync', function () {
[5, 8, '123456789'], [5, 8, '123456789'],
[9, 17, 'abcdefghijk'], [9, 17, 'abcdefghijk'],
]; ];
expect(Changeset.toSplices(cs)).to.eql(correctSplices); expect(Changeset.exportedForTestingOnly.toSplices(cs)).to.eql(correctSplices);
}); });
const testCharacterRangeFollow = (testId, cs, oldRange, insertionsAfter, correctNewRange) => { const testCharacterRangeFollow = (testId, cs, oldRange, insertionsAfter, correctNewRange) => {