release: WRNexusJS 0.8.0
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import {
|
||||
contentfulAdapter,
|
||||
createIncrementalHighlighter,
|
||||
renderMdxComponents,
|
||||
sanityAdapter,
|
||||
strapiAdapter,
|
||||
} from "../src/index.ts";
|
||||
|
||||
test("MDX executes only explicitly registered bounded components", () => {
|
||||
const html = renderMdxComponents(`<Callout tone="info">Safe</Callout>`, {
|
||||
Callout: (props, children) => `<aside class="${props.tone}">${children}</aside>`,
|
||||
});
|
||||
expect(html).toBe(`<aside class="info">Safe</aside>`);
|
||||
expect(() => renderMdxComponents(`<Unknown />`, {})).toThrow("not registered");
|
||||
});
|
||||
|
||||
test("syntax language bundles load once and only when encountered", async () => {
|
||||
let loads = 0;
|
||||
const highlighter = createIncrementalHighlighter({
|
||||
ts: async () => {
|
||||
loads++;
|
||||
return { highlight: (source) => `<mark>${source}</mark>` };
|
||||
},
|
||||
});
|
||||
expect(highlighter.languages()).toEqual([]);
|
||||
const html = await highlighter.render(`<pre><code class="language-ts">const x = 1;</code></pre>`);
|
||||
expect(html).toContain("<mark>const x = 1;</mark>");
|
||||
await highlighter.highlight("ts", "again");
|
||||
expect(loads).toBe(1);
|
||||
});
|
||||
|
||||
test("vendor adapters construct encoded authenticated requests and normalize records", async () => {
|
||||
const urls: string[] = [];
|
||||
const fetcher = async (input: RequestInfo | URL) => {
|
||||
urls.push(String(input));
|
||||
return Response.json({
|
||||
items: [{ sys: { id: "c1" }, fields: { body: "Contentful" } }],
|
||||
result: [{ _id: "s1", body: "Sanity" }],
|
||||
data: [{ id: "t1", body: "Strapi" }],
|
||||
});
|
||||
};
|
||||
expect((await contentfulAdapter("space", "master", { fetch: fetcher }).list("post"))[0]?.id).toBe(
|
||||
"c1",
|
||||
);
|
||||
expect((await sanityAdapter("project", "dataset", { fetch: fetcher }).list("post"))[0]?.id).toBe(
|
||||
"s1",
|
||||
);
|
||||
expect((await strapiAdapter("https://cms.test", { fetch: fetcher }).list("posts"))[0]?.id).toBe(
|
||||
"t1",
|
||||
);
|
||||
expect(urls.every((url) => url.startsWith("https://"))).toBeTrue();
|
||||
});
|
||||
@@ -0,0 +1,79 @@
|
||||
import { afterEach, describe, expect, test } from "bun:test";
|
||||
import { mkdir, rm, writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { tmpdir } from "node:os";
|
||||
import {
|
||||
contentRss,
|
||||
contentSitemap,
|
||||
createSearchIndex,
|
||||
defineCollection,
|
||||
localContentLoader,
|
||||
paginateContent,
|
||||
parseFrontmatter,
|
||||
remoteContentLoader,
|
||||
searchContent,
|
||||
} from "../src/index.ts";
|
||||
const roots: string[] = [];
|
||||
afterEach(async () =>
|
||||
Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true }))),
|
||||
);
|
||||
const schema = {
|
||||
parse(input: unknown) {
|
||||
const value = input as Record<string, unknown>;
|
||||
if (typeof value.title !== "string") throw new Error("title required");
|
||||
return {
|
||||
title: value.title,
|
||||
draft: value.draft === true,
|
||||
version: String(value.version ?? "v1"),
|
||||
};
|
||||
},
|
||||
};
|
||||
describe("typed content collections", () => {
|
||||
test("loads, validates, renders, filters drafts and supports preview/versioning", async () => {
|
||||
const root = join(tmpdir(), `wrn-content-${crypto.randomUUID()}`);
|
||||
roots.push(root);
|
||||
await mkdir(root);
|
||||
await writeFile(
|
||||
join(root, "hello.md"),
|
||||
"---\ntitle: Hello\nversion: v1\n---\n# Welcome\nUseful documentation.",
|
||||
);
|
||||
await writeFile(join(root, "draft.mdx"), "---\ntitle: Draft\ndraft: true\n---\nHidden");
|
||||
const collection = defineCollection({
|
||||
name: "docs",
|
||||
schema,
|
||||
loader: localContentLoader(root),
|
||||
previewToken: "secret",
|
||||
});
|
||||
expect(await collection.load()).toHaveLength(1);
|
||||
const preview = await collection.load({ previewToken: "secret" });
|
||||
expect(preview).toHaveLength(2);
|
||||
expect(preview[1]!.html).toContain("<h1");
|
||||
expect(await collection.get("hello", { version: "v1" })).not.toBeNull();
|
||||
});
|
||||
test("builds search, pagination, RSS and sitemap outputs", async () => {
|
||||
const collection = defineCollection({
|
||||
name: "docs",
|
||||
schema,
|
||||
loader: remoteContentLoader("https://cms.test/docs", {
|
||||
fetch: async () =>
|
||||
new Response(
|
||||
JSON.stringify([
|
||||
{ id: "guide", content: "---\ntitle: Guide\n---\n# Start\nSearch words" },
|
||||
]),
|
||||
) as any,
|
||||
}),
|
||||
});
|
||||
const entries = await collection.load();
|
||||
expect(searchContent(createSearchIndex(entries), "search words")).toHaveLength(1);
|
||||
expect(paginateContent(entries, 1, 1)).toMatchObject({ total: 1, totalPages: 1 });
|
||||
expect(contentRss(entries, { title: "Docs", baseUrl: "https://example.test/" })).toContain(
|
||||
"<rss",
|
||||
);
|
||||
expect(contentSitemap(entries, "https://example.test/")).toContain(
|
||||
"https://example.test/guide",
|
||||
);
|
||||
});
|
||||
test("rejects malformed frontmatter", () => {
|
||||
expect(() => parseFrontmatter("---\ntitle nope\n---\nbody")).toThrow("WRN-CONTENT-FRONTMATTER");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user