import { NodePosition, placeInAvailableSpace, setupUniqueIds, unwrapNodeRef } from "features/boards/board"; import { beforeEach, describe, expect, test } from "vitest"; import { Ref, ref } from "vue"; import "../utils"; import { Direction } from "util/common"; describe("Unwraps node refs", () => { test("Static value", () => expect(unwrapNodeRef(100, {})).toBe(100)); test("Ref value", () => expect(unwrapNodeRef(ref(100), {})).toBe(100)); test("0 param function value", () => expect(unwrapNodeRef(() => 100, {})).toBe(100)); test("1 param function value", () => { const actualNode = { foo: "bar" }; expect( unwrapNodeRef(function (node) { if (node === actualNode) { return true; } return false; }, actualNode) ).toBe(true); }); }); describe("Set up unique IDs", () => { let nodes: Ref<{ id: number }[]>, nextId: Ref; beforeEach(() => { nodes = ref([]); nextId = setupUniqueIds(nodes); }); test("Starts at 0", () => expect(nextId?.value).toBe(0)); test("Calculates initial value properly", () => { nodes.value = [{ id: 0 }, { id: 1 }, { id: 2 }]; expect(nextId.value).toBe(3); }); test("Non consecutive IDs", () => { nodes.value = [{ id: -5 }, { id: 0 }, { id: 200 }]; expect(nextId.value).toBe(201); }); test("After modification", () => { nodes.value = [{ id: 0 }, { id: 1 }, { id: 2 }]; nodes.value.push({ id: nextId.value }); expect(nextId.value).toBe(4); }); }); describe("Place in available space", () => { let nodes: Ref, node: NodePosition; beforeEach(() => { nodes = ref([]); node = { x: 10, y: 20 }; }); test("No nodes", () => { placeInAvailableSpace(node, nodes.value); expect(node).toMatchObject({ x: 10, y: 20 }); }); test("Moves node", () => { nodes.value = [{ x: 10, y: 20 }]; placeInAvailableSpace(node, nodes.value); expect(node).not.toMatchObject({ x: 10, y: 20 }); }); describe("Respects radius", () => { test("Positions radius away", () => { nodes.value = [{ x: 10, y: 20 }]; placeInAvailableSpace(node, nodes.value, 32); expect(node).toMatchObject({ x: 42, y: 20 }); }); test("Ignores node already radius away", () => { nodes.value = [{ x: 42, y: 20 }]; placeInAvailableSpace(node, nodes.value, 32); expect(node).toMatchObject({ x: 10, y: 20 }); }); test("Doesn't ignore node just under radius away", () => { nodes.value = [{ x: 41, y: 20 }]; placeInAvailableSpace(node, nodes.value, 32); expect(node).not.toMatchObject({ x: 10, y: 20 }); }); }); describe("Respects direction", () => { test("Goes left", () => { nodes.value = [{ x: 10, y: 20 }]; placeInAvailableSpace(node, nodes.value, 10, Direction.Left); expect(node).toMatchObject({ x: 0, y: 20 }); }); test("Goes up", () => { nodes.value = [{ x: 10, y: 20 }]; placeInAvailableSpace(node, nodes.value, 10, Direction.Up); expect(node).toMatchObject({ x: 10, y: 10 }); }); test("Goes down", () => { nodes.value = [{ x: 10, y: 20 }]; placeInAvailableSpace(node, nodes.value, 10, Direction.Down); expect(node).toMatchObject({ x: 10, y: 30 }); }); }); test("Finds hole", () => { nodes.value = [ { x: 10, y: 20 }, { x: 30, y: 20 } ]; placeInAvailableSpace(node, nodes.value, 10); expect(node).toMatchObject({ x: 20, y: 20 }); }); });