Initial Commit
This commit is contained in:
102
packages/foundation/data/templates/tests/presets.test.ts
Normal file
102
packages/foundation/data/templates/tests/presets.test.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* Integration tests for all preset bundles.
|
||||
*/
|
||||
import { describe, expect, it } from "@suaveplan/testing/runner";
|
||||
import type { createParseState } from "../src/engine/ParseState.js";
|
||||
import { TemplateEngine } from "../src/engine/TemplateEngine.js";
|
||||
import { fullPreset, fullPresetWithLoops } from "../src/presets/full.js";
|
||||
import { minimalPreset } from "../src/presets/minimal.js";
|
||||
import { standardPreset } from "../src/presets/standard.js";
|
||||
|
||||
type Ctx = Record<string, unknown>;
|
||||
|
||||
describe("minimalPreset", () => {
|
||||
it("resolves dot-notation", { timeout: 5000 }, () => {
|
||||
const e = new TemplateEngine<Ctx>().usePreset(minimalPreset<Ctx>());
|
||||
expect(e.parse("{user.name}", { user: { name: "Alice" } })).toBe(
|
||||
"Alice"
|
||||
);
|
||||
});
|
||||
|
||||
it("resolves array index", { timeout: 5000 }, () => {
|
||||
const e = new TemplateEngine<Ctx>().usePreset(minimalPreset<Ctx>());
|
||||
expect(e.parse("{items[1]}", { items: ["a", "b"] })).toBe("b");
|
||||
});
|
||||
|
||||
it("has 2 plugins", { timeout: 5000 }, () => {
|
||||
const e = new TemplateEngine<Ctx>().usePreset(minimalPreset<Ctx>());
|
||||
expect(e.getPlugins()).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe("standardPreset", () => {
|
||||
it("resolves variables, counter, case transform, conditional", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const e = new TemplateEngine<Ctx>().usePreset(standardPreset<Ctx>());
|
||||
const result = e.parse(
|
||||
"{if:active}Hello {name:title}! #{_counter}{/if}",
|
||||
{ active: true, name: "john doe" }
|
||||
);
|
||||
expect(result).toBe("Hello John Doe! #1");
|
||||
});
|
||||
|
||||
it("generates UUID in standard preset", { timeout: 5000 }, () => {
|
||||
const e = new TemplateEngine<Ctx>().usePreset(standardPreset<Ctx>());
|
||||
const result = e.parse("{_uuid}", {});
|
||||
expect(result).toMatch(
|
||||
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("fullPreset", () => {
|
||||
it("includes regex and string-split", { timeout: 5000 }, () => {
|
||||
const e = new TemplateEngine<Ctx>().usePreset(fullPreset<Ctx>());
|
||||
expect(
|
||||
e.parse("{phone:/\\D/g:replace:}", { phone: "(123) 456-7890" })
|
||||
).toBe("1234567890");
|
||||
expect(e.parse("{email:@[0]}", { email: "user@example.com" })).toBe(
|
||||
"user"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("fullPresetWithLoops", () => {
|
||||
it("iterates array with loop plugin", { timeout: 5000 }, () => {
|
||||
const e = new TemplateEngine<Ctx>();
|
||||
const preset = fullPresetWithLoops<Ctx>((tpl, ctx, state) =>
|
||||
(
|
||||
e as unknown as {
|
||||
parseInternal: (
|
||||
t: string,
|
||||
c: Ctx,
|
||||
s: ReturnType<typeof createParseState>
|
||||
) => string;
|
||||
}
|
||||
).parseInternal(tpl, ctx, state)
|
||||
);
|
||||
e.usePreset(preset);
|
||||
const result = e.parse("{each:items}{item} {/each}", {
|
||||
items: ["X", "Y", "Z"],
|
||||
});
|
||||
expect(result).toBe("X Y Z ");
|
||||
});
|
||||
|
||||
it("preset name is full-with-loops", { timeout: 5000 }, () => {
|
||||
const preset = fullPresetWithLoops<Ctx>((t, c) => t);
|
||||
expect(preset.name).toBe("full-with-loops");
|
||||
});
|
||||
});
|
||||
|
||||
describe("preset registration idempotency", () => {
|
||||
it("applying same preset twice does not duplicate plugins", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const e = new TemplateEngine<Ctx>();
|
||||
e.usePreset(minimalPreset<Ctx>());
|
||||
const countAfterFirst = e.getPlugins().length;
|
||||
e.usePreset(minimalPreset<Ctx>());
|
||||
expect(e.getPlugins()).toHaveLength(countAfterFirst);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user