ポップオーバーの既定の印を「既定」の札にする。バッジには名前を書かず、 表示中のバリアント名はツールチップで示す(はみ出しをなくす。T-30の着手前の決定を反映)。 バリアントグループは選択の入れ物(クラスター・バリアント)の中に作る。 そのため domain に createVariantGroupInParent を足し、variant のIDを渡すと 例外になっていた parentNodes を直した。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NznQtmVPoQAnietqwr1auL
125 lines
4.4 KiB
TypeScript
125 lines
4.4 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import type { PhyFile } from "../src/domain/phy";
|
|
import {
|
|
addComponentToParent,
|
|
addKeyToParent,
|
|
cloneNodesWithNewIds,
|
|
createVariantGroupInParent,
|
|
duplicateNode,
|
|
insertNodes,
|
|
} from "../src/domain/phyCommands";
|
|
const ids = (() => {
|
|
let n = 0;
|
|
return () => `0000000${++n}-0000-4000-8000-000000000000`;
|
|
})();
|
|
const file: PhyFile = {
|
|
version: "0.1.0",
|
|
metadata: {},
|
|
profiles: [{ id: "p", name: "P", unitSize: { x: 1, y: 1 } }],
|
|
root: [
|
|
{ type: "cluster", id: "cl-parent", name: "P", transform: { x: 0, y: 0, rotation: 0 }, children: [] },
|
|
],
|
|
};
|
|
describe("PHY parent insertion and duplication", () => {
|
|
it("adds keys and components to root, clusters, or variants", () => {
|
|
let p = addKeyToParent(file, "cl-parent", { x: 2, y: 3, rotation: 0 }, { w: 1, h: 1 }, "p", ids);
|
|
expect(
|
|
p.root[0]!.type === "cluster" &&
|
|
(p.root[0]! as import("../src/domain/phy").ClusterNode).children[0]?.type,
|
|
).toBe("key");
|
|
p = addComponentToParent(p, "cl-parent", { x: 0, y: 0, rotation: 0 }, "@led", ids);
|
|
expect(
|
|
p.root[0]!.type === "cluster" &&
|
|
(p.root[0]! as import("../src/domain/phy").ClusterNode).children[1]?.type,
|
|
).toBe("component");
|
|
});
|
|
it("inserts a copied node batch into a selected container", () => {
|
|
const node = {
|
|
type: "key" as const,
|
|
id: "key-source",
|
|
profile: "p",
|
|
transform: { x: 1, y: 1, rotation: 0 },
|
|
size: { w: 1, h: 1 },
|
|
};
|
|
const p = insertNodes(file, "cl-parent", [node]);
|
|
expect(
|
|
p.root[0]!.type === "cluster" && (p.root[0]! as import("../src/domain/phy").ClusterNode).children,
|
|
).toHaveLength(1);
|
|
});
|
|
it("renews IDs and remaps a duplicated group's internal default", () => {
|
|
const base: PhyFile = {
|
|
...file,
|
|
root: [
|
|
{
|
|
type: "variantGroup",
|
|
id: "vg-source",
|
|
name: "VG",
|
|
transform: { x: 0, y: 0, rotation: 0 },
|
|
default: "v-one",
|
|
children: [
|
|
{ type: "variant", id: "v-one", name: "One", children: [] },
|
|
{ type: "variant", id: "v-two", name: "Two", children: [] },
|
|
],
|
|
},
|
|
],
|
|
};
|
|
const q = duplicateNode(base, "vg-source", ids);
|
|
const copy = q.root[1];
|
|
expect(copy?.type).toBe("variantGroup");
|
|
if (copy?.type === "variantGroup") {
|
|
expect(copy.id).not.toBe("vg-source");
|
|
expect(copy.default).not.toBe("v-one");
|
|
expect(copy.children.map((v) => v.id)).not.toContain("v-one");
|
|
expect(copy.default).toBe(copy.children[0]!.id);
|
|
}
|
|
});
|
|
it("remaps defaults for variant groups nested inside a copied cluster", () => {
|
|
const nested: PhyFile["root"][number] = {
|
|
type: "cluster",
|
|
id: "outer",
|
|
transform: { x: 0, y: 0, rotation: 0 },
|
|
children: [
|
|
{
|
|
type: "variantGroup",
|
|
id: "vg-inner",
|
|
name: "Inner",
|
|
transform: { x: 1, y: 2, rotation: 0 },
|
|
default: "v-inner-a",
|
|
children: [
|
|
{ type: "variant", id: "v-inner-a", name: "A", children: [] },
|
|
{ type: "variant", id: "v-inner-b", name: "B", children: [] },
|
|
],
|
|
},
|
|
],
|
|
};
|
|
const copy = cloneNodesWithNewIds([nested], ids)[0];
|
|
expect(copy?.type).toBe("cluster");
|
|
if (copy?.type === "cluster") {
|
|
const group = copy.children[0];
|
|
expect(group?.type).toBe("variantGroup");
|
|
if (group?.type === "variantGroup") {
|
|
expect(group.default).toBe(group.children[0]!.id);
|
|
expect(group.default).not.toBe("v-inner-a");
|
|
}
|
|
}
|
|
});
|
|
it("creates a variant group inside a cluster or a variant", () => {
|
|
const variants: Parameters<typeof createVariantGroupInParent>[4] = [{ name: "A" }, { name: "B" }];
|
|
let p = createVariantGroupInParent(file, "cl-parent", "G", { x: 0, y: 0, rotation: 0 }, variants, ids);
|
|
const parent = p.root[0] as import("../src/domain/phy").ClusterNode;
|
|
expect(p.root).toHaveLength(1);
|
|
expect(parent.children.map((n) => n.type)).toEqual(["variantGroup"]);
|
|
const group = parent.children[0] as import("../src/domain/phy").VariantGroupNode;
|
|
p = createVariantGroupInParent(
|
|
p,
|
|
group.children[1]!.id,
|
|
"Inner",
|
|
{ x: 0, y: 0, rotation: 0 },
|
|
variants,
|
|
ids,
|
|
);
|
|
const updated = (p.root[0] as import("../src/domain/phy").ClusterNode).children[0] as typeof group;
|
|
expect(updated.children[1]!.children.map((n) => n.type)).toEqual(["variantGroup"]);
|
|
});
|
|
});
|