import { createRoot, createSignal } from "solid-js"; import { describe, expect, it, vi } from "vitest"; import { createControllableSignal } from "../../src/primitives/create-controllable-signal"; describe("createControllableSignal", () => { it("uses defaultValue when value accessor returns undefined (uncontrolled)", () => { createRoot((dispose) => { const [get] = createControllableSignal({ value: () => undefined, defaultValue: () => false, }); expect(get()).toBe(false); dispose(); }); }); it("uses value accessor when provided (controlled)", () => { createRoot((dispose) => { const [get] = createControllableSignal({ value: () => true, defaultValue: () => false, }); expect(get()).toBe(true); dispose(); }); }); it("calls onChange when setter is called in uncontrolled mode", () => { createRoot((dispose) => { const onChange = vi.fn(); const [, set] = createControllableSignal({ value: () => undefined, defaultValue: () => false, onChange, }); set(true); expect(onChange).toHaveBeenCalledWith(true); dispose(); }); }); it("updates internal signal when setter called in uncontrolled mode", () => { createRoot((dispose) => { const [get, set] = createControllableSignal({ value: () => undefined, defaultValue: () => "initial", }); set("updated"); expect(get()).toBe("updated"); dispose(); }); }); it("does not update internal signal in controlled mode — external value is source of truth", () => { createRoot((dispose) => { const [externalValue] = createSignal("controlled"); const [get, set] = createControllableSignal({ value: externalValue, defaultValue: () => "default", }); set("ignored"); // Still reflects external value since we're controlled expect(get()).toBe("controlled"); dispose(); }); }); });