import { mount } from "$core/binder"; import { extractDeps } from "$core/shared"; import { signal } from "$core/signal"; import { describe, expect, it } from "vitest"; describe("data-volt-if binding", () => { it("shows element when condition is truthy", () => { const container = document.createElement("div"); container.innerHTML = `

Hidden

`; const show = signal(true); const message = "Visible!"; mount(container, { show, message }); const paragraph = container.querySelector("p"); expect(paragraph).toBeTruthy(); expect(paragraph?.textContent).toBe("Visible!"); }); it("hides element when condition is falsy", () => { const container = document.createElement("div"); container.innerHTML = `

Should not appear

`; const show = signal(false); mount(container, { show }); const paragraph = container.querySelector("p"); expect(paragraph).toBeNull(); }); it("toggles element visibility when signal changes", () => { const container = document.createElement("div"); container.innerHTML = `
Toggle Me
`; const visible = signal(false); mount(container, { visible }); expect(container.querySelector("span")).toBeNull(); visible.set(true); expect(container.querySelector("span")).toBeTruthy(); expect(container.querySelector("span")?.textContent).toBe("Toggle Me"); visible.set(false); expect(container.querySelector("span")).toBeNull(); visible.set(true); expect(container.querySelector("span")).toBeTruthy(); }); it("works with static truthy values", () => { const container = document.createElement("div"); container.innerHTML = `

Always visible

`; mount(container, { alwaysTrue: true }); const paragraph = container.querySelector("p"); expect(paragraph).toBeTruthy(); expect(paragraph?.textContent).toBe("Always visible"); }); it("works with static falsy values", () => { const container = document.createElement("div"); container.innerHTML = `

Never visible

`; mount(container, { alwaysFalse: false }); expect(container.querySelector("p")).toBeNull(); }); it("preserves element bindings when re-rendering", () => { const container = document.createElement("div"); container.innerHTML = `
Default
`; const show = signal(true); const message = signal("First"); mount(container, { show, message }); expect(container.querySelector("span")?.textContent).toBe("First"); message.set("Second"); expect(container.querySelector("span")?.textContent).toBe("Second"); show.set(false); expect(container.querySelector("div[data-volt-if]")).toBeNull(); message.set("Third"); show.set(true); expect(container.querySelector("span")?.textContent).toBe("Third"); }); it("handles nested bindings correctly", () => { const container = document.createElement("div"); container.innerHTML = `

Outer

Inner

`; const showOuter = signal(true); const showInner = signal(true); mount(container, { showOuter, showInner }); expect(container.textContent?.trim()).toContain("Outer"); expect(container.textContent?.trim()).toContain("Inner"); showInner.set(false); expect(container.textContent?.trim()).toContain("Outer"); expect(container.textContent?.trim()).not.toContain("Inner"); showOuter.set(false); expect(container.textContent?.trim()).not.toContain("Outer"); expect(container.textContent?.trim()).not.toContain("Inner"); showOuter.set(true); expect(container.textContent?.trim()).toContain("Outer"); expect(container.textContent?.trim()).not.toContain("Inner"); showInner.set(true); expect(container.textContent?.trim()).toContain("Outer"); expect(container.textContent?.trim()).toContain("Inner"); }); it("properly cleans up when unmounting", () => { const container = document.createElement("div"); container.innerHTML = `

Hidden

`; const show = signal(true); const message = signal("Hello"); const cleanup = mount(container, { show, message }); expect(container.querySelector("p")?.textContent).toBe("Hello"); const elementBeforeCleanup = container.querySelector("p"); cleanup(); message.set("Changed"); expect(elementBeforeCleanup?.textContent).toBe("Hello"); show.set(false); expect(container.querySelector("p")).toBe(elementBeforeCleanup); }); it("handles event handlers correctly", () => { const container = document.createElement("div"); container.innerHTML = `
`; let clicked = false; const handleClick = () => { clicked = true; }; const show = signal(true); mount(container, { show, handleClick }); const button = container.querySelector("button"); expect(button).toBeTruthy(); button?.click(); expect(clicked).toBe(true); show.set(false); expect(container.querySelector("button")).toBeNull(); clicked = false; show.set(true); container.querySelector("button")?.click(); expect(clicked).toBe(true); }); it("works with property paths", () => { const container = document.createElement("div"); container.innerHTML = `

User is active

`; const user = { isActive: signal(true) }; mount(container, { user }); expect(container.querySelector("p")).toBeTruthy(); user.isActive.set(false); expect(container.querySelector("p")).toBeNull(); user.isActive.set(true); expect(container.querySelector("p")).toBeTruthy(); }); it("evaluates truthy and falsy values correctly", () => { const container = document.createElement("div"); container.innerHTML = `

0

Empty

1

String

`; mount(container, { zero: signal(0), empty: signal(""), one: signal(1), string: signal("text") }); expect(container.querySelector("#zero")).toBeNull(); expect(container.querySelector("#empty")).toBeNull(); expect(container.querySelector("#one")).toBeTruthy(); expect(container.querySelector("#string")).toBeTruthy(); }); it("reacts to complex expressions with multiple signal dependencies", () => { const container = document.createElement("div"); container.innerHTML = `

Error message

`; const value = signal(""); const isValid = signal(true); const scope = { value, isValid }; const deps = extractDeps("value.length > 0 && !isValid", scope); expect(deps.length).toBe(2); expect(deps).toContain(value); expect(deps).toContain(isValid); mount(container, scope); expect(container.querySelector("p")).toBeNull(); value.set("test"); expect(container.querySelector("p")).toBeNull(); isValid.set(false); expect(container.querySelector("p")).toBeTruthy(); expect(container.querySelector("p")?.textContent).toBe("Error message"); value.set(""); expect(container.querySelector("p")).toBeNull(); value.set("test"); expect(container.querySelector("p")).toBeTruthy(); isValid.set(true); expect(container.querySelector("p")).toBeNull(); }); });