PettyUI/packages/core/tests/primitives/create-controllable-signal.test.ts
2026-03-31 21:42:28 +07:00

68 lines
2.0 KiB
TypeScript

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<string>("controlled");
const [get, set] = createControllableSignal({
value: externalValue,
defaultValue: () => "default",
});
set("ignored");
// Still reflects external value since we're controlled
expect(get()).toBe("controlled");
dispose();
});
});
});