import assert from "assert"; import { Button } from "./widgets/Button"; import { Widget, WidgetConfig } from "./ui/Widget"; import { StringProp, NumberProp, BooleanProp } from "./core"; // Minimal mock implementations to avoid side effects from importing real widgets interface TextFieldConfig extends WidgetConfig { value?: StringProp; placeholder?: StringProp; disabled?: BooleanProp; readOnly?: BooleanProp; required?: BooleanProp; minLength?: NumberProp; maxLength?: NumberProp; validationErrorText?: StringProp; } class TextField extends Widget {} interface NumberFieldConfig extends WidgetConfig { value?: NumberProp; placeholder?: StringProp; minValue?: NumberProp; maxValue?: NumberProp; format?: StringProp; disabled?: BooleanProp; increment?: NumberProp; } class NumberField extends Widget {} import { Checkbox } from "./widgets/form/Checkbox"; import { bind } from "./ui/bind"; import { expr } from "./ui/expr"; import { createFunctionalComponent } from "./ui/createFunctionalComponent"; interface SandboxConfig extends WidgetConfig { key: StringProp; } class Sandbox extends Widget {} /** * These tests verify that widget props are correctly typed in JSX. * Negative tests use @ts-expect-error to verify that incorrect types are rejected. */ describe("jsx-runtime type inference", () => { describe("TextField", () => { it("accepts correct prop types", () => { const widget = ( ); assert.ok(widget); }); it("accepts binding for string props", () => { const widget = ( ); assert.ok(widget); }); it("accepts expressions for boolean props", () => { const widget = ( ); assert.ok(widget); }); it("rejects number for placeholder (expects string)", () => { const widget = ( {/* @ts-expect-error - placeholder should be StringProp, not a number */} ); assert.ok(widget); }); it("rejects string for minLength (expects number)", () => { const widget = ( {/* @ts-expect-error - minLength should be NumberProp, not a string */} ); assert.ok(widget); }); it("rejects string for maxLength (expects number)", () => { const widget = ( {/* @ts-expect-error - maxLength should be NumberProp, not a string */} ); assert.ok(widget); }); it("rejects number for disabled (expects boolean)", () => { const widget = ( {/* @ts-expect-error - disabled should be BooleanProp, not a number */} ); assert.ok(widget); }); it("rejects string for readOnly (expects boolean)", () => { const widget = ( {/* @ts-expect-error - readOnly should be BooleanProp, not a string */} ); assert.ok(widget); }); it("rejects non-existent properties", () => { const widget = ( {/* @ts-expect-error - nonExistentProp does not exist on TextFieldConfig */} ); assert.ok(widget); }); }); describe("NumberField", () => { it("accepts correct prop types", () => { const widget = ( ); assert.ok(widget); }); it("accepts bindings for number props", () => { const widget = ( ); assert.ok(widget); }); it("rejects string for value (expects number)", () => { const widget = ( {/* @ts-expect-error - value should be NumberProp, not a literal string */} ); assert.ok(widget); }); it("rejects string for minValue (expects number)", () => { const widget = ( {/* @ts-expect-error - minValue should be NumberProp, not a string */} ); assert.ok(widget); }); it("rejects string for maxValue (expects number)", () => { const widget = ( {/* @ts-expect-error - maxValue should be NumberProp, not a string */} ); assert.ok(widget); }); it("rejects boolean for increment (expects number)", () => { const widget = ( {/* @ts-expect-error - increment should be NumberProp, not a boolean */} ); assert.ok(widget); }); it("rejects number for format (expects string)", () => { const widget = ( {/* @ts-expect-error - format should be StringProp, not a number */} ); assert.ok(widget); }); }); describe("Button", () => { it("accepts correct prop types", () => { const widget = (