Merge feat/component-sequential: resolve conflicts in component/index.ts

This commit is contained in:
2026-05-21 20:51:13 +00:00
3 changed files with 81 additions and 2 deletions

View File

@@ -1,2 +1,4 @@
export { Parallel } from "./parallel.js";
export type { ParallelProps } from "./parallel.js";
export { Sequential } from "./sequential.js";
export type { SequentialProps } from "./sequential.js";

View File

@@ -1 +1,18 @@
export {};
import type { UElement, UNode } from "@alkdev/ujsx";
export interface SequentialProps {
id?: string;
}
function Sequential(props: SequentialProps & { children?: UNode[] }): UElement {
const { id, children } = props;
return {
type: "sequential",
props: id !== undefined ? { id } : {},
children: children ?? [],
};
}
Sequential.displayName = "Sequential";
export { Sequential };

View File

@@ -0,0 +1,60 @@
import { describe, it, expect } from "vitest";
import { Sequential } from "@/component/index.js";
import type { UElement, UNode } from "@alkdev/ujsx";
describe("Sequential", () => {
it("produces a UElement with type 'sequential' and no props", () => {
const result = Sequential({ children: [] });
expect(result.type).toBe("sequential");
expect(result.props).toEqual({});
expect(result.children).toEqual([]);
});
it("produces a UElement with optional id prop", () => {
const result = Sequential({ id: "my-seq", children: [] });
expect(result.type).toBe("sequential");
expect(result.props).toEqual({ id: "my-seq" });
expect(result.children).toEqual([]);
});
it("passes children through", () => {
const child1: UElement = { type: "operation", props: { name: "a" }, children: [] };
const child2: UElement = { type: "operation", props: { name: "b" }, children: [] };
const result = Sequential({ children: [child1, child2] });
expect(result.type).toBe("sequential");
expect(result.children).toEqual([child1, child2]);
});
it("single child is valid (degenerate case)", () => {
const child: UElement = { type: "operation", props: { name: "only" }, children: [] };
const result = Sequential({ children: [child] });
expect(result.type).toBe("sequential");
expect(result.children).toEqual([child]);
});
it("accepts nested structural children", () => {
const nested: UNode = { type: "parallel", props: {}, children: [] };
const result = Sequential({ children: [nested] });
expect(result.children).toHaveLength(1);
expect((result.children[0] as UElement).type).toBe("parallel");
});
it("omits id from props when not provided", () => {
const result = Sequential({ children: [] });
expect(result.props).not.toHaveProperty("id");
});
it("is a valid UElement (has type, props, children)", () => {
const result = Sequential({ children: [] });
expect(result).toHaveProperty("type");
expect(result).toHaveProperty("props");
expect(result).toHaveProperty("children");
expect(typeof result.type).toBe("string");
expect(typeof result.props).toBe("object");
expect(Array.isArray(result.children)).toBe(true);
});
it("displayName is Sequential", () => {
expect(Sequential.displayName).toBe("Sequential");
});
});