"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 mergeTreeTracking_js_1 = require("../mergeTreeTracking.js");
const ops_js_1 = require("../ops.js");
const testClient_js_1 = require("./testClient.js");
describe("MergeTree.tracking", () => {
    let testClient;
    beforeEach(() => {
        testClient = new testClient_js_1.TestClient();
        testClient.startOrUpdateCollaboration("me");
    });
    it("Inserted segment should have empty tracking groups", () => {
        testClient.insertTextLocal(0, "abc");
        node_assert_1.strict.equal(testClient.getLength(), 3);
        const segmentInfo = testClient.getContainingSegment(0);
        (0, node_assert_1.strict)(segmentInfo?.segment?.trackingCollection.empty);
    });
    it("Insert single segment with single tracking group", () => {
        const trackingGroup = new mergeTreeTracking_js_1.TrackingGroup();
        testClient.on("delta", (opArgs, deltaArgs) => {
            for (const sg of deltaArgs.deltaSegments)
                sg.segment.trackingCollection.link(trackingGroup);
        });
        testClient.insertTextLocal(0, "abc");
        node_assert_1.strict.equal(trackingGroup.size, 1);
        const segmentInfo = testClient.getContainingSegment(0);
        node_assert_1.strict.equal(segmentInfo?.segment?.trackingCollection.trackingGroups.size, 1);
        (0, node_assert_1.strict)(trackingGroup.unlink(segmentInfo?.segment), "unlink segment should be true");
        node_assert_1.strict.equal(segmentInfo?.segment?.trackingCollection.trackingGroups.size, 0);
    });
    it("Splitting segment should split tracking group", () => {
        const trackingGroup = new mergeTreeTracking_js_1.TrackingGroup();
        testClient.on("delta", (opArgs, deltaArgs) => {
            for (const sg of deltaArgs.deltaSegments)
                sg.segment.trackingCollection.link(trackingGroup);
        });
        const ops = [testClient.insertTextLocal(0, "abc")];
        testClient.removeAllListeners("delta");
        node_assert_1.strict.equal(trackingGroup.size, 1);
        ops.push(testClient.insertTextLocal(1, "z"));
        node_assert_1.strict.equal(testClient.getLength(), 4);
        node_assert_1.strict.equal(trackingGroup.size, 2);
        const segmentInfo = testClient.getContainingSegment(0);
        node_assert_1.strict.equal(segmentInfo?.segment?.trackingCollection.trackingGroups.size, 1);
    });
    it("Zamboni should merge matching tracking groups", () => {
        const trackingGroup = new mergeTreeTracking_js_1.TrackingGroup();
        testClient.on("delta", (opArgs, deltaArgs) => {
            for (const sg of deltaArgs.deltaSegments)
                sg.segment.trackingCollection.link(trackingGroup);
        });
        const ops = [testClient.insertTextLocal(0, "abc")];
        node_assert_1.strict.equal(trackingGroup.size, 1);
        ops.push(testClient.insertTextLocal(1, "z"));
        node_assert_1.strict.equal(testClient.getLength(), 4);
        node_assert_1.strict.equal(trackingGroup.size, 3);
        let segmentInfo = testClient.getContainingSegment(0);
        node_assert_1.strict.equal(segmentInfo?.segment?.trackingCollection.trackingGroups.size, 1);
        let seq = 1;
        for (const op of ops)
            testClient.applyMsg(testClient.makeOpMessage(op, ++seq));
        node_assert_1.strict.equal(trackingGroup.size, 3);
        segmentInfo = testClient.getContainingSegment(0);
        node_assert_1.strict.equal(segmentInfo?.segment?.trackingCollection.trackingGroups.size, 1);
        testClient.updateMinSeq(seq);
        node_assert_1.strict.equal(trackingGroup.size, 1);
        segmentInfo = testClient.getContainingSegment(0);
        node_assert_1.strict.equal(segmentInfo?.segment?.trackingCollection.trackingGroups.size, 1);
    });
    it("Newly created local reference should have empty tracking group", () => {
        testClient.insertTextLocal(0, "abc");
        node_assert_1.strict.equal(testClient.getLength(), 3);
        const segmentInfo = testClient.getContainingSegment(0);
        (0, node_assert_1.strict)(segmentInfo?.segment);
        const ref = testClient.createLocalReferencePosition(segmentInfo?.segment, 0, ops_js_1.ReferenceType.SlideOnRemove, undefined);
        (0, node_assert_1.strict)(ref.trackingCollection.empty);
    });
    it("Local reference can be added an removed from tracking group", () => {
        testClient.insertTextLocal(0, "abc");
        node_assert_1.strict.equal(testClient.getLength(), 3);
        const segmentInfo = testClient.getContainingSegment(0);
        (0, node_assert_1.strict)(segmentInfo?.segment);
        const ref = testClient.createLocalReferencePosition(segmentInfo?.segment, 0, ops_js_1.ReferenceType.SlideOnRemove, undefined);
        const trackingGroup = new mergeTreeTracking_js_1.TrackingGroup();
        ref.trackingCollection.link(trackingGroup);
        node_assert_1.strict.equal(trackingGroup.size, 1);
        node_assert_1.strict.equal(trackingGroup.has(ref), true);
        node_assert_1.strict.equal(trackingGroup.tracked.includes(ref), true);
        node_assert_1.strict.equal(ref.trackingCollection.trackingGroups.size, 1);
        ref.trackingCollection.unlink(trackingGroup);
        node_assert_1.strict.equal(trackingGroup.size, 0);
        node_assert_1.strict.equal(trackingGroup.has(ref), false);
        node_assert_1.strict.equal(trackingGroup.tracked.includes(ref), false);
        node_assert_1.strict.equal(ref.trackingCollection.trackingGroups.size, 0);
    });
    it("unlink segment from tracking group", () => {
        const trackingGroup = new mergeTreeTracking_js_1.TrackingGroup();
        testClient.insertTextLocal(0, "abc");
        const { segment } = testClient.getContainingSegment(0) ?? {};
        segment?.trackingCollection.link(trackingGroup);
        node_assert_1.strict.equal(segment?.trackingCollection.trackingGroups.size, 1);
        (0, node_assert_1.strict)(trackingGroup.unlink(segment), "unlink segment should be true");
        node_assert_1.strict.equal(segment?.trackingCollection.trackingGroups.size, 0);
        node_assert_1.strict.equal(trackingGroup.unlink(segment), false, "repeat unlink segment should be false");
        node_assert_1.strict.equal(segment.trackingCollection.unlink(trackingGroup), false, "repeat unlink trackingGroup should be false");
    });
    it("unlink tracking group from collection", () => {
        const trackingGroup = new mergeTreeTracking_js_1.TrackingGroup();
        testClient.insertTextLocal(0, "abc");
        const { segment } = testClient.getContainingSegment(0) ?? {};
        segment?.trackingCollection.link(trackingGroup);
        node_assert_1.strict.equal(segment?.trackingCollection.trackingGroups.size, 1);
        (0, node_assert_1.strict)(segment.trackingCollection.unlink(trackingGroup), "unlink trackingGroup should be true");
        node_assert_1.strict.equal(segment?.trackingCollection.trackingGroups.size, 0);
        node_assert_1.strict.equal(trackingGroup.unlink(segment), false, "repeat unlink segment should be false");
        node_assert_1.strict.equal(segment.trackingCollection.unlink(trackingGroup), false, "repeat unlink trackingGroup should be false");
    });
});
//# sourceMappingURL=tracking.spec.js.map