/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { strict as assert } from "assert";
import { mintRevisionTag } from "../../utils.js";
import { makeAnonChange, tagChange, } from "../../../core/index.js";
import { SequenceField as SF } from "../../../feature-libraries/index.js";
import { brand } from "../../../util/index.js";
import { TestChange } from "../../testChange.js";
import { MarkMaker as Mark } from "./testEdits.js";
const tag = mintRevisionTag();
const atomId = { localId: brand(0) };
const deltaId = { minor: atomId.localId };
const childChange = TestChange.mint([0], 1);
const relevantNestedTree = { minor: 4242 };
const oneTreeDelegate = (child) => {
    assert.deepEqual(child, childChange);
    return [relevantNestedTree];
};
const noTreeDelegate = (child) => {
    assert.deepEqual(child, childChange);
    return [];
};
export function testRelevantRemovedRoots() {
    describe("relevantRemovedRoots", () => {
        describe("does not include", () => {
            it("a tree that remains in-doc", () => {
                const input = [{ count: 1 }];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), noTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, []);
            });
            it("a tree with child changes that remains in-doc", () => {
                const input = [Mark.modify(childChange)];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), noTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, []);
            });
            it("a tree that remains removed", () => {
                const input = [{ count: 1, cellId: atomId }];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), noTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, []);
            });
            it("a tree being removed", () => {
                const input = [Mark.remove(1, atomId)];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), noTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, []);
            });
            it("a tree with child changes being removed", () => {
                const input = [Mark.remove(1, atomId, { changes: childChange })];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), noTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, []);
            });
            it("a tree being moved", () => {
                const input = [Mark.moveOut(1, atomId), Mark.moveIn(1, atomId)];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), noTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, []);
            });
            it("a tree with child changes being moved", () => {
                const input = [
                    Mark.moveOut(1, atomId, { changes: childChange }),
                    Mark.moveIn(1, atomId),
                ];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), noTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, []);
            });
            it("a live tree being pinned", () => {
                const input = [Mark.pin(1, brand(0))];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), noTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, []);
            });
        });
        describe("does include", () => {
            it("a tree being inserted", () => {
                const input = [Mark.insert(1, atomId)];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), noTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, [deltaId]);
            });
            it("a tree being transiently inserted", () => {
                const input = [
                    Mark.attachAndDetach(Mark.insert(1, atomId), Mark.remove(1, atomId)),
                ];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), noTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, [deltaId]);
            });
            it("a tree being transiently inserted and moved out", () => {
                const input = [
                    Mark.attachAndDetach(Mark.insert(1, atomId), Mark.moveOut(1, atomId)),
                ];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), noTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, [deltaId]);
            });
            it("relevant roots from nested changes under a tree that remains in-doc", () => {
                const input = [Mark.modify(childChange)];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), oneTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, [relevantNestedTree]);
            });
            it("relevant roots from nested changes under a tree that remains removed", () => {
                const input = [Mark.modify(childChange, atomId)];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), oneTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, [deltaId, relevantNestedTree]);
            });
            it("a removed tree with nested changes", () => {
                const input = [Mark.modify(childChange, atomId)];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), noTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, [deltaId]);
            });
            it("a tree being restored by revive", () => {
                const input = [Mark.revive(1, atomId)];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), noTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, [deltaId]);
            });
            it("a tree being restored by pin", () => {
                const input = [Mark.pin(1, brand(0), { cellId: atomId })];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), noTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, [deltaId]);
            });
            it("a tree being transiently restored", () => {
                const input = [Mark.remove(1, brand(0), { cellId: atomId })];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), noTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, [deltaId]);
            });
            it("relevant roots from nested changes under a tree being restored by revive", () => {
                const input = [Mark.revive(1, atomId, { changes: childChange })];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), oneTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, [deltaId, relevantNestedTree]);
            });
            it("relevant roots from nested changes under a tree being restored by pin", () => {
                const input = [
                    Mark.pin(1, brand(0), { cellId: atomId, changes: childChange }),
                ];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), oneTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, [deltaId, relevantNestedTree]);
            });
            it("relevant roots from nested changes under a tree being removed", () => {
                const input = [Mark.remove(1, atomId, { changes: childChange })];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), oneTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, [relevantNestedTree]);
            });
            it("relevant roots from nested changes under a tree being inserted", () => {
                const input = [Mark.insert(1, atomId, { changes: childChange })];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), oneTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, [deltaId, relevantNestedTree]);
            });
            it("relevant roots from nested changes under a tree being moved", () => {
                const input = [
                    Mark.moveOut(1, atomId, { changes: childChange }),
                    Mark.moveIn(1, atomId),
                ];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), oneTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, [relevantNestedTree]);
            });
            it("relevant roots from nested changes under a tree being transiently inserted", () => {
                const input = [
                    Mark.attachAndDetach(Mark.insert(1, atomId), Mark.remove(1, atomId), {
                        changes: childChange,
                    }),
                ];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), oneTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, [deltaId, relevantNestedTree]);
            });
            it("relevant roots from nested changes under a tree being transiently restored", () => {
                const input = [
                    Mark.remove(1, brand(0), { cellId: atomId, changes: childChange }),
                ];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), oneTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, [deltaId, relevantNestedTree]);
            });
            it("relevant roots from nested changes under a tree being transiently inserted and moved out", () => {
                const input = [
                    Mark.attachAndDetach(Mark.insert(1, atomId), Mark.moveOut(1, atomId), {
                        changes: childChange,
                    }),
                ];
                const actual = SF.relevantRemovedRoots(makeAnonChange(input), oneTreeDelegate);
                const array = Array.from(actual);
                assert.deepEqual(array, [deltaId, relevantNestedTree]);
            });
        });
        it("uses passed down revision", () => {
            const input = [Mark.modify(childChange, { localId: brand(42) })];
            const actual = SF.relevantRemovedRoots(tagChange(input, tag), noTreeDelegate);
            const array = Array.from(actual);
            assert.deepEqual(array, [{ major: tag, minor: 42 }]);
        });
    });
}
//# sourceMappingURL=relevantRemovedRoots.test.js.map