feat: release design system engine, studio and component contracts
This commit is contained in:
1 parent
ff1065fb27
commit
3943b946d6
693 files changed
+175546
-3894
No files matched your search
@@ -0,0 +1,98 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { chartConfiguration, chartTypes } from "../src/chart-config";
|
||||
import { renderComponent, mountHtml } from "../../test/src/index";
|
||||
import { discoverPlugins, createPluginRunner } from "../../plugin/src/index";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
const source = readFileSync(new URL("../components/Chart.wrn", import.meta.url), "utf8");
|
||||
for (const type of chartTypes) {
|
||||
test(`Chart.js ${type} preserves native datasets`, () => {
|
||||
const data = {
|
||||
labels: ["A", "B"],
|
||||
datasets: [
|
||||
{
|
||||
label: "Example",
|
||||
data: type === "scatter" || type === "bubble" ? [{ x: 1, y: -2, r: 5 }] : [-20, 40],
|
||||
},
|
||||
],
|
||||
};
|
||||
const config = chartConfiguration({ type, data });
|
||||
expect(config.type).toBe(type);
|
||||
expect(config.data).toEqual(data);
|
||||
expect(config.data).not.toBe(data);
|
||||
if (["pie", "doughnut", "radar", "polarArea"].includes(type))
|
||||
expect(config.options?.scales).toBeUndefined();
|
||||
});
|
||||
}
|
||||
test("legacy rows preserve negatives, gaps, zero, and small decimal values", () => {
|
||||
const config = chartConfiguration({
|
||||
items: [
|
||||
{ label: "Loss", value: -20 },
|
||||
{ label: "Gap", value: null },
|
||||
{ label: "Invalid", value: "oops" },
|
||||
{ label: "Zero", value: 0 },
|
||||
{ label: "Tiny", value: 0.0002 },
|
||||
],
|
||||
});
|
||||
expect(config.data.datasets[0].data).toEqual([-20, null, null, 0, 0.0002]);
|
||||
expect(config.data.labels).toEqual(["Loss", "Gap", "Invalid", "Zero", "Tiny"]);
|
||||
});
|
||||
test("native dataset options, mixed types, area fills, and stacked horizontal axes survive", () => {
|
||||
const data = {
|
||||
labels: ["A"],
|
||||
datasets: [
|
||||
{ type: "bar" as const, data: [20] },
|
||||
{ type: "line" as const, data: [10], borderColor: "red" },
|
||||
],
|
||||
};
|
||||
const options = {
|
||||
indexAxis: "y",
|
||||
scales: { x: { stacked: true }, y: { stacked: true } },
|
||||
plugins: { legend: { display: false } },
|
||||
};
|
||||
const config = chartConfiguration({ type: "bar", data, options });
|
||||
expect(config.data).toEqual(data);
|
||||
expect(config.options?.indexAxis).toBe("y");
|
||||
expect((config.options?.scales?.x as any)?.stacked).toBe(true);
|
||||
expect(config.options?.plugins?.legend?.display).toBe(false);
|
||||
const area = chartConfiguration({ type: "area", data: { datasets: [{ data: [1, 2] }] } });
|
||||
expect(area.type).toBe("line");
|
||||
expect((area.data.datasets[0] as any).fill).toBe(true);
|
||||
expect(() => chartConfiguration({ type: "unknown" })).toThrow("Unsupported chart type");
|
||||
});
|
||||
test("separate datasets and custom legacy keys remain supported", () => {
|
||||
expect(chartConfiguration({ labels: ["A"], datasets: [{ data: [3] }] }).data).toEqual({
|
||||
labels: ["A"],
|
||||
datasets: [{ data: [3] }],
|
||||
});
|
||||
expect(
|
||||
chartConfiguration({ items: [{ name: "A", amount: -2 }], labelKey: "name", valueKey: "amount" })
|
||||
.data.datasets[0].data,
|
||||
).toEqual([-2]);
|
||||
});
|
||||
test("SSR safely carries native chart config and typed public outputs", async () => {
|
||||
const data = { labels: ["<script>bad</script>"], datasets: [{ label: "Sample", data: [-2] }] };
|
||||
const dom = mountHtml(await renderComponent(source, { type: "radar", data }));
|
||||
const root = dom.querySelector('[data-ui-component="Chart"]') as HTMLElement;
|
||||
expect(root.dataset.wrnexusRuntime).toBe("chartjs");
|
||||
expect(JSON.parse(root.dataset.chartConfig!).data).toEqual(data);
|
||||
expect(root.querySelector("canvas")?.getAttribute("role")).toBe("img");
|
||||
expect(root.querySelector("script")).toBeNull();
|
||||
});
|
||||
test("UI package discovers its bundled Chart.js runtime automatically", async () => {
|
||||
const plugins = await discoverPlugins(resolve("examples/component-showcase"), [], {
|
||||
strict: true,
|
||||
});
|
||||
const runner = createPluginRunner(plugins, {
|
||||
root: resolve("examples/component-showcase"),
|
||||
mode: "development",
|
||||
command: "dev",
|
||||
metadata: new Map(),
|
||||
warn: () => {},
|
||||
});
|
||||
const contributions = await runner.contributions();
|
||||
expect(
|
||||
contributions.clientRuntimes.some((runtime) => runtime.id === "chartjs" && runtime.bundle),
|
||||
).toBe(true);
|
||||
});
|
||||
Reference in new issue
Block a user