WIP: Feature Rewrite #87
2 changed files with 109 additions and 0 deletions
|
@ -418,6 +418,7 @@ export function placeInAvailableSpace<T extends NodePosition>(
|
||||||
: Math.abs(nodeToPlace.y - nodeToCheck.y);
|
: Math.abs(nodeToPlace.y - nodeToCheck.y);
|
||||||
|
|
||||||
// If we're too close to this node, move further
|
// If we're too close to this node, move further
|
||||||
|
// Keep in mind positions start at top right, so "down" means increasing Y
|
||||||
if (distance < radius) {
|
if (distance < radius) {
|
||||||
if (direction === Direction.Right) {
|
if (direction === Direction.Right) {
|
||||||
nodeToPlace.x = nodeToCheck.x + radius;
|
nodeToPlace.x = nodeToCheck.x + radius;
|
||||||
|
|
108
tests/features/board.test.ts
Normal file
108
tests/features/board.test.ts
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
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<number>;
|
||||||
|
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<NodePosition[]>, 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 });
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue