init
This commit is contained in:
291
index.test.ts
Normal file
291
index.test.ts
Normal file
@@ -0,0 +1,291 @@
|
||||
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")
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user