/** * Type-level tests for Cell.key() with multiple keys * * These tests verify that key() correctly handles multiple keys. * If the types are incorrect, these tests will fail to compile. */ import { describe, it } from "@std/testing/bdd"; import { expect } from "@std/expect"; import type { AsCell, Cell, KeyResultType, Stream, } from "../src/builder/types.ts"; // ============================================================================ // Type-level assertions (compile-time checks) // ============================================================================ /** * Helper type that asserts two types are equal. * If T and U are not the same, this produces `never`. */ type AssertEqual = [T] extends [U] ? ([U] extends [T] ? true : never) : never; /** * Helper to force a compile error if the type is not `true`. * Usage: const _check: MustBeTrue> = true; */ type MustBeTrue = T; // Test data types type User = { name: string; age: number; profile: { bio: string; avatar: string; settings: { theme: "light" | "dark"; notifications: boolean; }; }; posts: Array<{ id: number; title: string; content: string; }>; }; // ============================================================================ // KeyResultType type tests // ============================================================================ // Use value assignments to enforce type checks at compile time // Empty keys should return the original type const _test1: MustBeTrue< AssertEqual, Cell> > = true; // Single key const _test2: MustBeTrue< AssertEqual, Cell> > = true; const _test3: MustBeTrue< AssertEqual, Cell> > = true; const _test4: MustBeTrue< AssertEqual< KeyResultType, Cell > > = true; // Two keys const _test5: MustBeTrue< AssertEqual< KeyResultType, Cell > > = true; const _test6: MustBeTrue< AssertEqual< KeyResultType, Cell > > = true; // Three keys const _test7: MustBeTrue< AssertEqual< KeyResultType, Cell<"light" | "dark"> > > = true; const _test8: MustBeTrue< AssertEqual< KeyResultType, Cell > > = true; // Array access const _test9: MustBeTrue< AssertEqual< KeyResultType, Cell > > = true; const _test10: MustBeTrue< AssertEqual< KeyResultType, Cell > > = true; // Unknown keys should fall back to Cell const _test11: MustBeTrue< AssertEqual< KeyResultType, Cell > > = true; const _test12: MustBeTrue< AssertEqual< KeyResultType, Cell > > = true; // ============================================================================ // Nested Cell and Stream type tests // ============================================================================ // Type with nested Cell and Stream type StateWithNestedCells = { user: Cell; events: Stream<{ type: string; data: unknown }>; nested: { counter: Cell; notifications: Stream; }; }; // When accessing a property that is Cell, returns Cell directly (not Cell>) const _testNestedCell1: MustBeTrue< AssertEqual< KeyResultType, Cell > > = true; // When accessing a property that is Stream, returns Stream directly (not Cell>) const _testNestedStream1: MustBeTrue< AssertEqual< KeyResultType, Stream<{ type: string; data: unknown }> > > = true; // Nested path to Cell - returns Cell directly const _testNestedCell2: MustBeTrue< AssertEqual< KeyResultType, Cell > > = true; // Nested path to Stream - returns Stream directly const _testNestedStream2: MustBeTrue< AssertEqual< KeyResultType, Stream > > = true; // ============================================================================ // Runtime tests (behavior verification) // ============================================================================ describe("Cell.key() with multiple keys", () => { it("compiles with correct types - this test verifies the type assertions above", () => { // If this file compiles, the type tests pass // The type assertions above use MustBeTrue which would cause compile errors if wrong expect(true).toBe(true); }); it("key() with no keys should have same type as the cell", () => { // This is a compile-time check - if types are wrong, this won't compile const checkType = (_cell: Cell, _keyed: Cell) => {}; const _useCheckType = (cell: Cell) => { // @ts-expect-error - key() with no args returns Cell, not void const _keyed: void = cell.key(); // This should compile fine: checkType(cell, cell.key()); }; expect(true).toBe(true); }); it("key() with multiple keys works", () => { const _useCheckType = (cell: Cell) => { // Single key const _name: Cell = cell.key("name"); // Two keys const _bio: Cell = cell.key("profile", "bio"); // Three keys const _theme: Cell<"light" | "dark"> = cell.key( "profile", "settings", "theme", ); // Array access const _post: Cell = cell.key("posts", 0); const _title: Cell = cell.key("posts", 0, "title"); }; expect(true).toBe(true); }); });