Files
tdir/index.test.ts
Gregor Lohaus 0fd19254e9 eq directive
2026-04-15 22:37:13 +02:00

300 lines
8.6 KiB
TypeScript

import { expect, test, beforeEach, afterEach } from 'bun:test'
import { initRenderer, SchemaMismatchError } from ".";
import { z } from "zod"
import { mkdtempSync, rmSync, existsSync, readFileSync } from "node:fs"
import { join } from "node:path"
import { tmpdir } from "node:os"
const ifExampleSchema = z.object({
web: z.boolean(),
header: z.object({
render: z.boolean(),
text: z.string()
})
})
let tmp: string
beforeEach(() => {
tmp = mkdtempSync(join(tmpdir(), "tdir-test-"))
})
afterEach(() => {
rmSync(tmp, { recursive: true, force: true })
})
test("createRenderer validates schema matches templates", () => {
const createRenderer = initRenderer("./testdata/if_example")
expect(() => createRenderer(ifExampleSchema)).not.toThrow()
expect(() => createRenderer(z.object({ web: z.boolean() }))).toThrow(SchemaMismatchError)
expect(() => createRenderer(z.object({
web: z.string(),
header: z.object({ render: z.boolean(), text: z.string() })
}))).toThrow(SchemaMismatchError)
})
test("render validates context via zod", () => {
const createRenderer = initRenderer("./testdata/if_example")
const render = createRenderer(ifExampleSchema)
expect(() => render(tmp, {} as any)).toThrow(z.ZodError)
expect(() => render(tmp, { web: "nope" } as any)).toThrow(z.ZodError)
expect(() => render(tmp, { web: true, header: { render: true } } as any)).toThrow(z.ZodError)
})
test("renders with web=true, header rendered", () => {
const createRenderer = initRenderer("./testdata/if_example")
const render = createRenderer(ifExampleSchema)
render(tmp, { web: true, header: { render: true, text: "My Title" } })
const outFile = join(tmp, "web", "if_example.html")
expect(existsSync(outFile)).toBe(true)
const content = readFileSync(outFile, "utf-8")
expect(content).toContain("My Title")
expect(content).toContain("<head>")
expect(content).toContain("<body>")
})
test("wrong schema throws error",() => {
const createRenderer = initRenderer("./testdata/if_example")
expect(() => createRenderer(z.object({
web: z.string(),
header: z.object({
render: z.string(),
text: z.boolean()
})
}))).toThrow(new SchemaMismatchError({message: 'expected z.boolean() but schema has z.string()', path: 'web'}))
})
test("wrong schema throws error",() => {
const createRenderer = initRenderer("./testdata/if_example")
expect(() => createRenderer(z.object({
web: z.boolean(),
header: z.object({
render: z.string(),
text: z.boolean()
})
}))).toThrow(new SchemaMismatchError({message: 'expected z.boolean() but schema has z.string()', path: 'header.render'}))
})
test("wrong schema throws error",() => {
const createRenderer = initRenderer("./testdata/if_example")
expect(() => createRenderer(z.object({
web: z.boolean(),
header: z.object({
render: z.boolean(),
text: z.boolean()
})
}))).toThrow(new SchemaMismatchError({message: 'expected z.string() but schema has z.boolean()', path: 'header.text'}))
})
test("renders with web=true, header not rendered", () => {
const createRenderer = initRenderer("./testdata/if_example")
const render = createRenderer(ifExampleSchema)
render(tmp, { web: true, header: { render: false, text: "Ignored" } })
const outFile = join(tmp, "web", "if_example.html")
expect(existsSync(outFile)).toBe(true)
const content = readFileSync(outFile, "utf-8")
expect(content).not.toContain("Ignored")
expect(content).not.toContain("<head>")
expect(content).toContain("<body>")
})
test("renders with web=false, skips directory", () => {
const createRenderer = initRenderer("./testdata/if_example")
const render = createRenderer(ifExampleSchema)
render(tmp, { web: false, header: { render: true, text: "Hello" } })
expect(existsSync(join(tmp, "web"))).toBe(false)
})
test("vars in path are added to schema",() => {
const createRenderer = initRenderer("./testdata/var_in_path")
expect(() => createRenderer(z.object({
web: z.boolean(),
header: z.object({
render: z.boolean(),
text: z.boolean()
})
}))).toThrow(new SchemaMismatchError({message: 'expected z.object() but schema has z.boolean()', path: 'web'}))
})
test("vars in path renders correctrly",() => {
const createRenderer = initRenderer("./testdata/var_in_path")
const render = createRenderer(z.object({
web: z.object({
create: z.boolean(),
dir: z.string()
}),
header: z.object({
render: z.boolean(),
text: z.string()
})
}))
render(tmp,{
web: {
create: true,
dir: "web"
},
header: {
render: false,
text: "test"
}
})
expect(existsSync(join(tmp, "web"))).toBe(true)
const outFile = join(tmp, "web", "var_in_path_example.html")
expect(existsSync(outFile)).toBe(true)
const content = readFileSync(outFile, "utf-8")
expect(content).not.toContain("Ignored")
expect(content).not.toContain("<head>")
expect(content).toContain("<body>")
})
test("vars in path renders correctrly",() => {
const createRenderer = initRenderer("./testdata/var_in_path")
const render = createRenderer(z.object({
web: z.object({
create: z.boolean(),
dir: z.string()
}),
header: z.object({
render: z.boolean(),
text: z.string()
})
}))
render(tmp,{
web: {
create: true,
dir: "test"
},
header: {
render: true,
text: "test"
}
})
expect(existsSync(join(tmp, "test"))).toBe(true)
const outFile = join(tmp, "test", "var_in_path_example.html")
expect(existsSync(outFile)).toBe(true)
const content = readFileSync(outFile, "utf-8")
expect(content).toContain("test")
expect(content).toContain("<head>")
expect(content).toContain("<body>")
})
test("nested if dir renders correctly",() => {
const createRenderer = initRenderer("./testdata/nested_if_dir")
const render = createRenderer(z.object({
web: z.boolean(),
webnested: z.boolean()
}))
render(tmp,{
web: true,
webnested: true
})
expect(existsSync(join(tmp, "web"))).toBe(true)
})
test("nested if dir renders correctly",() => {
const createRenderer = initRenderer("./testdata/nested_if_dir_named")
const render = createRenderer(z.object({
web: z.boolean(),
webnested: z.boolean()
}))
render(tmp,{
web: true,
webnested: true
})
expect(existsSync(join(tmp, "nested" , "web"))).toBe(true)
})
test("multiple dirs 1 var",() => {
const createRenderer = initRenderer("./testdata/multi_dir_one_var")
const render = createRenderer(z.object({
web: z.boolean(),
}))
render(tmp,{
web: true,
})
expect(existsSync(join(tmp, "dir1"))).toBe(true)
expect(existsSync(join(tmp, "dir2"))).toBe(true)
expect(existsSync(join(tmp, "dir1", "dir1n"))).toBe(true)
})
test("file if",() => {
const createRenderer = initRenderer("./testdata/file_if")
const render = createRenderer(z.object({
web: z.boolean(),
file: z.boolean(),
text: z.string()
}))
render(tmp,{
web: true,
file: true,
text: "test"
})
expect(existsSync(join(tmp, "web"))).toBe(true)
const outFile = join(tmp, "web", "example.txt")
expect(existsSync(outFile)).toBe(true)
const content = readFileSync(outFile, "utf-8")
expect(content).toContain("test")
})
test("no endif should throw",() => {
const createRenderer = initRenderer("./testdata/no_end_if")
const render = createRenderer(z.object({
test: z.boolean(),
}))
expect( () => render(tmp,{
test: true,
})).toThrow()
})
test("if elseif else",() => {
const createRenderer = initRenderer("./testdata/if_elseif_else_in_file")
const render = createRenderer(z.object({
test: z.boolean(),
test2: z.boolean()
}))
render(tmp,{
test: true,
test2: true
})
let outFile = join(tmp, "test.txt")
expect(existsSync(outFile)).toBe(true)
let content = readFileSync(outFile, "utf-8")
expect(content).toContain("test")
render(tmp,{
test: false,
test2: true
})
outFile = join(tmp, "test.txt")
expect(existsSync(outFile)).toBe(true)
content = readFileSync(outFile, "utf-8")
expect(content).toContain("test2")
render(tmp,{
test: false,
test2: false
})
outFile = join(tmp, "test.txt")
expect(existsSync(outFile)).toBe(true)
content = readFileSync(outFile, "utf-8")
expect(content).toContain("test3")
})
test("if eq in path", () => {
const createRenderer = initRenderer("./testdata/eq_in_path")
const render = createRenderer(z.object({test: z.string()}))
render(tmp,{test:"test"})
expect(existsSync(join(tmp,"test"))).toBe(true)
render(tmp,{test:"foo"})
expect(existsSync(join(tmp,"test"))).toBe(false)
})