@fluidframework/merge-tree 2.20.0 → 2.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +0 -1
- package/CHANGELOG.md +8 -0
- package/README.md +1 -0
- package/dist/attributionCollection.js +5 -7
- package/dist/attributionCollection.js.map +1 -1
- package/dist/localReference.js +6 -8
- package/dist/localReference.js.map +1 -1
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +69 -34
- package/dist/mergeTree.js.map +1 -1
- package/dist/mergeTreeNodes.d.ts +15 -4
- package/dist/mergeTreeNodes.d.ts.map +1 -1
- package/dist/mergeTreeNodes.js +1 -1
- package/dist/mergeTreeNodes.js.map +1 -1
- package/dist/partialLengths.d.ts +114 -144
- package/dist/partialLengths.d.ts.map +1 -1
- package/dist/partialLengths.js +431 -525
- package/dist/partialLengths.js.map +1 -1
- package/dist/perspective.d.ts +10 -1
- package/dist/perspective.d.ts.map +1 -1
- package/dist/perspective.js +10 -1
- package/dist/perspective.js.map +1 -1
- package/dist/properties.d.ts.map +1 -1
- package/dist/properties.js +2 -3
- package/dist/properties.js.map +1 -1
- package/dist/revertibles.js +3 -3
- package/dist/revertibles.js.map +1 -1
- package/dist/segmentInfos.d.ts +3 -0
- package/dist/segmentInfos.d.ts.map +1 -1
- package/dist/segmentInfos.js.map +1 -1
- package/dist/segmentPropertiesManager.js +3 -3
- package/dist/segmentPropertiesManager.js.map +1 -1
- package/dist/snapshotLoader.js +2 -2
- package/dist/snapshotLoader.js.map +1 -1
- package/dist/sortedSegmentSet.d.ts +5 -3
- package/dist/sortedSegmentSet.d.ts.map +1 -1
- package/dist/sortedSegmentSet.js +33 -41
- package/dist/sortedSegmentSet.js.map +1 -1
- package/dist/sortedSet.d.ts +20 -3
- package/dist/sortedSet.d.ts.map +1 -1
- package/dist/sortedSet.js +23 -14
- package/dist/sortedSet.js.map +1 -1
- package/dist/test/Snapshot.perf.spec.js +1 -1
- package/dist/test/Snapshot.perf.spec.js.map +1 -1
- package/dist/test/client.applyMsg.spec.js +20 -0
- package/dist/test/client.applyMsg.spec.js.map +1 -1
- package/dist/test/client.applyStashedOpFarm.spec.js +1 -1
- package/dist/test/client.applyStashedOpFarm.spec.js.map +1 -1
- package/dist/test/client.attributionFarm.spec.js +1 -1
- package/dist/test/client.attributionFarm.spec.js.map +1 -1
- package/dist/test/client.localReference.spec.js +48 -0
- package/dist/test/client.localReference.spec.js.map +1 -1
- package/dist/test/client.obliterateFarm.spec.d.ts +12 -0
- package/dist/test/client.obliterateFarm.spec.d.ts.map +1 -0
- package/dist/test/client.obliterateFarm.spec.js +89 -0
- package/dist/test/client.obliterateFarm.spec.js.map +1 -0
- package/dist/test/client.reconnectFarm.spec.js +1 -1
- package/dist/test/client.reconnectFarm.spec.js.map +1 -1
- package/dist/test/client.searchForMarker.spec.js +2 -2
- package/dist/test/client.searchForMarker.spec.js.map +1 -1
- package/dist/test/mergeTreeOperationRunner.d.ts +7 -2
- package/dist/test/mergeTreeOperationRunner.d.ts.map +1 -1
- package/dist/test/mergeTreeOperationRunner.js +31 -14
- package/dist/test/mergeTreeOperationRunner.js.map +1 -1
- package/dist/test/obliterate.concurrent.spec.js +45 -1
- package/dist/test/obliterate.concurrent.spec.js.map +1 -1
- package/dist/test/obliterate.rangeExpansion.spec.js +81 -5
- package/dist/test/obliterate.rangeExpansion.spec.js.map +1 -1
- package/dist/test/obliterate.spec.js +3 -3
- package/dist/test/obliterate.spec.js.map +1 -1
- package/dist/test/obliterateOperations.d.ts +15 -0
- package/dist/test/obliterateOperations.d.ts.map +1 -0
- package/dist/test/obliterateOperations.js +132 -0
- package/dist/test/obliterateOperations.js.map +1 -0
- package/dist/test/partialSyncHelper.d.ts +42 -0
- package/dist/test/partialSyncHelper.d.ts.map +1 -0
- package/dist/test/partialSyncHelper.js +96 -0
- package/dist/test/partialSyncHelper.js.map +1 -0
- package/dist/test/revertibles.spec.js +3 -3
- package/dist/test/revertibles.spec.js.map +1 -1
- package/dist/test/sortedSegmentSet.spec.js +21 -0
- package/dist/test/sortedSegmentSet.spec.js.map +1 -1
- package/dist/test/testClient.d.ts +1 -1
- package/dist/test/testClient.d.ts.map +1 -1
- package/dist/test/testClient.js +1 -0
- package/dist/test/testClient.js.map +1 -1
- package/dist/test/testUtils.js +2 -2
- package/dist/test/testUtils.js.map +1 -1
- package/lib/attributionCollection.js +5 -7
- package/lib/attributionCollection.js.map +1 -1
- package/lib/localReference.js +6 -8
- package/lib/localReference.js.map +1 -1
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +69 -34
- package/lib/mergeTree.js.map +1 -1
- package/lib/mergeTreeNodes.d.ts +15 -4
- package/lib/mergeTreeNodes.d.ts.map +1 -1
- package/lib/mergeTreeNodes.js +1 -1
- package/lib/mergeTreeNodes.js.map +1 -1
- package/lib/partialLengths.d.ts +114 -144
- package/lib/partialLengths.d.ts.map +1 -1
- package/lib/partialLengths.js +432 -525
- package/lib/partialLengths.js.map +1 -1
- package/lib/perspective.d.ts +10 -1
- package/lib/perspective.d.ts.map +1 -1
- package/lib/perspective.js +10 -1
- package/lib/perspective.js.map +1 -1
- package/lib/properties.d.ts.map +1 -1
- package/lib/properties.js +2 -3
- package/lib/properties.js.map +1 -1
- package/lib/revertibles.js +3 -3
- package/lib/revertibles.js.map +1 -1
- package/lib/segmentInfos.d.ts +3 -0
- package/lib/segmentInfos.d.ts.map +1 -1
- package/lib/segmentInfos.js.map +1 -1
- package/lib/segmentPropertiesManager.js +3 -3
- package/lib/segmentPropertiesManager.js.map +1 -1
- package/lib/snapshotLoader.js +2 -2
- package/lib/snapshotLoader.js.map +1 -1
- package/lib/sortedSegmentSet.d.ts +5 -3
- package/lib/sortedSegmentSet.d.ts.map +1 -1
- package/lib/sortedSegmentSet.js +33 -41
- package/lib/sortedSegmentSet.js.map +1 -1
- package/lib/sortedSet.d.ts +20 -3
- package/lib/sortedSet.d.ts.map +1 -1
- package/lib/sortedSet.js +23 -14
- package/lib/sortedSet.js.map +1 -1
- package/lib/test/Snapshot.perf.spec.js +1 -1
- package/lib/test/Snapshot.perf.spec.js.map +1 -1
- package/lib/test/client.applyMsg.spec.js +20 -0
- package/lib/test/client.applyMsg.spec.js.map +1 -1
- package/lib/test/client.applyStashedOpFarm.spec.js +1 -1
- package/lib/test/client.applyStashedOpFarm.spec.js.map +1 -1
- package/lib/test/client.attributionFarm.spec.js +1 -1
- package/lib/test/client.attributionFarm.spec.js.map +1 -1
- package/lib/test/client.localReference.spec.js +48 -0
- package/lib/test/client.localReference.spec.js.map +1 -1
- package/lib/test/client.obliterateFarm.spec.d.ts +12 -0
- package/lib/test/client.obliterateFarm.spec.d.ts.map +1 -0
- package/lib/test/client.obliterateFarm.spec.js +88 -0
- package/lib/test/client.obliterateFarm.spec.js.map +1 -0
- package/lib/test/client.reconnectFarm.spec.js +1 -1
- package/lib/test/client.reconnectFarm.spec.js.map +1 -1
- package/lib/test/client.searchForMarker.spec.js +2 -2
- package/lib/test/client.searchForMarker.spec.js.map +1 -1
- package/lib/test/mergeTreeOperationRunner.d.ts +7 -2
- package/lib/test/mergeTreeOperationRunner.d.ts.map +1 -1
- package/lib/test/mergeTreeOperationRunner.js +31 -14
- package/lib/test/mergeTreeOperationRunner.js.map +1 -1
- package/lib/test/obliterate.concurrent.spec.js +45 -1
- package/lib/test/obliterate.concurrent.spec.js.map +1 -1
- package/lib/test/obliterate.rangeExpansion.spec.js +81 -5
- package/lib/test/obliterate.rangeExpansion.spec.js.map +1 -1
- package/lib/test/obliterate.spec.js +3 -3
- package/lib/test/obliterate.spec.js.map +1 -1
- package/lib/test/obliterateOperations.d.ts +15 -0
- package/lib/test/obliterateOperations.d.ts.map +1 -0
- package/lib/test/obliterateOperations.js +123 -0
- package/lib/test/obliterateOperations.js.map +1 -0
- package/lib/test/partialSyncHelper.d.ts +42 -0
- package/lib/test/partialSyncHelper.d.ts.map +1 -0
- package/lib/test/partialSyncHelper.js +92 -0
- package/lib/test/partialSyncHelper.js.map +1 -0
- package/lib/test/revertibles.spec.js +3 -3
- package/lib/test/revertibles.spec.js.map +1 -1
- package/lib/test/sortedSegmentSet.spec.js +21 -0
- package/lib/test/sortedSegmentSet.spec.js.map +1 -1
- package/lib/test/testClient.d.ts +1 -1
- package/lib/test/testClient.d.ts.map +1 -1
- package/lib/test/testClient.js +1 -0
- package/lib/test/testClient.js.map +1 -1
- package/lib/test/testUtils.js +2 -2
- package/lib/test/testUtils.js.map +1 -1
- package/package.json +21 -79
- package/src/mergeTree.ts +80 -28
- package/src/mergeTreeNodes.ts +15 -4
- package/src/partialLengths.ts +559 -776
- package/src/perspective.ts +10 -1
- package/src/properties.ts +2 -3
- package/src/segmentInfos.ts +3 -0
- package/src/snapshotLoader.ts +1 -1
- package/src/sortedSegmentSet.ts +41 -50
- package/src/sortedSet.ts +32 -16
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import { strict as assert } from "node:assert";
|
|
6
|
+
import { TestClientLogger, createClientsAtInitialState } from "./testClientLogger.js";
|
|
7
|
+
const ClientIds = ["A", "B", "C", "D"];
|
|
8
|
+
/**
|
|
9
|
+
* Like `ReconnectHelper`, but:
|
|
10
|
+
* - does not support reconnecting clients
|
|
11
|
+
* - supports advancing only some clients to a given sequence number (not all clients must be synchronized at the same time).
|
|
12
|
+
*
|
|
13
|
+
* This allows testing sequences of operations where clients have varying refSeqs, rather than having all clients advance refSeq
|
|
14
|
+
* in lockstep.
|
|
15
|
+
*/
|
|
16
|
+
export class PartialSyncTestHelper {
|
|
17
|
+
idxFromName(name) {
|
|
18
|
+
return (name.codePointAt(0) ?? 0) - ("A".codePointAt(0) ?? 0);
|
|
19
|
+
}
|
|
20
|
+
constructor(options = {}) {
|
|
21
|
+
this.ops = [];
|
|
22
|
+
this.clientToLastAppliedSeq = new Map();
|
|
23
|
+
this.seq = 0;
|
|
24
|
+
this.clients = createClientsAtInitialState({
|
|
25
|
+
initialState: "",
|
|
26
|
+
options: {
|
|
27
|
+
mergeTreeEnableObliterate: true,
|
|
28
|
+
mergeTreeEnableSidedObliterate: true,
|
|
29
|
+
...options,
|
|
30
|
+
},
|
|
31
|
+
}, ...ClientIds);
|
|
32
|
+
this.logger = new TestClientLogger(this.clients.all);
|
|
33
|
+
this.perClientOps = this.clients.all.map(() => []);
|
|
34
|
+
}
|
|
35
|
+
addMessage(message) {
|
|
36
|
+
this.ops.push(message);
|
|
37
|
+
// This implementation (specifically, that of applying ops / synchronizing clients) assumes messages
|
|
38
|
+
// are pushed sequentially starting with seq 1.
|
|
39
|
+
assert(message.sequenceNumber === this.ops.length, "Partial sync test helper invariant violated");
|
|
40
|
+
}
|
|
41
|
+
insertText(clientName, pos, text) {
|
|
42
|
+
const client = this.clients[clientName];
|
|
43
|
+
this.addMessage(client.makeOpMessage(client.insertTextLocal(pos, text), ++this.seq));
|
|
44
|
+
}
|
|
45
|
+
removeRange(clientName, start, end) {
|
|
46
|
+
const client = this.clients[clientName];
|
|
47
|
+
this.addMessage(client.makeOpMessage(client.removeRangeLocal(start, end), ++this.seq));
|
|
48
|
+
}
|
|
49
|
+
obliterateRange(clientName, start, end) {
|
|
50
|
+
const client = this.clients[clientName];
|
|
51
|
+
this.addMessage(client.makeOpMessage(
|
|
52
|
+
// TODO: remove type assertions when sidedness is enabled
|
|
53
|
+
client.obliterateRangeLocal(start, end), ++this.seq));
|
|
54
|
+
}
|
|
55
|
+
advanceClientToSeq(clientName, seq) {
|
|
56
|
+
const client = this.clients[clientName];
|
|
57
|
+
const lastApplied = this.clientToLastAppliedSeq.get(clientName);
|
|
58
|
+
assert(seq > 0, "Can only advance clients to sequence numbers that exist");
|
|
59
|
+
assert(this.ops.length >= seq, "Cannot attempt to advance clients to sequence numbers that don't yet exist");
|
|
60
|
+
let startIndex;
|
|
61
|
+
if (lastApplied === undefined) {
|
|
62
|
+
startIndex = 0;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
if (lastApplied >= seq) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
startIndex = lastApplied;
|
|
69
|
+
}
|
|
70
|
+
for (let i = startIndex; i < seq; i++) {
|
|
71
|
+
const nextMessage = this.ops[i];
|
|
72
|
+
client.applyMsg(nextMessage);
|
|
73
|
+
this.clientToLastAppliedSeq.set(clientName, nextMessage.sequenceNumber);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Sends all known ops to the procieded client ids.
|
|
78
|
+
*/
|
|
79
|
+
advanceClients(...clientNames) {
|
|
80
|
+
const latestSeq = this.ops[this.ops.length - 1].sequenceNumber;
|
|
81
|
+
for (const name of clientNames) {
|
|
82
|
+
this.advanceClientToSeq(name, latestSeq);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
processAllOps() {
|
|
86
|
+
const latestSeq = this.ops[this.ops.length - 1].sequenceNumber;
|
|
87
|
+
for (const name of ClientIds) {
|
|
88
|
+
this.advanceClientToSeq(name, latestSeq);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=partialSyncHelper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"partialSyncHelper.js","sourceRoot":"","sources":["../../src/test/partialSyncHelper.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport type { IMergeTreeOptions, InteriorSequencePlace } from \"../index.js\";\n\nimport type { TestClient } from \"./testClient.js\";\nimport { TestClientLogger, createClientsAtInitialState } from \"./testClientLogger.js\";\n\nconst ClientIds = [\"A\", \"B\", \"C\", \"D\"] as const;\ntype ClientName = (typeof ClientIds)[number];\n\n/**\n * Like `ReconnectHelper`, but:\n * - does not support reconnecting clients\n * - supports advancing only some clients to a given sequence number (not all clients must be synchronized at the same time).\n *\n * This allows testing sequences of operations where clients have varying refSeqs, rather than having all clients advance refSeq\n * in lockstep.\n */\nexport class PartialSyncTestHelper {\n\tclients: Record<ClientName, TestClient> & { all: TestClient[] };\n\n\tidxFromName(name: ClientName): number {\n\t\treturn (name.codePointAt(0) ?? 0) - (\"A\".codePointAt(0) ?? 0);\n\t}\n\n\tlogger: TestClientLogger;\n\n\tops: ISequencedDocumentMessage[] = [];\n\tclientToLastAppliedSeq = new Map<ClientName, number>();\n\n\tperClientOps: ISequencedDocumentMessage[][];\n\n\tprivate seq: number = 0;\n\n\tpublic constructor(options: IMergeTreeOptions = {}) {\n\t\tthis.clients = createClientsAtInitialState(\n\t\t\t{\n\t\t\t\tinitialState: \"\",\n\t\t\t\toptions: {\n\t\t\t\t\tmergeTreeEnableObliterate: true,\n\t\t\t\t\tmergeTreeEnableSidedObliterate: true,\n\t\t\t\t\t...options,\n\t\t\t\t},\n\t\t\t},\n\t\t\t...ClientIds,\n\t\t);\n\t\tthis.logger = new TestClientLogger(this.clients.all);\n\t\tthis.perClientOps = this.clients.all.map(() => []);\n\t}\n\n\tprivate addMessage(message: ISequencedDocumentMessage): void {\n\t\tthis.ops.push(message);\n\t\t// This implementation (specifically, that of applying ops / synchronizing clients) assumes messages\n\t\t// are pushed sequentially starting with seq 1.\n\t\tassert(\n\t\t\tmessage.sequenceNumber === this.ops.length,\n\t\t\t\"Partial sync test helper invariant violated\",\n\t\t);\n\t}\n\n\tpublic insertText(clientName: ClientName, pos: number, text: string): void {\n\t\tconst client = this.clients[clientName];\n\t\tthis.addMessage(client.makeOpMessage(client.insertTextLocal(pos, text), ++this.seq));\n\t}\n\n\tpublic removeRange(clientName: ClientName, start: number, end: number): void {\n\t\tconst client = this.clients[clientName];\n\t\tthis.addMessage(client.makeOpMessage(client.removeRangeLocal(start, end), ++this.seq));\n\t}\n\n\tpublic obliterateRange(\n\t\tclientName: ClientName,\n\t\tstart: number | InteriorSequencePlace,\n\t\tend: number | InteriorSequencePlace,\n\t): void {\n\t\tconst client = this.clients[clientName];\n\t\tthis.addMessage(\n\t\t\tclient.makeOpMessage(\n\t\t\t\t// TODO: remove type assertions when sidedness is enabled\n\t\t\t\tclient.obliterateRangeLocal(start as number, end as number),\n\t\t\t\t++this.seq,\n\t\t\t),\n\t\t);\n\t}\n\n\tpublic advanceClientToSeq(clientName: ClientName, seq: number): void {\n\t\tconst client = this.clients[clientName];\n\t\tconst lastApplied = this.clientToLastAppliedSeq.get(clientName);\n\t\tassert(seq > 0, \"Can only advance clients to sequence numbers that exist\");\n\t\tassert(\n\t\t\tthis.ops.length >= seq,\n\t\t\t\"Cannot attempt to advance clients to sequence numbers that don't yet exist\",\n\t\t);\n\t\tlet startIndex: number;\n\t\tif (lastApplied === undefined) {\n\t\t\tstartIndex = 0;\n\t\t} else {\n\t\t\tif (lastApplied >= seq) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tstartIndex = lastApplied;\n\t\t}\n\t\tfor (let i = startIndex; i < seq; i++) {\n\t\t\tconst nextMessage = this.ops[i];\n\t\t\tclient.applyMsg(nextMessage);\n\t\t\tthis.clientToLastAppliedSeq.set(clientName, nextMessage.sequenceNumber);\n\t\t}\n\t}\n\n\t/**\n\t * Sends all known ops to the procieded client ids.\n\t */\n\tpublic advanceClients(...clientNames: ClientName[]): void {\n\t\tconst latestSeq = this.ops[this.ops.length - 1].sequenceNumber;\n\t\tfor (const name of clientNames) {\n\t\t\tthis.advanceClientToSeq(name, latestSeq);\n\t\t}\n\t}\n\n\tpublic processAllOps(): void {\n\t\tconst latestSeq = this.ops[this.ops.length - 1].sequenceNumber;\n\t\tfor (const name of ClientIds) {\n\t\t\tthis.advanceClientToSeq(name, latestSeq);\n\t\t}\n\t}\n}\n"]}
|
|
@@ -352,7 +352,7 @@ describe("MergeTree.Revertibles", () => {
|
|
|
352
352
|
let afterUndoBaseText;
|
|
353
353
|
if (options.revertMarkerInsert) {
|
|
354
354
|
openNewUndoRedoTransaction();
|
|
355
|
-
afterUndoBaseText
|
|
355
|
+
afterUndoBaseText ??= clients.B.getText();
|
|
356
356
|
}
|
|
357
357
|
ops.push(clients.B.makeOpMessage(clients.B.insertMarkerLocal(0, ReferenceType.Simple), ++seq), clients.B.makeOpMessage(clients.B.insertMarkerLocal(1, ReferenceType.Simple), ++seq));
|
|
358
358
|
if (options.ackMarkerInsert) {
|
|
@@ -363,7 +363,7 @@ describe("MergeTree.Revertibles", () => {
|
|
|
363
363
|
}
|
|
364
364
|
if (options.splitInsertTextRevertible) {
|
|
365
365
|
openNewUndoRedoTransaction();
|
|
366
|
-
afterUndoBaseText
|
|
366
|
+
afterUndoBaseText ??= clients.B.getText();
|
|
367
367
|
}
|
|
368
368
|
ops.push(clients.B.makeOpMessage(clients.B.insertTextLocal(1, "B"), ++seq));
|
|
369
369
|
if (options.ackTextInsert) {
|
|
@@ -374,7 +374,7 @@ describe("MergeTree.Revertibles", () => {
|
|
|
374
374
|
}
|
|
375
375
|
if (options.splitRemoveRevertible) {
|
|
376
376
|
openNewUndoRedoTransaction();
|
|
377
|
-
afterUndoBaseText
|
|
377
|
+
afterUndoBaseText ??= clients.B.getText();
|
|
378
378
|
}
|
|
379
379
|
ops.push(clients.B.makeOpMessage(clients.B.removeRangeLocal(1, 2), ++seq));
|
|
380
380
|
if (options.ackTextRemove) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revertibles.spec.js","sourceRoot":"","sources":["../../src/test/revertibles.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\nimport { strict as assert } from \"node:assert\";\n\nimport { generatePairwiseOptions } from \"@fluid-private/test-pairwise-generator\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport type {\n\tIMergeTreeDeltaCallbackArgs,\n\tIMergeTreeDeltaOpArgs,\n} from \"../mergeTreeDeltaCallback.js\";\nimport { TrackingGroup, UnorderedTrackingGroup } from \"../mergeTreeTracking.js\";\nimport { ReferenceType } from \"../ops.js\";\nimport {\n\tMergeTreeDeltaRevertible,\n\tappendToMergeTreeDeltaRevertibles,\n\trevertMergeTreeDeltaRevertibles,\n} from \"../revertibles.js\";\n\nimport { createRevertDriver } from \"./testClient.js\";\nimport { TestClientLogger, createClientsAtInitialState } from \"./testClientLogger.js\";\n\n/**\n * Run a custom \"spy function\" every time the given method is invoked.\n * @param methodClass - the class that has the method\n * @param methodName - the name of the method\n * @param spy - the spy function to run alongside the method\n * @returns a function which will remove the spy function when invoked. Should be called exactly once\n * after the spy is no longer needed.\n *\n * This method is duplicated between shared-tree test code, and should eventually\n * be merged with the implementation that lives there\n */\nexport function spyOnMethod(\n\t// eslint-disable-next-line @typescript-eslint/ban-types\n\tmethodClass: Function,\n\tmethodName: string,\n\tspy: () => void,\n): () => void {\n\tconst { prototype } = methodClass;\n\tconst method = prototype[methodName];\n\tassert(typeof method === \"function\", `Method does not exist: ${methodName}`);\n\n\tconst methodSpy = function (this: unknown, ...args: unknown[]): unknown {\n\t\tspy();\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-call\n\t\treturn method.call(this, ...args);\n\t};\n\tprototype[methodName] = methodSpy;\n\n\treturn () => {\n\t\tprototype[methodName] = method;\n\t};\n}\n\ndescribe(\"MergeTree.Revertibles\", () => {\n\tit(\"revert insert\", () => {\n\t\tconst clients = createClientsAtInitialState(\n\t\t\t{ initialState: \"123\", options: {} },\n\t\t\t\"A\",\n\t\t\t\"B\",\n\t\t);\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tlet seq = 0;\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\tclients.B.on(\"delta\", (op, delta) => {\n\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t});\n\n\t\tops.push(clients.B.makeOpMessage(clients.B.insertTextLocal(0, \"BB\"), ++seq));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"BB123\" });\n\n\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"123\" });\n\t});\n\n\tit(\"has reasonable asymptotics in face of remove\", () => {\n\t\tconst length = 100;\n\n\t\t// track the amount of tracking group linking that occurs\n\t\tlet linkCount = 0;\n\t\tlet unlinkCount = 0;\n\n\t\tconst unspy1 = spyOnMethod(TrackingGroup, \"link\", () => (linkCount += 1));\n\t\tconst unspy2 = spyOnMethod(TrackingGroup, \"unlink\", () => (unlinkCount += 1));\n\t\tconst unspy3 = spyOnMethod(UnorderedTrackingGroup, \"link\", () => (linkCount += 1));\n\t\tconst unspy4 = spyOnMethod(UnorderedTrackingGroup, \"unlink\", () => (unlinkCount += 1));\n\n\t\ttry {\n\t\t\tconst clients = createClientsAtInitialState(\n\t\t\t\t{\n\t\t\t\t\tinitialState: \"\",\n\t\t\t\t\toptions: {},\n\t\t\t\t},\n\t\t\t\t\"A\",\n\t\t\t);\n\n\t\t\tfor (let i = 1; i <= length; i++) {\n\t\t\t\tconst insertOp = clients.A.insertTextLocal(i - 1, \"a\");\n\t\t\t\tclients.A.applyMsg(\n\t\t\t\t\tclients.A.makeOpMessage(\n\t\t\t\t\t\tinsertOp,\n\t\t\t\t\t\t/* seq */ i + 1,\n\t\t\t\t\t\t/* refSeq */ i,\n\t\t\t\t\t\tclients.A.longClientId,\n\t\t\t\t\t\t/* minSeq */ 1,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst revertibles: MergeTreeDeltaRevertible[] = [];\n\t\t\tclients.A.on(\"delta\", (_op, delta) => {\n\t\t\t\tappendToMergeTreeDeltaRevertibles(delta, revertibles);\n\t\t\t});\n\n\t\t\tconst op = clients.A.removeRangeLocal(0, length - 1);\n\n\t\t\tclients.A.applyMsg(\n\t\t\t\tclients.A.makeOpMessage(\n\t\t\t\t\top,\n\t\t\t\t\t/* seq */ length + 1,\n\t\t\t\t\t/* refSeq */ length,\n\t\t\t\t\tclients.A.longClientId,\n\t\t\t\t\t/* minSeq */ length,\n\t\t\t\t),\n\t\t\t);\n\n\t\t\t// the below checks act as a proxy for the asymptotics of undo-redo\n\t\t\t// linking. they are perhaps a bit more strict than necessary. if these\n\t\t\t// tests are failing and the number of calls is still within a sane limit,\n\t\t\t// it should be fine to update these checks to allow a larger number of\n\t\t\t// calls\n\t\t\tassert(\n\t\t\t\tlinkCount <= length * 3,\n\t\t\t\t`expected tracking group link to occur at most three times per segment. found ${linkCount} instead of ${\n\t\t\t\t\tlength * 3\n\t\t\t\t}`,\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tunlinkCount <= length * 2,\n\t\t\t\t`expected tracking group unlink to occur at most twice per segment. found ${unlinkCount} instead of ${\n\t\t\t\t\tlength * 2\n\t\t\t\t}`,\n\t\t\t);\n\t\t} finally {\n\t\t\tunspy1();\n\t\t\tunspy2();\n\t\t\tunspy3();\n\t\t\tunspy4();\n\t\t}\n\t});\n\n\tit(\"revert remove\", () => {\n\t\tconst clients = createClientsAtInitialState(\n\t\t\t{ initialState: \"123\", options: {} },\n\t\t\t\"A\",\n\t\t\t\"B\",\n\t\t);\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tlet seq = 0;\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\tclients.B.on(\"delta\", (op, delta) => {\n\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t});\n\n\t\tops.push(clients.B.makeOpMessage(clients.B.removeRangeLocal(0, 1), ++seq));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"23\" });\n\n\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"123\" });\n\t});\n\n\tfor (const { name, removeStart, removeEnd, expectedPostRemove } of [\n\t\t{\n\t\t\tname: \"revert overlapping remove\",\n\t\t\tremoveStart: 0,\n\t\t\tremoveEnd: 1,\n\t\t\texpectedPostRemove: \"23\",\n\t\t},\n\t\t{\n\t\t\tname: \"revert overlapping remove of multiple segments\",\n\t\t\tremoveStart: 0,\n\t\t\tremoveEnd: 2,\n\t\t\texpectedPreRemove: \"23\",\n\t\t},\n\t]) {\n\t\tit(name, () => {\n\t\t\tconst clients = createClientsAtInitialState(\n\t\t\t\t{ initialState: \"1-23\", options: {} },\n\t\t\t\t\"A\",\n\t\t\t\t\"B\",\n\t\t\t\t\"C\",\n\t\t\t);\n\t\t\tconst logger = new TestClientLogger(clients.all);\n\t\t\tlet seq = 0;\n\t\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\t\tclients.B.on(\"delta\", (op, delta) => {\n\t\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t\t});\n\n\t\t\tops.push(\n\t\t\t\tclients.C.makeOpMessage(clients.C.removeRangeLocal(removeStart, removeEnd), ++seq),\n\t\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(removeStart, removeEnd), ++seq),\n\t\t\t);\n\n\t\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\t\tlogger.validate({ baseText: expectedPostRemove });\n\n\t\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\n\t\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\t\tlogger.validate({ baseText: \"123\" });\n\t\t});\n\t}\n\n\tit(\"revert two overlapping removes\", () => {\n\t\tconst clients = createClientsAtInitialState(\n\t\t\t{ initialState: \"123\", options: {} },\n\t\t\t\"A\",\n\t\t\t\"B\",\n\t\t\t\"C\",\n\t\t);\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tlet seq = 0;\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\tconst clientC_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\tconst clientCDriver = createRevertDriver(clients.C);\n\t\tclientCDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.C.makeOpMessage(op, ++seq));\n\n\t\tclients.B.on(\"delta\", (op, delta) => {\n\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t});\n\n\t\tclients.C.on(\"delta\", (op, delta) => {\n\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientC_Revertibles);\n\t\t});\n\n\t\tops.push(\n\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(0, 1), ++seq),\n\t\t\tclients.C.makeOpMessage(clients.C.removeRangeLocal(0, 1), ++seq),\n\t\t);\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"23\" });\n\n\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\t\trevertMergeTreeDeltaRevertibles(clientCDriver, clientC_Revertibles.splice(0));\n\n\t\t// \"123\" would be the ideal final state, but due to current limitations,\n\t\t// the eventual consistent state is \"1123\"\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"1123\" });\n\t});\n\n\tit(\"revert annotate\", () => {\n\t\tconst clients = createClientsAtInitialState(\n\t\t\t{ initialState: \"123\", options: {} },\n\t\t\t\"A\",\n\t\t\t\"B\",\n\t\t);\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tlet seq = 0;\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\tclients.B.on(\"delta\", (op, delta) => {\n\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t});\n\t\tops.push(clients.B.makeOpMessage(clients.B.annotateRangeLocal(0, 1, { test: 1 }), ++seq));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"123\" });\n\n\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"123\" });\n\t});\n\n\tit(\"Remove All Original Text and Insert then Revert\", () => {\n\t\tconst clients = createClientsAtInitialState(\n\t\t\t{ initialState: \"1-2--\", options: {} },\n\t\t\t\"A\",\n\t\t\t\"B\",\n\t\t\t\"C\",\n\t\t);\n\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tlet seq = 0;\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\t// the test logger uses these callbacks, so preserve it\n\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\tconst deltaCallback = (op, delta: IMergeTreeDeltaCallbackArgs): void => {\n\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t};\n\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\tclients.B.on(\"delta\", deltaCallback);\n\t\tops.push(\n\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(0, 1), ++seq),\n\t\t\tclients.B.makeOpMessage(clients.B.insertTextLocal(0, \"BB\"), ++seq),\n\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(2, 3), ++seq),\n\t\t);\n\n\t\t// revert to the original callback\n\t\tclients.B.off(\"delta\", deltaCallback);\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\n\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\n\t\tlogger.validate({ baseText: \"12\" });\n\t});\n\n\tit(\"Re-Insert at position 0 in empty string\", () => {\n\t\tconst clients = createClientsAtInitialState(\n\t\t\t{ initialState: \"BBC-\", options: {} },\n\t\t\t\"A\",\n\t\t\t\"B\",\n\t\t\t\"C\",\n\t\t);\n\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tlet seq = 0;\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\tconst deltaCallback = (op, delta: IMergeTreeDeltaCallbackArgs): void => {\n\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t};\n\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\tclients.B.on(\"delta\", deltaCallback);\n\t\tops.push(\n\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(2, 3), ++seq),\n\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(0, 1), ++seq),\n\t\t\tclients.B.makeOpMessage(clients.B.insertTextLocal(1, \"BB\"), ++seq),\n\t\t);\n\n\t\t// revert to the original callback\n\t\tclients.B.off(\"delta\", deltaCallback);\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\n\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\n\t\tlogger.validate({ baseText: \"BBC\" });\n\t});\n\n\tit(\"Revert remove to empty with annotate\", () => {\n\t\tconst clients = createClientsAtInitialState(\n\t\t\t{ initialState: \"1-23--\", options: {} },\n\t\t\t\"A\",\n\t\t\t\"B\",\n\t\t\t\"C\",\n\t\t);\n\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tlet seq = 0;\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\tconst deltaCallback = (op, delta: IMergeTreeDeltaCallbackArgs): void => {\n\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t};\n\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\tclients.B.on(\"delta\", deltaCallback);\n\t\tops.push(\n\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(0, 2), ++seq),\n\t\t\tclients.B.makeOpMessage(clients.B.annotateRangeLocal(0, 1, { test: 1 }), ++seq),\n\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(0, 1), ++seq),\n\t\t);\n\n\t\t// revert to the original callback\n\t\tclients.B.off(\"delta\", deltaCallback);\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\n\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\n\t\tlogger.validate({ baseText: \"123\" });\n\t});\n\n\tit(\"Revert Local annotate and remove with intersecting remote annotate\", () => {\n\t\tconst clients = createClientsAtInitialState(\n\t\t\t{ initialState: \"1234-----\", options: {} },\n\t\t\t\"A\",\n\t\t\t\"B\",\n\t\t\t\"C\",\n\t\t);\n\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tlet seq = 0;\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\tconst deltaCallback = (\n\t\t\top: IMergeTreeDeltaOpArgs,\n\t\t\tdelta: IMergeTreeDeltaCallbackArgs,\n\t\t): void => {\n\t\t\tif (op.sequencedMessage === undefined) {\n\t\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t\t}\n\t\t};\n\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\tclients.B.on(\"delta\", deltaCallback);\n\t\tops.push(\n\t\t\tclients.B.makeOpMessage(clients.B.annotateRangeLocal(0, 4, { test: \"B\" }), ++seq),\n\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(1, 2), ++seq),\n\t\t);\n\n\t\t// revert to the original callback\n\t\tclients.B.off(\"delta\", deltaCallback);\n\n\t\tops.push(\n\t\t\tclients.C.makeOpMessage(clients.C.annotateRangeLocal(3, 4, { test: \"C\" }), ++seq),\n\t\t);\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"134\" });\n\n\t\ttry {\n\t\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\t\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\t} catch (error) {\n\t\t\tthrow logger.addLogsToError(error);\n\t\t}\n\n\t\tlogger.validate({ baseText: \"1234\" });\n\t});\n\n\tdescribe(\"Revertibles work as expected when a pair of markers and text is involved\", () => {\n\t\tfor (const options of generatePairwiseOptions({\n\t\t\trevertMarkerInsert: [true, undefined],\n\t\t\tackMarkerInsert: [true, undefined],\n\t\t\tsplitInsertTextRevertible: [true, undefined],\n\t\t\tackTextInsert: [true, undefined],\n\t\t\tsplitRemoveRevertible: [true, undefined],\n\t\t\tackTextRemove: [true, undefined],\n\t\t\tackUndo: [true, undefined],\n\t\t})) {\n\t\t\tit(JSON.stringify(options), () => {\n\t\t\t\tconst clients = createClientsAtInitialState(\n\t\t\t\t\t{ initialState: \"\", options: {} },\n\t\t\t\t\t\"A\",\n\t\t\t\t\t\"B\",\n\t\t\t\t);\n\n\t\t\t\tconst logger = new TestClientLogger(clients.all);\n\t\t\t\tlet seq = 0;\n\t\t\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\t\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[][] = [];\n\t\t\t\tconst openNewUndoRedoTransaction = (): number => clientB_Revertibles.unshift([]);\n\t\t\t\t// the test logger uses these callbacks, so preserve it\n\t\t\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\t\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\t\t\t\tclients.B.on(\"delta\", (op, delta) => {\n\t\t\t\t\tif (op.sequencedMessage === undefined && clientB_Revertibles.length > 0) {\n\t\t\t\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles[0]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tlet afterUndoBaseText: string | undefined;\n\t\t\t\tif (options.revertMarkerInsert) {\n\t\t\t\t\topenNewUndoRedoTransaction();\n\t\t\t\t\tafterUndoBaseText ??= clients.B.getText();\n\t\t\t\t}\n\t\t\t\tops.push(\n\t\t\t\t\tclients.B.makeOpMessage(clients.B.insertMarkerLocal(0, ReferenceType.Simple), ++seq),\n\t\t\t\t\tclients.B.makeOpMessage(clients.B.insertMarkerLocal(1, ReferenceType.Simple), ++seq),\n\t\t\t\t);\n\n\t\t\t\tif (options.ackMarkerInsert) {\n\t\t\t\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\t\t\t\tlogger.validate({ baseText: afterUndoBaseText });\n\t\t\t\t}\n\n\t\t\t\tif (options.splitInsertTextRevertible) {\n\t\t\t\t\topenNewUndoRedoTransaction();\n\t\t\t\t\tafterUndoBaseText ??= clients.B.getText();\n\t\t\t\t}\n\t\t\t\tops.push(clients.B.makeOpMessage(clients.B.insertTextLocal(1, \"B\"), ++seq));\n\t\t\t\tif (options.ackTextInsert) {\n\t\t\t\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\t\t\t\tlogger.validate({ baseText: \"B\" });\n\t\t\t\t}\n\n\t\t\t\tif (options.splitRemoveRevertible) {\n\t\t\t\t\topenNewUndoRedoTransaction();\n\t\t\t\t\tafterUndoBaseText ??= clients.B.getText();\n\t\t\t\t}\n\n\t\t\t\tops.push(clients.B.makeOpMessage(clients.B.removeRangeLocal(1, 2), ++seq));\n\t\t\t\tif (options.ackTextRemove) {\n\t\t\t\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\t\t\t\tlogger.validate({ baseText: \"\" });\n\t\t\t\t}\n\n\t\t\t\tconst afterRevertBaseTest = clients.B.getText();\n\t\t\t\ttry {\n\t\t\t\t\tconst reverts = clientB_Revertibles.splice(0);\n\t\t\t\t\tfor (const revert of reverts) {\n\t\t\t\t\t\topenNewUndoRedoTransaction();\n\t\t\t\t\t\trevertMergeTreeDeltaRevertibles(clientBDriver, revert);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow logger.addLogsToError(error);\n\t\t\t\t}\n\n\t\t\t\tif (options.ackUndo) {\n\t\t\t\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\t\t\t\tlogger.validate({ baseText: afterUndoBaseText });\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst reverts = clientB_Revertibles.splice(0);\n\t\t\t\t\tfor (const revert of reverts) {\n\t\t\t\t\t\trevertMergeTreeDeltaRevertibles(clientBDriver, revert);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow logger.addLogsToError(error);\n\t\t\t\t}\n\n\t\t\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\t\t\tlogger.validate({ baseText: afterRevertBaseTest });\n\t\t\t});\n\t\t}\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"file":"revertibles.spec.js","sourceRoot":"","sources":["../../src/test/revertibles.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\nimport { strict as assert } from \"node:assert\";\n\nimport { generatePairwiseOptions } from \"@fluid-private/test-pairwise-generator\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport type {\n\tIMergeTreeDeltaCallbackArgs,\n\tIMergeTreeDeltaOpArgs,\n} from \"../mergeTreeDeltaCallback.js\";\nimport { TrackingGroup, UnorderedTrackingGroup } from \"../mergeTreeTracking.js\";\nimport { ReferenceType } from \"../ops.js\";\nimport {\n\tMergeTreeDeltaRevertible,\n\tappendToMergeTreeDeltaRevertibles,\n\trevertMergeTreeDeltaRevertibles,\n} from \"../revertibles.js\";\n\nimport { createRevertDriver } from \"./testClient.js\";\nimport { TestClientLogger, createClientsAtInitialState } from \"./testClientLogger.js\";\n\n/**\n * Run a custom \"spy function\" every time the given method is invoked.\n * @param methodClass - the class that has the method\n * @param methodName - the name of the method\n * @param spy - the spy function to run alongside the method\n * @returns a function which will remove the spy function when invoked. Should be called exactly once\n * after the spy is no longer needed.\n *\n * This method is duplicated between shared-tree test code, and should eventually\n * be merged with the implementation that lives there\n */\nexport function spyOnMethod(\n\t// eslint-disable-next-line @typescript-eslint/ban-types\n\tmethodClass: Function,\n\tmethodName: string,\n\tspy: () => void,\n): () => void {\n\tconst { prototype } = methodClass;\n\tconst method = prototype[methodName];\n\tassert(typeof method === \"function\", `Method does not exist: ${methodName}`);\n\n\tconst methodSpy = function (this: unknown, ...args: unknown[]): unknown {\n\t\tspy();\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-call\n\t\treturn method.call(this, ...args);\n\t};\n\tprototype[methodName] = methodSpy;\n\n\treturn () => {\n\t\tprototype[methodName] = method;\n\t};\n}\n\ndescribe(\"MergeTree.Revertibles\", () => {\n\tit(\"revert insert\", () => {\n\t\tconst clients = createClientsAtInitialState(\n\t\t\t{ initialState: \"123\", options: {} },\n\t\t\t\"A\",\n\t\t\t\"B\",\n\t\t);\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tlet seq = 0;\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\tclients.B.on(\"delta\", (op, delta) => {\n\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t});\n\n\t\tops.push(clients.B.makeOpMessage(clients.B.insertTextLocal(0, \"BB\"), ++seq));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"BB123\" });\n\n\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"123\" });\n\t});\n\n\tit(\"has reasonable asymptotics in face of remove\", () => {\n\t\tconst length = 100;\n\n\t\t// track the amount of tracking group linking that occurs\n\t\tlet linkCount = 0;\n\t\tlet unlinkCount = 0;\n\n\t\tconst unspy1 = spyOnMethod(TrackingGroup, \"link\", () => (linkCount += 1));\n\t\tconst unspy2 = spyOnMethod(TrackingGroup, \"unlink\", () => (unlinkCount += 1));\n\t\tconst unspy3 = spyOnMethod(UnorderedTrackingGroup, \"link\", () => (linkCount += 1));\n\t\tconst unspy4 = spyOnMethod(UnorderedTrackingGroup, \"unlink\", () => (unlinkCount += 1));\n\n\t\ttry {\n\t\t\tconst clients = createClientsAtInitialState(\n\t\t\t\t{\n\t\t\t\t\tinitialState: \"\",\n\t\t\t\t\toptions: {},\n\t\t\t\t},\n\t\t\t\t\"A\",\n\t\t\t);\n\n\t\t\tfor (let i = 1; i <= length; i++) {\n\t\t\t\tconst insertOp = clients.A.insertTextLocal(i - 1, \"a\");\n\t\t\t\tclients.A.applyMsg(\n\t\t\t\t\tclients.A.makeOpMessage(\n\t\t\t\t\t\tinsertOp,\n\t\t\t\t\t\t/* seq */ i + 1,\n\t\t\t\t\t\t/* refSeq */ i,\n\t\t\t\t\t\tclients.A.longClientId,\n\t\t\t\t\t\t/* minSeq */ 1,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst revertibles: MergeTreeDeltaRevertible[] = [];\n\t\t\tclients.A.on(\"delta\", (_op, delta) => {\n\t\t\t\tappendToMergeTreeDeltaRevertibles(delta, revertibles);\n\t\t\t});\n\n\t\t\tconst op = clients.A.removeRangeLocal(0, length - 1);\n\n\t\t\tclients.A.applyMsg(\n\t\t\t\tclients.A.makeOpMessage(\n\t\t\t\t\top,\n\t\t\t\t\t/* seq */ length + 1,\n\t\t\t\t\t/* refSeq */ length,\n\t\t\t\t\tclients.A.longClientId,\n\t\t\t\t\t/* minSeq */ length,\n\t\t\t\t),\n\t\t\t);\n\n\t\t\t// the below checks act as a proxy for the asymptotics of undo-redo\n\t\t\t// linking. they are perhaps a bit more strict than necessary. if these\n\t\t\t// tests are failing and the number of calls is still within a sane limit,\n\t\t\t// it should be fine to update these checks to allow a larger number of\n\t\t\t// calls\n\t\t\tassert(\n\t\t\t\tlinkCount <= length * 3,\n\t\t\t\t`expected tracking group link to occur at most three times per segment. found ${linkCount} instead of ${\n\t\t\t\t\tlength * 3\n\t\t\t\t}`,\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tunlinkCount <= length * 2,\n\t\t\t\t`expected tracking group unlink to occur at most twice per segment. found ${unlinkCount} instead of ${\n\t\t\t\t\tlength * 2\n\t\t\t\t}`,\n\t\t\t);\n\t\t} finally {\n\t\t\tunspy1();\n\t\t\tunspy2();\n\t\t\tunspy3();\n\t\t\tunspy4();\n\t\t}\n\t});\n\n\tit(\"revert remove\", () => {\n\t\tconst clients = createClientsAtInitialState(\n\t\t\t{ initialState: \"123\", options: {} },\n\t\t\t\"A\",\n\t\t\t\"B\",\n\t\t);\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tlet seq = 0;\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\tclients.B.on(\"delta\", (op, delta) => {\n\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t});\n\n\t\tops.push(clients.B.makeOpMessage(clients.B.removeRangeLocal(0, 1), ++seq));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"23\" });\n\n\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"123\" });\n\t});\n\n\tfor (const { name, removeStart, removeEnd, expectedPostRemove } of [\n\t\t{\n\t\t\tname: \"revert overlapping remove\",\n\t\t\tremoveStart: 0,\n\t\t\tremoveEnd: 1,\n\t\t\texpectedPostRemove: \"23\",\n\t\t},\n\t\t{\n\t\t\tname: \"revert overlapping remove of multiple segments\",\n\t\t\tremoveStart: 0,\n\t\t\tremoveEnd: 2,\n\t\t\texpectedPreRemove: \"23\",\n\t\t},\n\t]) {\n\t\tit(name, () => {\n\t\t\tconst clients = createClientsAtInitialState(\n\t\t\t\t{ initialState: \"1-23\", options: {} },\n\t\t\t\t\"A\",\n\t\t\t\t\"B\",\n\t\t\t\t\"C\",\n\t\t\t);\n\t\t\tconst logger = new TestClientLogger(clients.all);\n\t\t\tlet seq = 0;\n\t\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\t\tclients.B.on(\"delta\", (op, delta) => {\n\t\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t\t});\n\n\t\t\tops.push(\n\t\t\t\tclients.C.makeOpMessage(clients.C.removeRangeLocal(removeStart, removeEnd), ++seq),\n\t\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(removeStart, removeEnd), ++seq),\n\t\t\t);\n\n\t\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\t\tlogger.validate({ baseText: expectedPostRemove });\n\n\t\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\n\t\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\t\tlogger.validate({ baseText: \"123\" });\n\t\t});\n\t}\n\n\tit(\"revert two overlapping removes\", () => {\n\t\tconst clients = createClientsAtInitialState(\n\t\t\t{ initialState: \"123\", options: {} },\n\t\t\t\"A\",\n\t\t\t\"B\",\n\t\t\t\"C\",\n\t\t);\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tlet seq = 0;\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\tconst clientC_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\tconst clientCDriver = createRevertDriver(clients.C);\n\t\tclientCDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.C.makeOpMessage(op, ++seq));\n\n\t\tclients.B.on(\"delta\", (op, delta) => {\n\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t});\n\n\t\tclients.C.on(\"delta\", (op, delta) => {\n\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientC_Revertibles);\n\t\t});\n\n\t\tops.push(\n\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(0, 1), ++seq),\n\t\t\tclients.C.makeOpMessage(clients.C.removeRangeLocal(0, 1), ++seq),\n\t\t);\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"23\" });\n\n\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\t\trevertMergeTreeDeltaRevertibles(clientCDriver, clientC_Revertibles.splice(0));\n\n\t\t// \"123\" would be the ideal final state, but due to current limitations,\n\t\t// the eventual consistent state is \"1123\"\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"1123\" });\n\t});\n\n\tit(\"revert annotate\", () => {\n\t\tconst clients = createClientsAtInitialState(\n\t\t\t{ initialState: \"123\", options: {} },\n\t\t\t\"A\",\n\t\t\t\"B\",\n\t\t);\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tlet seq = 0;\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\tclients.B.on(\"delta\", (op, delta) => {\n\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t});\n\t\tops.push(clients.B.makeOpMessage(clients.B.annotateRangeLocal(0, 1, { test: 1 }), ++seq));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"123\" });\n\n\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"123\" });\n\t});\n\n\tit(\"Remove All Original Text and Insert then Revert\", () => {\n\t\tconst clients = createClientsAtInitialState(\n\t\t\t{ initialState: \"1-2--\", options: {} },\n\t\t\t\"A\",\n\t\t\t\"B\",\n\t\t\t\"C\",\n\t\t);\n\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tlet seq = 0;\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\t// the test logger uses these callbacks, so preserve it\n\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\tconst deltaCallback = (op, delta: IMergeTreeDeltaCallbackArgs): void => {\n\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t};\n\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\tclients.B.on(\"delta\", deltaCallback);\n\t\tops.push(\n\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(0, 1), ++seq),\n\t\t\tclients.B.makeOpMessage(clients.B.insertTextLocal(0, \"BB\"), ++seq),\n\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(2, 3), ++seq),\n\t\t);\n\n\t\t// revert to the original callback\n\t\tclients.B.off(\"delta\", deltaCallback);\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\n\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\n\t\tlogger.validate({ baseText: \"12\" });\n\t});\n\n\tit(\"Re-Insert at position 0 in empty string\", () => {\n\t\tconst clients = createClientsAtInitialState(\n\t\t\t{ initialState: \"BBC-\", options: {} },\n\t\t\t\"A\",\n\t\t\t\"B\",\n\t\t\t\"C\",\n\t\t);\n\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tlet seq = 0;\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\tconst deltaCallback = (op, delta: IMergeTreeDeltaCallbackArgs): void => {\n\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t};\n\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\tclients.B.on(\"delta\", deltaCallback);\n\t\tops.push(\n\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(2, 3), ++seq),\n\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(0, 1), ++seq),\n\t\t\tclients.B.makeOpMessage(clients.B.insertTextLocal(1, \"BB\"), ++seq),\n\t\t);\n\n\t\t// revert to the original callback\n\t\tclients.B.off(\"delta\", deltaCallback);\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\n\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\n\t\tlogger.validate({ baseText: \"BBC\" });\n\t});\n\n\tit(\"Revert remove to empty with annotate\", () => {\n\t\tconst clients = createClientsAtInitialState(\n\t\t\t{ initialState: \"1-23--\", options: {} },\n\t\t\t\"A\",\n\t\t\t\"B\",\n\t\t\t\"C\",\n\t\t);\n\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tlet seq = 0;\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\tconst deltaCallback = (op, delta: IMergeTreeDeltaCallbackArgs): void => {\n\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t};\n\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\tclients.B.on(\"delta\", deltaCallback);\n\t\tops.push(\n\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(0, 2), ++seq),\n\t\t\tclients.B.makeOpMessage(clients.B.annotateRangeLocal(0, 1, { test: 1 }), ++seq),\n\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(0, 1), ++seq),\n\t\t);\n\n\t\t// revert to the original callback\n\t\tclients.B.off(\"delta\", deltaCallback);\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\n\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\n\t\tlogger.validate({ baseText: \"123\" });\n\t});\n\n\tit(\"Revert Local annotate and remove with intersecting remote annotate\", () => {\n\t\tconst clients = createClientsAtInitialState(\n\t\t\t{ initialState: \"1234-----\", options: {} },\n\t\t\t\"A\",\n\t\t\t\"B\",\n\t\t\t\"C\",\n\t\t);\n\n\t\tconst logger = new TestClientLogger(clients.all);\n\t\tlet seq = 0;\n\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[] = [];\n\t\tconst deltaCallback = (\n\t\t\top: IMergeTreeDeltaOpArgs,\n\t\t\tdelta: IMergeTreeDeltaCallbackArgs,\n\t\t): void => {\n\t\t\tif (op.sequencedMessage === undefined) {\n\t\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles);\n\t\t\t}\n\t\t};\n\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\n\t\tclients.B.on(\"delta\", deltaCallback);\n\t\tops.push(\n\t\t\tclients.B.makeOpMessage(clients.B.annotateRangeLocal(0, 4, { test: \"B\" }), ++seq),\n\t\t\tclients.B.makeOpMessage(clients.B.removeRangeLocal(1, 2), ++seq),\n\t\t);\n\n\t\t// revert to the original callback\n\t\tclients.B.off(\"delta\", deltaCallback);\n\n\t\tops.push(\n\t\t\tclients.C.makeOpMessage(clients.C.annotateRangeLocal(3, 4, { test: \"C\" }), ++seq),\n\t\t);\n\n\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\tlogger.validate({ baseText: \"134\" });\n\n\t\ttry {\n\t\t\trevertMergeTreeDeltaRevertibles(clientBDriver, clientB_Revertibles.splice(0));\n\t\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\t} catch (error) {\n\t\t\tthrow logger.addLogsToError(error);\n\t\t}\n\n\t\tlogger.validate({ baseText: \"1234\" });\n\t});\n\n\tdescribe(\"Revertibles work as expected when a pair of markers and text is involved\", () => {\n\t\tfor (const options of generatePairwiseOptions({\n\t\t\trevertMarkerInsert: [true, undefined],\n\t\t\tackMarkerInsert: [true, undefined],\n\t\t\tsplitInsertTextRevertible: [true, undefined],\n\t\t\tackTextInsert: [true, undefined],\n\t\t\tsplitRemoveRevertible: [true, undefined],\n\t\t\tackTextRemove: [true, undefined],\n\t\t\tackUndo: [true, undefined],\n\t\t})) {\n\t\t\tit(JSON.stringify(options), () => {\n\t\t\t\tconst clients = createClientsAtInitialState(\n\t\t\t\t\t{ initialState: \"\", options: {} },\n\t\t\t\t\t\"A\",\n\t\t\t\t\t\"B\",\n\t\t\t\t);\n\n\t\t\t\tconst logger = new TestClientLogger(clients.all);\n\t\t\t\tlet seq = 0;\n\t\t\t\tconst ops: ISequencedDocumentMessage[] = [];\n\n\t\t\t\tconst clientB_Revertibles: MergeTreeDeltaRevertible[][] = [];\n\t\t\t\tconst openNewUndoRedoTransaction = (): number => clientB_Revertibles.unshift([]);\n\t\t\t\t// the test logger uses these callbacks, so preserve it\n\t\t\t\tconst clientBDriver = createRevertDriver(clients.B);\n\t\t\t\tclientBDriver.submitOpCallback = (op): number =>\n\t\t\t\t\tops.push(clients.B.makeOpMessage(op, ++seq));\n\t\t\t\tclients.B.on(\"delta\", (op, delta) => {\n\t\t\t\t\tif (op.sequencedMessage === undefined && clientB_Revertibles.length > 0) {\n\t\t\t\t\t\tappendToMergeTreeDeltaRevertibles(delta, clientB_Revertibles[0]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tlet afterUndoBaseText: string | undefined;\n\t\t\t\tif (options.revertMarkerInsert) {\n\t\t\t\t\topenNewUndoRedoTransaction();\n\t\t\t\t\tafterUndoBaseText ??= clients.B.getText();\n\t\t\t\t}\n\t\t\t\tops.push(\n\t\t\t\t\tclients.B.makeOpMessage(clients.B.insertMarkerLocal(0, ReferenceType.Simple), ++seq),\n\t\t\t\t\tclients.B.makeOpMessage(clients.B.insertMarkerLocal(1, ReferenceType.Simple), ++seq),\n\t\t\t\t);\n\n\t\t\t\tif (options.ackMarkerInsert) {\n\t\t\t\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\t\t\t\tlogger.validate({ baseText: afterUndoBaseText });\n\t\t\t\t}\n\n\t\t\t\tif (options.splitInsertTextRevertible) {\n\t\t\t\t\topenNewUndoRedoTransaction();\n\t\t\t\t\tafterUndoBaseText ??= clients.B.getText();\n\t\t\t\t}\n\t\t\t\tops.push(clients.B.makeOpMessage(clients.B.insertTextLocal(1, \"B\"), ++seq));\n\t\t\t\tif (options.ackTextInsert) {\n\t\t\t\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\t\t\t\tlogger.validate({ baseText: \"B\" });\n\t\t\t\t}\n\n\t\t\t\tif (options.splitRemoveRevertible) {\n\t\t\t\t\topenNewUndoRedoTransaction();\n\t\t\t\t\tafterUndoBaseText ??= clients.B.getText();\n\t\t\t\t}\n\n\t\t\t\tops.push(clients.B.makeOpMessage(clients.B.removeRangeLocal(1, 2), ++seq));\n\t\t\t\tif (options.ackTextRemove) {\n\t\t\t\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\t\t\t\tlogger.validate({ baseText: \"\" });\n\t\t\t\t}\n\n\t\t\t\tconst afterRevertBaseTest = clients.B.getText();\n\t\t\t\ttry {\n\t\t\t\t\tconst reverts = clientB_Revertibles.splice(0);\n\t\t\t\t\tfor (const revert of reverts) {\n\t\t\t\t\t\topenNewUndoRedoTransaction();\n\t\t\t\t\t\trevertMergeTreeDeltaRevertibles(clientBDriver, revert);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow logger.addLogsToError(error);\n\t\t\t\t}\n\n\t\t\t\tif (options.ackUndo) {\n\t\t\t\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\t\t\t\tlogger.validate({ baseText: afterUndoBaseText });\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst reverts = clientB_Revertibles.splice(0);\n\t\t\t\t\tfor (const revert of reverts) {\n\t\t\t\t\t\trevertMergeTreeDeltaRevertibles(clientBDriver, revert);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow logger.addLogsToError(error);\n\t\t\t\t}\n\n\t\t\t\tfor (const op of ops.splice(0)) for (const c of clients.all) c.applyMsg(op);\n\t\t\t\tlogger.validate({ baseText: afterRevertBaseTest });\n\t\t\t});\n\t\t}\n\t});\n});\n"]}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { strict as assert } from "node:assert";
|
|
6
|
+
import { makeRandom } from "@fluid-private/stochastic-test-utils";
|
|
6
7
|
import { TrackingGroup } from "../mergeTreeTracking.js";
|
|
7
8
|
import { ReferenceType } from "../ops.js";
|
|
8
9
|
import { toMergeNodeInfo } from "../segmentInfos.js";
|
|
@@ -71,6 +72,26 @@ describe("SortedSegmentSet", () => {
|
|
|
71
72
|
assert.equal(set.size, segmentCount);
|
|
72
73
|
validateSet(client, set, (i) => toMergeNodeInfo(i)?.ordinal);
|
|
73
74
|
});
|
|
75
|
+
describe("SortedSegmentSet of local references", () => {
|
|
76
|
+
it("Inserts in order", () => {
|
|
77
|
+
const random = makeRandom(0);
|
|
78
|
+
const refsAtAllPositions = [];
|
|
79
|
+
for (let i = 0; i < client.getLength(); i++) {
|
|
80
|
+
const { segment, offset } = client.getContainingSegment(i);
|
|
81
|
+
assert(segment !== undefined);
|
|
82
|
+
assert(offset !== undefined);
|
|
83
|
+
refsAtAllPositions.push(client.createLocalReferencePosition(segment, offset, ReferenceType.SlideOnRemove, undefined));
|
|
84
|
+
}
|
|
85
|
+
random.shuffle(refsAtAllPositions);
|
|
86
|
+
const segmentSet = new SortedSegmentSet();
|
|
87
|
+
for (const ref of refsAtAllPositions) {
|
|
88
|
+
segmentSet.addOrUpdate(ref);
|
|
89
|
+
}
|
|
90
|
+
// Validate that the set is sorted
|
|
91
|
+
const refsBackToPositions = segmentSet.items.map((ref) => client.localReferencePositionToPosition(ref));
|
|
92
|
+
assert.deepEqual(refsBackToPositions, Array.from({ length: client.getLength() }, (_, i) => i));
|
|
93
|
+
});
|
|
94
|
+
});
|
|
74
95
|
it("SortedSegmentSet of local references", () => {
|
|
75
96
|
// using a sorted segment set directly creates problems,
|
|
76
97
|
// as we don't correctly split, or merge, so leverage
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sortedSegmentSet.spec.js","sourceRoot":"","sources":["../../src/test/sortedSegmentSet.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { LocalReferencePosition } from \"../localReference.js\";\nimport { ISegment, type ISegmentPrivate } from \"../mergeTreeNodes.js\";\nimport { TrackingGroup } from \"../mergeTreeTracking.js\";\nimport { ReferenceType } from \"../ops.js\";\nimport { toMergeNodeInfo } from \"../segmentInfos.js\";\nimport { SortedSegmentSet, SortedSegmentSetItem } from \"../sortedSegmentSet.js\";\n\nimport { TestClient } from \"./testClient.js\";\nconst segmentCount = 15;\n\nfunction validateSorted<T extends SortedSegmentSetItem>(\n\tset: SortedSegmentSet<T>,\n\tgetOrdinal: (item: T) => string | undefined,\n\tprefix: string,\n): void {\n\tfor (let i = 0; i < set.size - 1; i++) {\n\t\tconst a = getOrdinal(set.items[i]);\n\t\tconst b = getOrdinal(set.items[i + 1]);\n\t\tassert(a !== undefined, `${prefix}: Undefined ordinal ${i}`);\n\t\tassert(b !== undefined, `${prefix}: Undefined ordinal ${i + 1}`);\n\t\tassert(a <= b, `${prefix}: Not sorted at item ${i}`);\n\t}\n}\n\nfunction validateSet<T extends SortedSegmentSetItem>(\n\tclient: TestClient,\n\tset: SortedSegmentSet<T>,\n\tgetOrdinal: (item: T) => string | undefined,\n): void {\n\tvalidateSorted(set, getOrdinal, \"initial\");\n\n\t// add content to shift ordinals in tree\n\tfor (let i = 0; i < segmentCount * 5; i++) {\n\t\tclient.insertTextLocal((i * 3) % client.getLength(), `X`);\n\t}\n\tvalidateSorted(set, getOrdinal, \"after insert\");\n\n\tfor (let i = set.size; set.size > 0; i += set.size) {\n\t\t// jump around the list a bit, so its not just an in-order remove\n\t\tconst item = set.items[i % set.size];\n\t\tassert.equal(set.remove(item), true, \"remove failed\");\n\t\tassert.equal(set.has(item), false);\n\t\tvalidateSorted(set, getOrdinal, \"during remove\");\n\t}\n}\n\ndescribe(\"SortedSegmentSet\", () => {\n\tconst localUserLongId = \"localUser\";\n\tlet client: TestClient;\n\tbeforeEach(() => {\n\t\tclient = new TestClient();\n\t\tfor (let i = 0; i < segmentCount; i++) {\n\t\t\tclient.insertTextLocal(client.getLength(), i.toString()[0].repeat(i + 1));\n\t\t}\n\t\tclient.startOrUpdateCollaboration(localUserLongId);\n\t});\n\n\tit(\"SortedSegmentSet of objects with segments\", () => {\n\t\tconst set = new SortedSegmentSet<{ segment: ISegment }>();\n\t\tfor (let i = 0; i < client.getLength(); i++) {\n\t\t\tfor (const pos of [i, client.getLength() - 1 - i]) {\n\t\t\t\tconst segment = client.getContainingSegment<ISegmentPrivate>(pos).segment;\n\t\t\t\tassert(segment);\n\t\t\t\tconst item = { segment };\n\t\t\t\tassert.equal(set.has(item), false);\n\t\t\t\tset.addOrUpdate(item);\n\t\t\t\tassert.equal(set.has(item), true);\n\t\t\t}\n\t\t}\n\t\tassert.equal(set.size, client.getLength() * 2);\n\t\tvalidateSet(client, set, (i) => toMergeNodeInfo(i.segment)?.ordinal);\n\t});\n\n\tit(\"SortedSegmentSet of segments\", () => {\n\t\tconst set = new SortedSegmentSet();\n\t\tfor (let i = 0; i < client.getLength(); i++) {\n\t\t\tfor (const pos of [i, client.getLength() - 1 - i]) {\n\t\t\t\tconst segment = client.getContainingSegment<ISegmentPrivate>(pos).segment;\n\t\t\t\tassert(segment);\n\t\t\t\tset.addOrUpdate(segment);\n\t\t\t\tassert.equal(set.has(segment), true);\n\t\t\t}\n\t\t}\n\t\tassert.equal(set.size, segmentCount);\n\t\tvalidateSet(client, set, (i) => toMergeNodeInfo(i)?.ordinal);\n\t});\n\n\tit(\"SortedSegmentSet of local references\", () => {\n\t\t// using a sorted segment set directly creates problems,\n\t\t// as we don't correctly split, or merge, so leverage\n\t\t// the tracking group for correct behavior in those case\n\t\t// and spy it's internal set\n\t\tconst set = new TrackingGroup();\n\t\tfor (let i = 0; i < client.getLength(); i++) {\n\t\t\tfor (const pos of [i, client.getLength() - 1 - i]) {\n\t\t\t\tconst segmentInfo = client.getContainingSegment<ISegmentPrivate>(pos);\n\t\t\t\tassert(segmentInfo?.segment);\n\t\t\t\tconst lref = client.createLocalReferencePosition(\n\t\t\t\t\tsegmentInfo.segment,\n\t\t\t\t\tsegmentInfo.offset,\n\t\t\t\t\tReferenceType.SlideOnRemove,\n\t\t\t\t\tundefined,\n\t\t\t\t);\n\t\t\t\tassert.equal(set.has(lref), false);\n\t\t\t\tset.link(lref);\n\t\t\t\tassert.equal(set.has(lref), true);\n\t\t\t}\n\t\t}\n\t\tassert.equal(set.size, client.getLength() * 2);\n\t\tvalidateSet<LocalReferencePosition>(\n\t\t\tclient,\n\t\t\t// Cast to any because we are validating a set of local references, but the instantiated type of trackedSet\n\t\t\t// on TrackingGroup is SortedSegmentSet<Trackable>.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\t(set as any).trackedSet,\n\t\t\t(i) => toMergeNodeInfo(i.getSegment())?.ordinal,\n\t\t);\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"file":"sortedSegmentSet.spec.js","sourceRoot":"","sources":["../../src/test/sortedSegmentSet.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { makeRandom } from \"@fluid-private/stochastic-test-utils\";\n\nimport { LocalReferencePosition } from \"../localReference.js\";\nimport { ISegment, type ISegmentPrivate } from \"../mergeTreeNodes.js\";\nimport { TrackingGroup } from \"../mergeTreeTracking.js\";\nimport { ReferenceType } from \"../ops.js\";\nimport { toMergeNodeInfo } from \"../segmentInfos.js\";\nimport { SortedSegmentSet, SortedSegmentSetItem } from \"../sortedSegmentSet.js\";\n\nimport { TestClient } from \"./testClient.js\";\nconst segmentCount = 15;\n\nfunction validateSorted<T extends SortedSegmentSetItem>(\n\tset: SortedSegmentSet<T>,\n\tgetOrdinal: (item: T) => string | undefined,\n\tprefix: string,\n): void {\n\tfor (let i = 0; i < set.size - 1; i++) {\n\t\tconst a = getOrdinal(set.items[i]);\n\t\tconst b = getOrdinal(set.items[i + 1]);\n\t\tassert(a !== undefined, `${prefix}: Undefined ordinal ${i}`);\n\t\tassert(b !== undefined, `${prefix}: Undefined ordinal ${i + 1}`);\n\t\tassert(a <= b, `${prefix}: Not sorted at item ${i}`);\n\t}\n}\n\nfunction validateSet<T extends SortedSegmentSetItem>(\n\tclient: TestClient,\n\tset: SortedSegmentSet<T>,\n\tgetOrdinal: (item: T) => string | undefined,\n): void {\n\tvalidateSorted(set, getOrdinal, \"initial\");\n\n\t// add content to shift ordinals in tree\n\tfor (let i = 0; i < segmentCount * 5; i++) {\n\t\tclient.insertTextLocal((i * 3) % client.getLength(), `X`);\n\t}\n\tvalidateSorted(set, getOrdinal, \"after insert\");\n\n\tfor (let i = set.size; set.size > 0; i += set.size) {\n\t\t// jump around the list a bit, so its not just an in-order remove\n\t\tconst item = set.items[i % set.size];\n\t\tassert.equal(set.remove(item), true, \"remove failed\");\n\t\tassert.equal(set.has(item), false);\n\t\tvalidateSorted(set, getOrdinal, \"during remove\");\n\t}\n}\n\ndescribe(\"SortedSegmentSet\", () => {\n\tconst localUserLongId = \"localUser\";\n\tlet client: TestClient;\n\tbeforeEach(() => {\n\t\tclient = new TestClient();\n\t\tfor (let i = 0; i < segmentCount; i++) {\n\t\t\tclient.insertTextLocal(client.getLength(), i.toString()[0].repeat(i + 1));\n\t\t}\n\t\tclient.startOrUpdateCollaboration(localUserLongId);\n\t});\n\n\tit(\"SortedSegmentSet of objects with segments\", () => {\n\t\tconst set = new SortedSegmentSet<{ segment: ISegment }>();\n\t\tfor (let i = 0; i < client.getLength(); i++) {\n\t\t\tfor (const pos of [i, client.getLength() - 1 - i]) {\n\t\t\t\tconst segment = client.getContainingSegment<ISegmentPrivate>(pos).segment;\n\t\t\t\tassert(segment);\n\t\t\t\tconst item = { segment };\n\t\t\t\tassert.equal(set.has(item), false);\n\t\t\t\tset.addOrUpdate(item);\n\t\t\t\tassert.equal(set.has(item), true);\n\t\t\t}\n\t\t}\n\t\tassert.equal(set.size, client.getLength() * 2);\n\t\tvalidateSet(client, set, (i) => toMergeNodeInfo(i.segment)?.ordinal);\n\t});\n\n\tit(\"SortedSegmentSet of segments\", () => {\n\t\tconst set = new SortedSegmentSet();\n\t\tfor (let i = 0; i < client.getLength(); i++) {\n\t\t\tfor (const pos of [i, client.getLength() - 1 - i]) {\n\t\t\t\tconst segment = client.getContainingSegment<ISegmentPrivate>(pos).segment;\n\t\t\t\tassert(segment);\n\t\t\t\tset.addOrUpdate(segment);\n\t\t\t\tassert.equal(set.has(segment), true);\n\t\t\t}\n\t\t}\n\t\tassert.equal(set.size, segmentCount);\n\t\tvalidateSet(client, set, (i) => toMergeNodeInfo(i)?.ordinal);\n\t});\n\n\tdescribe(\"SortedSegmentSet of local references\", () => {\n\t\tit(\"Inserts in order\", () => {\n\t\t\tconst random = makeRandom(0);\n\t\t\tconst refsAtAllPositions: LocalReferencePosition[] = [];\n\t\t\tfor (let i = 0; i < client.getLength(); i++) {\n\t\t\t\tconst { segment, offset } = client.getContainingSegment<ISegmentPrivate>(i);\n\t\t\t\tassert(segment !== undefined);\n\t\t\t\tassert(offset !== undefined);\n\t\t\t\trefsAtAllPositions.push(\n\t\t\t\t\tclient.createLocalReferencePosition(\n\t\t\t\t\t\tsegment,\n\t\t\t\t\t\toffset,\n\t\t\t\t\t\tReferenceType.SlideOnRemove,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\trandom.shuffle(refsAtAllPositions);\n\t\t\tconst segmentSet = new SortedSegmentSet<LocalReferencePosition>();\n\t\t\tfor (const ref of refsAtAllPositions) {\n\t\t\t\tsegmentSet.addOrUpdate(ref);\n\t\t\t}\n\n\t\t\t// Validate that the set is sorted\n\t\t\tconst refsBackToPositions = segmentSet.items.map((ref) =>\n\t\t\t\tclient.localReferencePositionToPosition(ref),\n\t\t\t);\n\t\t\tassert.deepEqual(\n\t\t\t\trefsBackToPositions,\n\t\t\t\tArray.from({ length: client.getLength() }, (_, i) => i),\n\t\t\t);\n\t\t});\n\t});\n\n\tit(\"SortedSegmentSet of local references\", () => {\n\t\t// using a sorted segment set directly creates problems,\n\t\t// as we don't correctly split, or merge, so leverage\n\t\t// the tracking group for correct behavior in those case\n\t\t// and spy it's internal set\n\t\tconst set = new TrackingGroup();\n\t\tfor (let i = 0; i < client.getLength(); i++) {\n\t\t\tfor (const pos of [i, client.getLength() - 1 - i]) {\n\t\t\t\tconst segmentInfo = client.getContainingSegment<ISegmentPrivate>(pos);\n\t\t\t\tassert(segmentInfo?.segment);\n\t\t\t\tconst lref = client.createLocalReferencePosition(\n\t\t\t\t\tsegmentInfo.segment,\n\t\t\t\t\tsegmentInfo.offset,\n\t\t\t\t\tReferenceType.SlideOnRemove,\n\t\t\t\t\tundefined,\n\t\t\t\t);\n\t\t\t\tassert.equal(set.has(lref), false);\n\t\t\t\tset.link(lref);\n\t\t\t\tassert.equal(set.has(lref), true);\n\t\t\t}\n\t\t}\n\t\tassert.equal(set.size, client.getLength() * 2);\n\t\tvalidateSet<LocalReferencePosition>(\n\t\t\tclient,\n\t\t\t// Cast to any because we are validating a set of local references, but the instantiated type of trackedSet\n\t\t\t// on TrackingGroup is SortedSegmentSet<Trackable>.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\t(set as any).trackedSet,\n\t\t\t(i) => toMergeNodeInfo(i.getSegment())?.ordinal,\n\t\t);\n\t});\n});\n"]}
|
package/lib/test/testClient.d.ts
CHANGED
|
@@ -61,7 +61,7 @@ export declare class TestClient extends Client {
|
|
|
61
61
|
text: string;
|
|
62
62
|
pos: number;
|
|
63
63
|
} | undefined;
|
|
64
|
-
debugDumpTree(tree: MergeTree):
|
|
64
|
+
debugDumpTree(tree: MergeTree): string[];
|
|
65
65
|
/**
|
|
66
66
|
* Rebases a (local) position from the perspective `{ seq: seqNumberFrom, localSeq }` to the perspective
|
|
67
67
|
* of the current sequence number. This is desirable when rebasing operations for reconnection. Perform
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testClient.d.ts","sourceRoot":"","sources":["../../src/test/testClient.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"testClient.d.ts","sourceRoot":"","sources":["../../src/test/testClient.ts"],"names":[],"mappings":"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"}
|
package/lib/test/testClient.js
CHANGED
|
@@ -188,6 +188,7 @@ export class TestClient extends Client {
|
|
|
188
188
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
189
189
|
test.push(`${prefixes.join(",")}:${segment.text}`);
|
|
190
190
|
});
|
|
191
|
+
return test;
|
|
191
192
|
}
|
|
192
193
|
/**
|
|
193
194
|
* Rebases a (local) position from the perspective `{ seq: seqNumberFrom, localSeq }` to the perspective
|