WIP test(tree-view): more unit tests

This commit is contained in:
Eric Liu 2025-04-12 15:26:55 -07:00
commit 42eb0d2315
2 changed files with 107 additions and 5 deletions

View file

@ -5,9 +5,10 @@
import Analytics from "carbon-icons-svelte/lib/Analytics.svelte"; import Analytics from "carbon-icons-svelte/lib/Analytics.svelte";
let treeview: TreeView; let treeview: TreeView;
let activeId: TreeNodeId = ""; export let activeId: TreeNodeId = "";
let selectedIds: TreeNodeId[] = []; export let selectedIds: TreeNodeId[] = [];
let expandedIds: TreeNodeId[] = []; export let expandedIds: TreeNodeId[] = [];
export let size: "default" | "compact" = "compact";
let nodes: ComponentProps<TreeView>["nodes"] = [ let nodes: ComponentProps<TreeView>["nodes"] = [
{ id: 0, text: "AI / Machine learning", icon: Analytics }, { id: 0, text: "AI / Machine learning", icon: Analytics },
{ {
@ -47,6 +48,7 @@
disabled: true, disabled: true,
nodes: [{ id: 15, text: "IBM API Connect", disabled: true }], nodes: [{ id: 15, text: "IBM API Connect", disabled: true }],
}, },
{ id: 16, text: "Disabled Node", disabled: true },
]; ];
$: console.log("selectedIds", selectedIds); $: console.log("selectedIds", selectedIds);
@ -54,7 +56,7 @@
<TreeView <TreeView
bind:this={treeview} bind:this={treeview}
size="compact" {size}
labelText="Cloud Products" labelText="Cloud Products"
{nodes} {nodes}
bind:activeId bind:activeId

View file

@ -1,4 +1,5 @@
import { render, screen } from "@testing-library/svelte"; import { render, screen } from "@testing-library/svelte";
import type { TreeNode } from "carbon-components-svelte/TreeView/TreeView.svelte";
import { user } from "../setup-tests"; import { user } from "../setup-tests";
import TreeViewHierarchy from "./TreeView.hierarchy.test.svelte"; import TreeViewHierarchy from "./TreeView.hierarchy.test.svelte";
import TreeView from "./TreeView.test.svelte"; import TreeView from "./TreeView.test.svelte";
@ -6,7 +7,7 @@ import TreeView from "./TreeView.test.svelte";
const testCases = [ const testCases = [
{ name: "TreeView", component: TreeView }, { name: "TreeView", component: TreeView },
{ name: "TreeView hierarchy", component: TreeViewHierarchy }, { name: "TreeView hierarchy", component: TreeViewHierarchy },
]; ] as const;
describe.each(testCases)("$name", ({ component }) => { describe.each(testCases)("$name", ({ component }) => {
const getItemByName = (name: RegExp) => { const getItemByName = (name: RegExp) => {
@ -79,4 +80,103 @@ describe.each(testCases)("$name", ({ component }) => {
screen.getByText("IBM Analytics Engine").parentNode?.parentNode, screen.getByText("IBM Analytics Engine").parentNode?.parentNode,
).toHaveAttribute("aria-expanded", "true"); ).toHaveAttribute("aria-expanded", "true");
}); });
it("can set initial active node", () => {
render(component, { activeId: "0" });
const activeItem = screen.getByRole("treeitem", {
name: /AI \/ Machine learning/,
});
expect(activeItem).toHaveAttribute("tabindex", "0");
});
it("can use compact size variant", () => {
render(component, { size: "compact" });
const tree = screen.getByRole("tree");
expect(tree).toHaveClass("bx--tree--compact");
});
it("can render nodes with icons", () => {
render(component);
const iconItem = screen.getByRole("treeitem", {
name: /IBM Analytics Engine/,
});
expect(iconItem.querySelector("svg")).toBeInTheDocument();
});
it("can set initial expanded nodes", () => {
render(component, { expandedIds: ["0", "1"] });
const expandedItems = screen.getAllByRole("treeitem", { expanded: true });
expect(expandedItems).toHaveLength(2);
});
it("can set initial multiple selected nodes", () => {
render(component, { selectedIds: ["0", "1"] });
const selectedItems = screen.getAllByRole("treeitem", { selected: true });
expect(selectedItems).toHaveLength(2);
});
it("can programmatically expand all nodes", () => {
const { component: treeView } = render(component);
treeView.expandAll();
const expandedItems = screen.getAllByRole("treeitem", { expanded: true });
expect(expandedItems).toHaveLength(5);
});
it("can programmatically collapse all nodes", () => {
const { component: treeView } = render(component, {
expandedIds: ["0", "1", "2", "3", "4"],
});
treeView.collapseAll();
noExpandedItems();
});
it("can programmatically expand a subset of nodes", () => {
const { component: treeView } = render(component);
treeView.expandNodes((node: TreeNode) => node.text.includes("Analytics"));
const expandedItems = screen.getAllByRole("treeitem", { expanded: true });
expect(expandedItems).toHaveLength(2);
});
it("can programmatically collapse a subset of nodes", () => {
const { component: treeView } = render(component, {
expandedIds: ["0", "1", "2", "3", "4"],
});
treeView.collapseNodes((node: TreeNode) => node.text.includes("Analytics"));
const expandedItems = screen.getAllByRole("treeitem", { expanded: true });
expect(expandedItems).toHaveLength(3);
});
it("can show a specific node", () => {
const { component: treeView } = render(component);
treeView.showNode("4");
const activeItem = screen.getByRole("treeitem", {
name: /IBM Cloud Pak for Data/,
});
expect(activeItem).toHaveAttribute("tabindex", "0");
expect(activeItem).toHaveAttribute("aria-selected", "true");
});
it("can handle keyboard navigation", async () => {
render(component);
const firstItem = getItemByName(/AI \/ Machine learning/);
firstItem.focus();
await user.keyboard("{ArrowDown}");
const secondItem = getItemByName(/IBM Analytics Engine/);
expect(secondItem).toHaveAttribute("tabindex", "0");
expect(secondItem).toHaveFocus();
await user.keyboard("{ArrowUp}");
expect(firstItem).toHaveAttribute("tabindex", "0");
expect(firstItem).toHaveFocus();
});
it.only("can handle disabled nodes", () => {
render(component);
const disabledItem = screen.getByRole("treeitem", {
name: /Disabled Node/,
});
expect(disabledItem).toHaveAttribute("aria-disabled", "true");
expect(disabledItem).toHaveClass("bx--tree-node--disabled");
});
}); });