// Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 import { assert, test } from "vitest"; import { newLayoutNode } from "../lib/layoutNode"; import { computeMoveNode, moveNode } from "../lib/layoutTree"; import { DropDirection, LayoutTreeActionType, LayoutTreeComputeMoveNodeAction, LayoutTreeMoveNodeAction, } from "../lib/types"; import { newLayoutTreeState } from "./model"; test("layoutTreeStateReducer - compute move", () => { let treeState = newLayoutTreeState(newLayoutNode(undefined, undefined, undefined, { blockId: "root" })); assert(treeState.rootNode.data!.blockId === "root", "root should have no children and should have data"); let node1 = newLayoutNode(undefined, undefined, undefined, { blockId: "node1" }); let pendingAction = computeMoveNode(treeState, { type: LayoutTreeActionType.ComputeMove, nodeId: treeState.rootNode.id, nodeToMoveId: node1.id, direction: DropDirection.Bottom, }); const insertOperation = pendingAction as LayoutTreeMoveNodeAction; assert(insertOperation.node === node1, "insert operation node should equal node1"); assert(!insertOperation.parentId, "insert operation parent should not be defined"); assert(insertOperation.index === 1, "insert operation index should equal 1"); assert(insertOperation.insertAtRoot, "insert operation insertAtRoot should be true"); moveNode(treeState, insertOperation); assert( treeState.rootNode.data === undefined && treeState.rootNode.children!.length === 2, "root node should now have no data and should have two children" ); assert(treeState.rootNode.children![1].data!.blockId === "node1", "root's second child should be node1"); let node2 = newLayoutNode(undefined, undefined, undefined, { blockId: "node2" }); pendingAction = computeMoveNode(treeState, { type: LayoutTreeActionType.ComputeMove, nodeId: node1.id, nodeToMoveId: node2.id, direction: DropDirection.Bottom, }); const insertOperation2 = pendingAction as LayoutTreeMoveNodeAction; assert(insertOperation2.node === node2, "insert operation node should equal node2"); assert(insertOperation2.parentId === node1.id, "insert operation parent id should be node1 id"); assert(insertOperation2.index === 1, "insert operation index should equal 1"); assert(!insertOperation2.insertAtRoot, "insert operation insertAtRoot should be false"); moveNode(treeState, insertOperation2); assert( treeState.rootNode.data === undefined && treeState.rootNode.children!.length === 2, "root node should still have three children" ); assert(treeState.rootNode.children![1].children!.length === 2, "root's second child should now have two children"); }); test("computeMove - noop action", () => { let nodeToMove = newLayoutNode(undefined, undefined, undefined, { blockId: "nodeToMove" }); let treeState = newLayoutTreeState( newLayoutNode(undefined, undefined, [ nodeToMove, newLayoutNode(undefined, undefined, undefined, { blockId: "otherNode" }), ]) ); let moveAction: LayoutTreeComputeMoveNodeAction = { type: LayoutTreeActionType.ComputeMove, nodeId: treeState.rootNode.id, nodeToMoveId: nodeToMove.id, direction: DropDirection.Left, }; let pendingAction = computeMoveNode(treeState, moveAction); assert(pendingAction === undefined, "inserting a node to the left of itself should not produce a pendingAction"); moveAction = { type: LayoutTreeActionType.ComputeMove, nodeId: treeState.rootNode.id, nodeToMoveId: nodeToMove.id, direction: DropDirection.Right, }; pendingAction = computeMoveNode(treeState, moveAction); assert(pendingAction === undefined, "inserting a node to the right of itself should not produce a pendingAction"); });