"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const node_assert_1 = require("node:assert");
const constants_js_1 = require("../constants.js");
const opstampUtils = __importStar(require("../stamps.js"));
function lessThan(a, b) {
    const result = opstampUtils.lessThan(a, b);
    // Validate that this gives a consistent result with some other ways to compute the same thing
    const fromComparison = opstampUtils.compare(a, b) === -1;
    const fromGte = !opstampUtils.gte(a, b);
    node_assert_1.strict.strictEqual(result, fromComparison);
    node_assert_1.strict.strictEqual(result, fromGte);
    return result;
}
function greaterThan(a, b) {
    const result = opstampUtils.greaterThan(a, b);
    // Validate that this gives a consistent result with some other ways to compute the same thing
    const fromComparison = opstampUtils.compare(a, b) === 1;
    const fromLte = !opstampUtils.lte(a, b);
    node_assert_1.strict.strictEqual(result, fromComparison);
    node_assert_1.strict.strictEqual(result, fromLte);
    return result;
}
/**
 * Validate that a list of operation stamps is in strictly increasing order in several different ways using the comparison
 * operation stamp utility methods.
 */
function expectStrictlyIncreasing(list) {
    for (let i = 0; i < list.length - 1; i++) {
        node_assert_1.strict.ok(lessThan(list[i], list[i + 1]), `List not strictly increasing by lessThan:  ${JSON.stringify(list[i])} >= ${JSON.stringify(list[i + 1])}`);
        node_assert_1.strict.ok(greaterThan(list[i + 1], list[i]), `List not strictly increasing by greaterThan:  ${JSON.stringify(list[i + 1])} <= ${JSON.stringify(list[i])}`);
    }
}
describe("opstampUtils", () => {
    const acked1 = { clientId: 1, seq: 1 };
    const acked2 = { clientId: 2, seq: 2 };
    const acked3 = { clientId: 1, seq: 3 };
    const local1 = { clientId: 1, seq: constants_js_1.UnassignedSequenceNumber, localSeq: 1 };
    const local2 = { clientId: 1, seq: constants_js_1.UnassignedSequenceNumber, localSeq: 2 };
    describe("equality", () => {
        it("returns true for reference equal stamps", () => {
            for (const stamp of [acked1, acked2, acked3, local1, local2]) {
                node_assert_1.strict.ok(opstampUtils.equal(stamp, stamp));
            }
        });
        it("returns true for equal stamps", () => {
            for (const stamp of [acked1, acked2, acked3, local1, local2]) {
                node_assert_1.strict.ok(opstampUtils.equal(stamp, { ...stamp }));
            }
        });
        it("returns false for different stamps", () => {
            node_assert_1.strict.ok(!opstampUtils.equal(acked1, acked2));
            node_assert_1.strict.ok(!opstampUtils.equal(acked1, acked3));
            node_assert_1.strict.ok(!opstampUtils.equal(acked1, local1));
            node_assert_1.strict.ok(!opstampUtils.equal(acked1, local2));
            node_assert_1.strict.ok(!opstampUtils.equal(local1, local2));
        });
    });
    describe("comparison", () => {
        it("orders stamps correctly", () => {
            expectStrictlyIncreasing([acked1, acked2, acked3, local1, local2]);
        });
        it("compare can sort lists", () => {
            const list = [acked3, local1, acked1, local2, acked2];
            list.sort(opstampUtils.compare);
            node_assert_1.strict.deepEqual(list, [acked1, acked2, acked3, local1, local2]);
        });
    });
    describe("spliceIntoList", () => {
        it("inserts unacked into empty list", () => {
            const list = [];
            opstampUtils.spliceIntoList(list, local1);
            node_assert_1.strict.deepStrictEqual(list, [local1]);
        });
        it("inserts acked into empty list", () => {
            const list = [];
            opstampUtils.spliceIntoList(list, acked1);
            node_assert_1.strict.deepStrictEqual(list, [acked1]);
        });
        it("inserts unacked after acked", () => {
            const list = [acked1];
            opstampUtils.spliceIntoList(list, local1);
            node_assert_1.strict.deepStrictEqual(list, [acked1, local1]);
        });
        it("inserts acked before unacked", () => {
            const list = [acked1, acked2, local1];
            opstampUtils.spliceIntoList(list, acked3);
            node_assert_1.strict.deepStrictEqual(list, [acked1, acked2, acked3, local1]);
        });
        it("inserts acked before single unacked", () => {
            const list = [local1];
            opstampUtils.spliceIntoList(list, acked2);
            node_assert_1.strict.deepStrictEqual(list, [acked2, local1]);
        });
        it("inserts local seqs at end", () => {
            const list = [acked1, acked2];
            opstampUtils.spliceIntoList(list, local1);
            opstampUtils.spliceIntoList(list, local2);
            node_assert_1.strict.deepStrictEqual(list, [acked1, acked2, local1, local2]);
        });
    });
});
//# sourceMappingURL=stamps.spec.js.map