"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
const node_assert_1 = require("node:assert");
const stochastic_test_utils_1 = require("@fluid-private/stochastic-test-utils");
const constants_js_1 = require("../constants.js");
const mergeTreeNodes_js_1 = require("../mergeTreeNodes.js");
const ops_js_1 = require("../ops.js");
const referencePositions_js_1 = require("../referencePositions.js");
const textSegment_js_1 = require("../textSegment.js");
const testClient_js_1 = require("./testClient.js");
const testClientLogger_js_1 = require("./testClientLogger.js");
describe("TestClient", () => {
    const localUserLongId = "localUser";
    let client;
    beforeEach(() => {
        client = new testClient_js_1.TestClient();
        client.mergeTree.insertSegments(0, [textSegment_js_1.TextSegment.make("")], client.mergeTree.localPerspective, client.mergeTree.collabWindow.mintNextLocalOperationStamp(), undefined);
        client.startOrUpdateCollaboration(localUserLongId);
    });
    describe(".searchForMarker", () => {
        it("Should return marker at the search position in either direction", () => {
            client.insertTextLocal(0, "abcdefg");
            client.insertMarkerLocal(4, ops_js_1.ReferenceType.Tile, {
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "marker",
                [referencePositions_js_1.reservedTileLabelsKey]: ["Eop"],
            });
            node_assert_1.strict.equal(client.getLength(), 8);
            const marker1 = client.searchForMarker(4, "Eop", true);
            (0, node_assert_1.strict)(marker1, "Returned marker undefined.");
            let exp = client.mergeTree.referencePositionToLocalPosition(marker1, constants_js_1.UniversalSequenceNumber, client.getClientId());
            node_assert_1.strict.equal(exp, 4, "Marker with label not at expected position");
            const marker2 = client.searchForMarker(4, "Eop", false);
            (0, node_assert_1.strict)(marker2, "Returned marker undefined.");
            exp = client.mergeTree.referencePositionToLocalPosition(marker2, constants_js_1.UniversalSequenceNumber, client.getClientId());
            node_assert_1.strict.equal(exp, 4, "Marker with label not at expected position");
        });
        it("Should return the marker at the search position in either direction from multiple blocks", () => {
            client.insertTextLocal(0, "abcd");
            client.insertTextLocal(4, "efg");
            client.insertMarkerLocal(4, ops_js_1.ReferenceType.Tile, {
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "marker",
                [referencePositions_js_1.reservedTileLabelsKey]: ["Eop"],
            });
            node_assert_1.strict.equal(client.getLength(), 8);
            const marker1 = client.searchForMarker(4, "Eop", true);
            (0, node_assert_1.strict)(marker1, "Returned marker undefined.");
            let exp = client.mergeTree.referencePositionToLocalPosition(marker1, constants_js_1.UniversalSequenceNumber, client.getClientId());
            node_assert_1.strict.equal(exp, 4, "Marker with label not at expected position");
            const marker2 = client.searchForMarker(4, "Eop", false);
            (0, node_assert_1.strict)(marker2, "Returned marker undefined.");
            exp = client.mergeTree.referencePositionToLocalPosition(marker2, constants_js_1.UniversalSequenceNumber, client.getClientId());
            node_assert_1.strict.equal(exp, 4, "Marker with label not at expected position");
        });
        it("Should be able to find forward marker position based on label", () => {
            const markerLabel = "EOP";
            client.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                [referencePositions_js_1.reservedTileLabelsKey]: [markerLabel],
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "some-id",
            });
            client.insertTextLocal(0, "abc");
            node_assert_1.strict.equal(client.getLength(), 4, "length not expected");
            const marker = client.searchForMarker(0, markerLabel, true);
            (0, node_assert_1.strict)(marker, "Returned marker undefined.");
            const exp = client.mergeTree.referencePositionToLocalPosition(marker, constants_js_1.UniversalSequenceNumber, client.getClientId());
            node_assert_1.strict.equal(exp, 3, "Marker with label not at expected position");
        });
        it("Should be able to find forward marker position based on label from client with single marker", () => {
            const markerLabel = "EOP";
            client.insertTextLocal(0, "abc d");
            client.insertMarkerLocal(1, ops_js_1.ReferenceType.Tile, {
                [referencePositions_js_1.reservedTileLabelsKey]: [markerLabel],
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "some-id",
            });
            node_assert_1.strict.equal(client.getLength(), 6, "length not expected");
            const marker = client.searchForMarker(0, markerLabel, true);
            (0, node_assert_1.strict)(marker, "Returned marker undefined.");
            const exp = client.mergeTree.referencePositionToLocalPosition(marker, constants_js_1.UniversalSequenceNumber, client.getClientId());
            node_assert_1.strict.equal(exp, 1, "Marker with label not at expected position");
        });
        it("Should be able to find backward marker position based on label from client with multiple marker", () => {
            const markerLabel = "EOP";
            client.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                [referencePositions_js_1.reservedTileLabelsKey]: [markerLabel],
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "some-id",
            });
            client.insertTextLocal(0, "abc d");
            client.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                [referencePositions_js_1.reservedTileLabelsKey]: [markerLabel],
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "some-id",
            });
            client.insertTextLocal(7, "ef");
            client.insertMarkerLocal(8, ops_js_1.ReferenceType.Tile, {
                [referencePositions_js_1.reservedTileLabelsKey]: [markerLabel],
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "some-id",
            });
            node_assert_1.strict.equal(client.getLength(), 10, "length not expected");
            const marker = client.searchForMarker(5, markerLabel, false);
            (0, node_assert_1.strict)(marker, "Returned marker undefined.");
            const exp = client.mergeTree.referencePositionToLocalPosition(marker, constants_js_1.UniversalSequenceNumber, client.getClientId());
            node_assert_1.strict.equal(exp, 0, "Marker with label not at expected position");
        });
        it("Should be able to find forward marker position from client with multiple marker", () => {
            const markerLabel = "EOP";
            client.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                [referencePositions_js_1.reservedTileLabelsKey]: [markerLabel],
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "some-id",
            });
            client.insertTextLocal(0, "abc d");
            client.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                [referencePositions_js_1.reservedTileLabelsKey]: [markerLabel],
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "some-id",
            });
            client.insertTextLocal(7, "ef");
            client.insertMarkerLocal(8, ops_js_1.ReferenceType.Tile, {
                [referencePositions_js_1.reservedTileLabelsKey]: [markerLabel],
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "some-id",
            });
            node_assert_1.strict.equal(client.getLength(), 10, "length not expected");
            const marker = client.searchForMarker(5, markerLabel, true);
            (0, node_assert_1.strict)(marker, "Returned marker undefined.");
            const exp = client.mergeTree.referencePositionToLocalPosition(marker, constants_js_1.UniversalSequenceNumber, client.getClientId());
            node_assert_1.strict.equal(exp, 6, "Marker with label not at expected position");
        });
        it("Should be able to find forward marker position with multiple segments and markers", () => {
            const markerLabel = "EOP";
            for (const [i, _] of Array.from({ length: mergeTreeNodes_js_1.MaxNodesInBlock ** 3 * 2 }).entries())
                client.insertTextLocal(0, i.toString());
            // pad the string with markers on both ends so we never get undefined solely for convenience of this test
            for (let i = 0; i <= client.getLength(); i += 3) {
                client.insertMarkerLocal(i, ops_js_1.ReferenceType.Tile, {
                    [referencePositions_js_1.reservedTileLabelsKey]: [markerLabel],
                    [mergeTreeNodes_js_1.reservedMarkerIdKey]: "some-id",
                });
            }
            for (let index = 0; index < client.getLength(); index++) {
                const marker = client.searchForMarker(index, markerLabel, true);
                (0, node_assert_1.strict)(marker, `Returned marker undefined @ ${index}.`);
                const exp = client.mergeTree.referencePositionToLocalPosition(marker, constants_js_1.UniversalSequenceNumber, client.getClientId());
                const offset = index % 3 === 0 ? index % 3 : 3 - (index % 3);
                node_assert_1.strict.equal(exp, index + offset, "Marker with label not at expected position");
            }
        });
        it("Should be able to find backward marker position with multiple segments and markers", () => {
            const markerLabel = "EOP";
            for (const [i, _] of Array.from({ length: mergeTreeNodes_js_1.MaxNodesInBlock ** 3 * 2 }).entries())
                client.insertTextLocal(0, i.toString());
            // pad the string with markers on both ends so we never get undefined solely for convenience of this test
            for (let i = 0; i <= client.getLength(); i += 3) {
                client.insertMarkerLocal(i, ops_js_1.ReferenceType.Tile, {
                    [referencePositions_js_1.reservedTileLabelsKey]: [markerLabel],
                    [mergeTreeNodes_js_1.reservedMarkerIdKey]: "some-id",
                });
            }
            for (let index = client.getLength() - 1; index >= 0; index--) {
                const marker = client.searchForMarker(index, markerLabel, false);
                (0, node_assert_1.strict)(marker, `Returned marker undefined @ ${index}.`);
                const exp = client.mergeTree.referencePositionToLocalPosition(marker, constants_js_1.UniversalSequenceNumber, client.getClientId());
                node_assert_1.strict.equal(exp, index - (index % 3), "Marker with label not at expected position");
            }
        });
        it("Should be able to find distant forward marker", () => {
            const markerLabel = "EOP";
            for (const [i, _] of Array.from({ length: mergeTreeNodes_js_1.MaxNodesInBlock ** 3 * 2 }).entries())
                client.insertTextLocal(0, i.toString());
            for (let i = 10; i > 1; i -= 2) {
                client.insertMarkerLocal(client.getLength() - i, ops_js_1.ReferenceType.Tile, {
                    [referencePositions_js_1.reservedTileLabelsKey]: [markerLabel],
                    [mergeTreeNodes_js_1.reservedMarkerIdKey]: "some-id",
                });
            }
            for (let index = 0; index < client.getLength(); index++) {
                const exp = client.slowSearchForMarker(index, markerLabel, true);
                const actual = client.searchForMarker(index, markerLabel, true);
                node_assert_1.strict.equal(exp, actual, "Marker with label not at expected position");
            }
        });
        it("Should be able to find distant backward marker", () => {
            const markerLabel = "EOP";
            for (const [i, _] of Array.from({ length: mergeTreeNodes_js_1.MaxNodesInBlock ** 3 * 2 }).entries())
                client.insertTextLocal(0, i.toString());
            for (let i = 10; i > 1; i -= 2) {
                client.insertMarkerLocal(client.getLength() - i, ops_js_1.ReferenceType.Tile, {
                    [referencePositions_js_1.reservedTileLabelsKey]: [markerLabel],
                    [mergeTreeNodes_js_1.reservedMarkerIdKey]: "some-id",
                });
            }
            for (let index = client.getLength() - 1; index >= 0; index--) {
                const exp = client.slowSearchForMarker(index, markerLabel, false);
                const actual = client.searchForMarker(index, markerLabel, false);
                node_assert_1.strict.equal(exp, actual, "Marker with label not at expected position");
            }
        });
        it("Should match results from forwardExcursion for many segments", () => {
            const markerLabel = "EOP";
            for (const [i, _] of Array.from({ length: mergeTreeNodes_js_1.MaxNodesInBlock * 3 }).entries())
                client.insertTextLocal(0, i.toString());
            const random = (0, stochastic_test_utils_1.makeRandom)(0xdeadbeef, 0xfeedbed, client.getLength());
            for (let i = 0; i <= client.getLength() / 6; i++) {
                const pos = random.integer(0, client.getLength() - 1);
                client.insertMarkerLocal(pos, ops_js_1.ReferenceType.Tile, {
                    [referencePositions_js_1.reservedTileLabelsKey]: [markerLabel],
                    [mergeTreeNodes_js_1.reservedMarkerIdKey]: "some-id",
                });
            }
            for (let index = 0; index < client.getLength(); index++) {
                const exp = client.slowSearchForMarker(index, markerLabel, true);
                const actual = client.searchForMarker(index, markerLabel, true);
                node_assert_1.strict.equal(exp, actual, "Marker with label not at expected position");
            }
        });
        it("Should match results from backwardExcursion for many segments", () => {
            const markerLabel = "EOP";
            for (const [i, _] of Array.from({ length: mergeTreeNodes_js_1.MaxNodesInBlock * 3 }).entries())
                client.insertTextLocal(0, i.toString());
            const random = (0, stochastic_test_utils_1.makeRandom)(0xdeadbeef, 0xfeedbed, client.getLength());
            for (let i = 0; i <= client.getLength() / 6; i++) {
                const pos = random.integer(0, client.getLength() - 1);
                client.insertMarkerLocal(pos, ops_js_1.ReferenceType.Tile, {
                    [referencePositions_js_1.reservedTileLabelsKey]: [markerLabel],
                    [mergeTreeNodes_js_1.reservedMarkerIdKey]: "some-id",
                });
            }
            for (let index = 0; index < client.getLength(); index++) {
                const exp = client.slowSearchForMarker(index, markerLabel, false);
                const actual = client.searchForMarker(index, markerLabel, false);
                node_assert_1.strict.equal(exp, actual, "Marker with label not at expected position");
            }
        });
        it("Should be able to find marker from client with text length 1", () => {
            const markerLabel = "EOP";
            client.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                [referencePositions_js_1.reservedTileLabelsKey]: [markerLabel],
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "some-id",
            });
            node_assert_1.strict.equal(client.getLength(), 1, "length not expected");
            const marker = client.searchForMarker(client.getLength() - 1, markerLabel, false);
            (0, node_assert_1.strict)(marker, "Returned marker undefined.");
            let exp = client.mergeTree.referencePositionToLocalPosition(marker, constants_js_1.UniversalSequenceNumber, client.getClientId());
            node_assert_1.strict.equal(exp, 0, "Marker with label not at expected position");
            const marker1 = client.searchForMarker(0, markerLabel, true);
            (0, node_assert_1.strict)(marker1, "Returned marker undefined.");
            exp = client.mergeTree.referencePositionToLocalPosition(marker, constants_js_1.UniversalSequenceNumber, client.getClientId());
            node_assert_1.strict.equal(exp, 0, "Marker with label not at expected position");
        });
        it("Should not be able to find marker position with index out of bound", () => {
            const markerLabel = "EOP";
            client.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                [referencePositions_js_1.reservedTileLabelsKey]: [markerLabel],
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "some-id",
            });
            client.insertTextLocal(0, "abc");
            node_assert_1.strict.equal(client.getLength(), 4, "length not expected");
            const marker = client.searchForMarker(5, markerLabel, true);
            node_assert_1.strict.equal(marker, undefined, "Returned marker should be undefined.");
            const marker1 = client.searchForMarker(5, markerLabel, false);
            node_assert_1.strict.equal(marker1, undefined, "Returned marker should be undefined.");
            const marker2 = client.searchForMarker(-1, markerLabel, false);
            node_assert_1.strict.equal(marker2, undefined, "Returned marker should be undefined.");
        });
        it("Should be able to find a deleted and rolled back marker", () => {
            client.insertTextLocal(0, "abc");
            client.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "marker",
                [referencePositions_js_1.reservedTileLabelsKey]: ["Eop"],
            });
            client.removeRangeLocal(0, 1);
            client.rollback({ type: ops_js_1.MergeTreeDeltaType.REMOVE }, client.peekPendingSegmentGroups());
            const marker = client.searchForMarker(0, "Eop", true);
            (0, node_assert_1.strict)(marker, "Returned marker undefined.");
            const exp = client.mergeTree.referencePositionToLocalPosition(marker, constants_js_1.UniversalSequenceNumber, client.getClientId());
            node_assert_1.strict.equal(exp, 0, "Marker with label not at expected position");
        });
        it("Should not be able to find an inserted and rolled back marker", () => {
            client.insertTextLocal(0, "abc");
            client.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "marker",
                [referencePositions_js_1.reservedTileLabelsKey]: ["Eop"],
            });
            client.rollback({ type: ops_js_1.MergeTreeDeltaType.INSERT }, client.peekPendingSegmentGroups());
            const marker = client.searchForMarker(0, "Eop", true);
            node_assert_1.strict.equal(marker, undefined, "Returned marker should be undefined.");
        });
        it("Should be able to find a marker at 0 searching at 0 in both directions", () => {
            client.insertTextLocal(0, "abc");
            client.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "marker",
                [referencePositions_js_1.reservedTileLabelsKey]: ["Eop"],
            });
            node_assert_1.strict.equal(client.getLength(), 4);
            const marker = client.searchForMarker(0, "Eop", true);
            (0, node_assert_1.strict)(marker, "Returned marker undefined.");
            let exp = client.mergeTree.referencePositionToLocalPosition(marker, constants_js_1.UniversalSequenceNumber, client.getClientId());
            node_assert_1.strict.equal(exp, 0, "Marker with label not at expected position");
            const marker2 = client.searchForMarker(0, "Eop", false);
            (0, node_assert_1.strict)(marker2, "Returned marker undefined.");
            exp = client.mergeTree.referencePositionToLocalPosition(marker2, constants_js_1.UniversalSequenceNumber, client.getClientId());
            node_assert_1.strict.equal(exp, 0, "Marker with label not at expected position");
        });
        it("Should be able to find a marker at length-1 searching at length-1 in both directions", () => {
            client.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "marker",
                [referencePositions_js_1.reservedTileLabelsKey]: ["Eop"],
            });
            client.insertTextLocal(0, "abc");
            const length = client.getLength();
            node_assert_1.strict.equal(length, 4);
            const marker = client.searchForMarker(length - 1, "Eop", true);
            (0, node_assert_1.strict)(marker, "Returned marker undefined.");
            let exp = client.mergeTree.referencePositionToLocalPosition(marker, constants_js_1.UniversalSequenceNumber, client.getClientId());
            node_assert_1.strict.equal(exp, length - 1, "Marker with label not at expected position");
            const marker2 = client.searchForMarker(length - 1, "Eop", false);
            (0, node_assert_1.strict)(marker2, "Returned marker undefined.");
            exp = client.mergeTree.referencePositionToLocalPosition(marker2, constants_js_1.UniversalSequenceNumber, client.getClientId());
            node_assert_1.strict.equal(exp, length - 1, "Marker with label not at expected position");
        });
        it("Should return undefined when searching past the end of a string length 1", () => {
            client.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "marker",
                [referencePositions_js_1.reservedTileLabelsKey]: ["Eop"],
            });
            node_assert_1.strict.equal(client.getLength(), 1);
            const marker = client.searchForMarker(client.getLength(), "Eop", true);
            node_assert_1.strict.equal(marker, undefined, "Returned marker should be undefined.");
        });
        it("Should return undefined when searching before the start of a string length 1", () => {
            client.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "marker",
                [referencePositions_js_1.reservedTileLabelsKey]: ["Eop"],
            });
            node_assert_1.strict.equal(client.getLength(), 1);
            const marker = client.searchForMarker(-1, "Eop", false);
            node_assert_1.strict.equal(marker, undefined, "Returned marker should be undefined.");
        });
        it("Should return undefined when searching past the end of a string length > 1", () => {
            client.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "marker",
                [referencePositions_js_1.reservedTileLabelsKey]: ["Eop"],
            });
            client.insertTextLocal(0, "abc");
            node_assert_1.strict.equal(client.getLength(), 4);
            const marker = client.searchForMarker(client.getLength(), "Eop", true);
            node_assert_1.strict.equal(marker, undefined, "Returned marker should be undefined.");
        });
        it("Should return undefined when searching before the start of a string length > 1", () => {
            client.insertTextLocal(0, "abc");
            client.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "marker",
                [referencePositions_js_1.reservedTileLabelsKey]: ["Eop"],
            });
            node_assert_1.strict.equal(client.getLength(), 4);
            const marker = client.searchForMarker(-1, "Eop", false);
            node_assert_1.strict.equal(marker, undefined, "Returned marker should be undefined.");
        });
        it("Should return undefined when trying to find marker from text without the specified marker", () => {
            const markerLabel = "EOP";
            client.insertTextLocal(0, "abc");
            node_assert_1.strict.equal(client.getLength(), 3, "length not expected");
            const marker = client.searchForMarker(1, markerLabel);
            node_assert_1.strict.equal(marker, undefined, "Returned marker should be undefined.");
            const marker1 = client.searchForMarker(1, markerLabel, false);
            node_assert_1.strict.equal(marker1, undefined, "Returned marker should be undefined.");
        });
        it("Should return undefined when trying to find marker from null text", () => {
            const markerLabel = "EOP";
            const marker = client.searchForMarker(1, markerLabel);
            node_assert_1.strict.equal(marker, undefined, "Returned marker should be undefined.");
            const marker1 = client.searchForMarker(1, markerLabel, false);
            node_assert_1.strict.equal(marker1, undefined, "Returned marker should be undefined.");
        });
        it("Should return undefined when trying to find a removed marker", () => {
            client.insertTextLocal(0, "abc");
            client.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                [mergeTreeNodes_js_1.reservedMarkerIdKey]: "marker",
                [referencePositions_js_1.reservedTileLabelsKey]: ["Eop"],
            });
            node_assert_1.strict.equal(client.getLength(), 4, "length not expected");
            client.removeRangeLocal(0, 1);
            node_assert_1.strict.equal(client.getLength(), 3, "length not expected");
            const marker = client.searchForMarker(0, "Eop", true);
            node_assert_1.strict.equal(marker, undefined, "Returned marker should be undefined");
        });
        describe("with remote client", () => {
            const remoteUserLongId = "remoteUser";
            let client2;
            beforeEach(() => {
                client2 = new testClient_js_1.TestClient();
                client2.mergeTree.insertSegments(0, [textSegment_js_1.TextSegment.make("")], client2.mergeTree.localPerspective, client2.mergeTree.collabWindow.mintNextLocalOperationStamp(), undefined);
                client2.startOrUpdateCollaboration(remoteUserLongId);
            });
            it("Should be able to find remotely inserted marker", () => {
                let seq = 0;
                const textMsg = client.makeOpMessage(client.insertTextLocal(0, "abc"), ++seq);
                const markerMsg = client2.makeOpMessage(client2.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                    [mergeTreeNodes_js_1.reservedMarkerIdKey]: "marker",
                    [referencePositions_js_1.reservedTileLabelsKey]: ["Eop"],
                }), ++seq);
                client.applyMsg(textMsg);
                client2.applyMsg(textMsg);
                client.applyMsg(markerMsg);
                client2.applyMsg(markerMsg);
                node_assert_1.strict.equal(client.getLength(), 4, "length not expected - client");
                node_assert_1.strict.equal(client2.getLength(), 4, "length not expected - client 2");
                const marker = client.searchForMarker(0, "Eop", true);
                (0, node_assert_1.strict)(marker, "Returned marker undefined");
                const exp = client.mergeTree.referencePositionToLocalPosition(marker, constants_js_1.UniversalSequenceNumber, client.getClientId());
                node_assert_1.strict.equal(exp, 0, "Marker with label not at expected position");
            });
            it("Should not be able to find remotely removed marker", () => {
                let seq = 0;
                const textMsg = client.makeOpMessage(client.insertTextLocal(0, "abc"), ++seq);
                const mInsertMsg = client.makeOpMessage(client.insertMarkerLocal(0, ops_js_1.ReferenceType.Tile, {
                    [mergeTreeNodes_js_1.reservedMarkerIdKey]: "marker",
                    [referencePositions_js_1.reservedTileLabelsKey]: ["Eop"],
                }), ++seq);
                client.applyMsg(textMsg);
                client2.applyMsg(textMsg);
                client.applyMsg(mInsertMsg);
                client2.applyMsg(mInsertMsg);
                node_assert_1.strict.equal(client.getLength(), 4, "length not expected - client");
                node_assert_1.strict.equal(client2.getLength(), 4, "length not expected - client 2");
                const mRemoveMsg = client2.makeOpMessage(client2.removeRangeLocal(0, 1), ++seq);
                client.applyMsg(mRemoveMsg);
                client2.applyMsg(mRemoveMsg);
                node_assert_1.strict.equal(client.getLength(), 3, "length not expected - client");
                node_assert_1.strict.equal(client2.getLength(), 3, "length not expected - client 2");
                const marker = client.searchForMarker(0, "Eop", true);
                node_assert_1.strict.equal(marker, undefined, "Returned marker should be undefined.");
            });
        });
    });
    describe(".getMarkerById", () => {
        it("removed marker", () => {
            const clients = (0, testClientLogger_js_1.createClientsAtInitialState)({ initialState: "hello world" }, "A", "B");
            const randomMarkerKey = "randomKey1";
            (0, node_assert_1.strict)(!clients.A.getMarkerFromId(randomMarkerKey), "local client before insert");
            const ops = [
                clients.A.makeOpMessage(clients.A.insertMarkerLocal(5, ops_js_1.ReferenceType.Simple, {
                    [mergeTreeNodes_js_1.reservedMarkerIdKey]: randomMarkerKey,
                }), 1),
            ];
            (0, node_assert_1.strict)(clients.A.getMarkerFromId(randomMarkerKey), "local client after insert before ack");
            for (const op of ops.splice(0)) {
                for (const c of clients.all)
                    c.applyMsg(op);
            }
            (0, node_assert_1.strict)(clients.A.getMarkerFromId(randomMarkerKey), "local client after insert after ack");
            (0, node_assert_1.strict)(clients.B.getMarkerFromId(randomMarkerKey), "remote client after insert after ack");
            ops.push(clients.A.makeOpMessage(clients.A.removeRangeLocal(5, 6), 1));
            (0, node_assert_1.strict)(!clients.A.getMarkerFromId(randomMarkerKey), "local client after remove before ack");
            (0, node_assert_1.strict)(clients.B.getMarkerFromId(randomMarkerKey), "remote client after remove before ack");
            for (const op of ops.splice(0)) {
                for (const c of clients.all)
                    c.applyMsg(op);
            }
            (0, node_assert_1.strict)(!clients.A.getMarkerFromId(randomMarkerKey), "local client after remove after ack");
            (0, node_assert_1.strict)(!clients.B.getMarkerFromId(randomMarkerKey), "remote client after remove after ack");
        });
        it("obliterate marker", () => {
            const clients = (0, testClientLogger_js_1.createClientsAtInitialState)({ initialState: "hello world", options: { mergeTreeEnableObliterate: true } }, "A", "B");
            const randomMarkerKey = "randomKey1";
            (0, node_assert_1.strict)(!clients.A.getMarkerFromId(randomMarkerKey), "local client before insert");
            const ops = [
                clients.A.makeOpMessage(clients.A.insertMarkerLocal(5, ops_js_1.ReferenceType.Simple, {
                    [mergeTreeNodes_js_1.reservedMarkerIdKey]: randomMarkerKey,
                }), 1),
            ];
            (0, node_assert_1.strict)(clients.A.getMarkerFromId(randomMarkerKey), "local client after insert before ack");
            for (const op of ops.splice(0)) {
                for (const c of clients.all)
                    c.applyMsg(op);
            }
            (0, node_assert_1.strict)(clients.A.getMarkerFromId(randomMarkerKey), "local client after insert after ack");
            (0, node_assert_1.strict)(clients.B.getMarkerFromId(randomMarkerKey), "remote client after insert after ack");
            ops.push(clients.A.makeOpMessage(clients.A.obliterateRangeLocal(5, 6), 1));
            (0, node_assert_1.strict)(!clients.A.getMarkerFromId(randomMarkerKey), "local client after obliterate before ack");
            (0, node_assert_1.strict)(clients.B.getMarkerFromId(randomMarkerKey), "remote client after obliterate before ack");
            for (const op of ops.splice(0)) {
                for (const c of clients.all)
                    c.applyMsg(op);
            }
            (0, node_assert_1.strict)(!clients.A.getMarkerFromId(randomMarkerKey), "local client after obliterate after ack");
            (0, node_assert_1.strict)(!clients.B.getMarkerFromId(randomMarkerKey), "remote client after obliterate after ack");
        });
    });
});
//# sourceMappingURL=client.searchForMarker.spec.js.map