cloudflare/kumo

Public

mirrored fromhttps://github.com/cloudflare/kumoAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
5260f1a5703bb69e6c7f7cf0ce8033a561cac8b5

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

packages/kumo-figma/src/generators/breadcrumbs.test.ts

229lines · modecode

1/**
2 * Breadcrumbs Generator Tests
3 *
4 * Tests the Breadcrumbs generator configuration and data structure.
5 * Follows the structural + snapshot testing pattern from badge.test.ts.
6 */
7
8import { describe, it, expect } from "vitest";
9import {
10 getBreadcrumbsSizeConfig,
11 getBreadcrumbsParsedSizeStyles,
12 getBreadcrumbsColorBindings,
13 getBreadcrumbsSeparatorConfig,
14 getAllBreadcrumbsData,
15} from "./breadcrumbs";
16import registry from "@cloudflare/kumo/ai/component-registry.json";
17
18describe("Breadcrumbs Generator - Registry Validation", () => {
19 it("should exist in registry", () => {
20 expect(registry.components.Breadcrumbs).toBeDefined();
21 });
22
23 it("should have size prop in registry", () => {
24 const breadcrumbsComponent = registry.components.Breadcrumbs;
25 expect(breadcrumbsComponent.props.size).toBeDefined();
26 });
27
28 it("should have size values in registry", () => {
29 const breadcrumbsComponent = registry.components.Breadcrumbs;
30 const sizeProp = breadcrumbsComponent.props.size as { values?: string[] };
31 expect(sizeProp.values).toBeDefined();
32 if (sizeProp.values) {
33 expect(Array.isArray(sizeProp.values)).toBe(true);
34 expect(sizeProp.values.length).toBeGreaterThan(0);
35 }
36 });
37
38 it("should have size classes in registry", () => {
39 const breadcrumbsComponent = registry.components.Breadcrumbs;
40 const sizeProp = breadcrumbsComponent.props.size as {
41 classes?: Record<string, string>;
42 };
43 expect(sizeProp.classes).toBeDefined();
44 expect(typeof sizeProp.classes).toBe("object");
45 });
46
47 it("should have subComponents in registry", () => {
48 const breadcrumbsComponent = registry.components.Breadcrumbs;
49 expect(breadcrumbsComponent.subComponents).toBeDefined();
50 expect(breadcrumbsComponent.subComponents.Link).toBeDefined();
51 expect(breadcrumbsComponent.subComponents.Current).toBeDefined();
52 expect(breadcrumbsComponent.subComponents.Separator).toBeDefined();
53 });
54});
55
56describe("Breadcrumbs Generator - Size Configuration", () => {
57 it("should have size config defined", () => {
58 const config = getBreadcrumbsSizeConfig();
59 expect(config).toBeDefined();
60 expect(config.values).toBeDefined();
61 expect(config.classes).toBeDefined();
62 expect(config.descriptions).toBeDefined();
63 expect(config.default).toBeDefined();
64 });
65
66 it("should have all sizes with classes", () => {
67 const config = getBreadcrumbsSizeConfig();
68 config.values.forEach((size) => {
69 expect(config.classes[size]).toBeDefined();
70 expect(typeof config.classes[size]).toBe("string");
71 expect(config.classes[size].length).toBeGreaterThan(0);
72 });
73 });
74
75 it("should have all sizes with descriptions", () => {
76 const config = getBreadcrumbsSizeConfig();
77 config.values.forEach((size) => {
78 expect(config.descriptions[size]).toBeDefined();
79 expect(typeof config.descriptions[size]).toBe("string");
80 });
81 });
82});
83
84describe("Breadcrumbs Generator - Parsed Size Styles", () => {
85 it("should parse sm size styles", () => {
86 const parsed = getBreadcrumbsParsedSizeStyles("sm");
87 expect(parsed).toBeDefined();
88 expect(parsed.size).toBe("sm");
89 expect(parsed.classes).toBeDefined();
90 expect(parsed.parsed).toBeDefined();
91 });
92
93 it("should parse base size styles", () => {
94 const parsed = getBreadcrumbsParsedSizeStyles("base");
95 expect(parsed).toBeDefined();
96 expect(parsed.size).toBe("base");
97 expect(parsed.classes).toBeDefined();
98 expect(parsed.parsed).toBeDefined();
99 });
100
101 it("should have height in parsed styles", () => {
102 const smParsed = getBreadcrumbsParsedSizeStyles("sm");
103 const baseParsed = getBreadcrumbsParsedSizeStyles("base");
104
105 // Parser should extract height from h-10 (40px) and h-12 (48px)
106 expect(smParsed.parsed.height).toBeDefined();
107 expect(baseParsed.parsed.height).toBeDefined();
108 });
109
110 it("should have gap in parsed styles", () => {
111 const smParsed = getBreadcrumbsParsedSizeStyles("sm");
112 const baseParsed = getBreadcrumbsParsedSizeStyles("base");
113
114 // Parser should extract gap from gap-0.5 and gap-1
115 expect(smParsed.parsed.gap).toBeDefined();
116 expect(baseParsed.parsed.gap).toBeDefined();
117 });
118
119 it("should have fontSize in parsed styles", () => {
120 const smParsed = getBreadcrumbsParsedSizeStyles("sm");
121 const baseParsed = getBreadcrumbsParsedSizeStyles("base");
122
123 // Parser should extract fontSize from text-sm and text-base
124 expect(smParsed.parsed.fontSize).toBeDefined();
125 expect(baseParsed.parsed.fontSize).toBeDefined();
126 });
127});
128
129describe("Breadcrumbs Generator - Color Bindings", () => {
130 it("should have color bindings defined", () => {
131 const bindings = getBreadcrumbsColorBindings();
132 expect(bindings).toBeDefined();
133 expect(bindings.link).toBeDefined();
134 expect(bindings.current).toBeDefined();
135 expect(bindings.separator).toBeDefined();
136 });
137
138 it("should have string values for all color bindings", () => {
139 const bindings = getBreadcrumbsColorBindings();
140 expect(typeof bindings.link).toBe("string");
141 expect(typeof bindings.current).toBe("string");
142 expect(typeof bindings.separator).toBe("string");
143 });
144
145 it("should use semantic kumo color tokens", () => {
146 const bindings = getBreadcrumbsColorBindings();
147 // Verify tokens follow the kumo semantic pattern without hardcoding exact values
148 expect(bindings.link).toMatch(/^text-color-kumo-/);
149 expect(bindings.current).toMatch(/^text-color-kumo-/);
150 expect(bindings.separator).toMatch(/^text-color-kumo-/);
151 });
152
153 it("should have different colors for link and current states", () => {
154 const bindings = getBreadcrumbsColorBindings();
155 // Current item should be visually distinct from link items
156 expect(bindings.link).not.toBe(bindings.current);
157 });
158});
159
160describe("Breadcrumbs Generator - Separator Configuration", () => {
161 it("should have separator config defined", () => {
162 const config = getBreadcrumbsSeparatorConfig();
163 expect(config).toBeDefined();
164 expect(config.iconName).toBeDefined();
165 expect(config.size).toBeDefined();
166 });
167
168 it("should use a phosphor icon", () => {
169 const config = getBreadcrumbsSeparatorConfig();
170 // Verify icon follows phosphor naming convention
171 expect(config.iconName).toMatch(/^ph-/);
172 });
173
174 it("should have numeric size", () => {
175 const config = getBreadcrumbsSeparatorConfig();
176 expect(typeof config.size).toBe("number");
177 expect(config.size).toBeGreaterThan(0);
178 });
179});
180
181describe("Breadcrumbs Generator - Complete Data Structure", () => {
182 it("should have all data defined", () => {
183 const allData = getAllBreadcrumbsData();
184 expect(allData).toBeDefined();
185 expect(allData.sizeConfig).toBeDefined();
186 expect(allData.sizes).toBeDefined();
187 expect(allData.colorBindings).toBeDefined();
188 expect(allData.separatorConfig).toBeDefined();
189 });
190
191 it("should have sizes array matching size config", () => {
192 const allData = getAllBreadcrumbsData();
193 expect(allData.sizes.length).toBe(allData.sizeConfig.values.length);
194 });
195
196 it("should have layout data for each size", () => {
197 const allData = getAllBreadcrumbsData();
198 allData.sizes.forEach((size) => {
199 expect(size.layout).toBeDefined();
200 expect(size.layout.height).toBeDefined();
201 expect(size.layout.gap).toBeDefined();
202 expect(size.layout.fontSize).toBeDefined();
203 expect(size.layout.itemGap).toBeDefined();
204 });
205 });
206
207 it("should have numeric layout dimensions", () => {
208 const allData = getAllBreadcrumbsData();
209 allData.sizes.forEach((size) => {
210 expect(typeof size.layout.height).toBe("number");
211 expect(typeof size.layout.gap).toBe("number");
212 expect(typeof size.layout.fontSize).toBe("number");
213 expect(typeof size.layout.itemGap).toBe("number");
214 });
215 });
216
217 it("should have sm size smaller than base size", () => {
218 const allData = getAllBreadcrumbsData();
219 const smSize = allData.sizes.find((s) => s.size === "sm");
220 const baseSize = allData.sizes.find((s) => s.size === "base");
221
222 if (smSize && baseSize) {
223 expect(smSize.layout.height).toBeLessThan(baseSize.layout.height);
224 expect(smSize.layout.fontSize).toBeLessThanOrEqual(
225 baseSize.layout.fontSize,
226 );
227 }
228 });
229});
230