- Use function replacer in rewriteBody to prevent $& / $$ / $` / $' pattern corruption when alt text or siteUrl contains dollar-sign sequences - Detect empty staged index after `git add -A` and throw a clear "No changes to publish" error instead of a cryptic git failure - Correct README flat-slug description: single image → <slug>.<ext>, multiple → <slug>-1.<ext>, <slug>-2.<ext> (original filename discarded) - Harden askpass dir resolution: show a Notice and return early if getFullPath is absent (desktop-only guard), rather than passing a bad path Co-Authored-By: Claude <noreply@anthropic.com>
79 lines
3.8 KiB
TypeScript
79 lines
3.8 KiB
TypeScript
import { describe, expect, test } from "vitest";
|
|
import { findImageRefs, planImages, rewriteBody } from "./images";
|
|
|
|
describe("findImageRefs", () => {
|
|
test("detects embeds, markdown, html; ignores external and site-absolute", () => {
|
|
const body = [
|
|
"![[shot.png]]",
|
|
"",
|
|
'<img src="diagram.svg" alt="d">',
|
|
"",
|
|
"",
|
|
].join("\n");
|
|
const refs = findImageRefs(body);
|
|
expect(refs.map((r) => r.linktext)).toEqual(["shot.png", "pics/local.jpeg", "diagram.svg"]);
|
|
expect(refs.map((r) => r.kind)).toEqual(["embed", "markdown", "html"]);
|
|
expect(refs[1].alt).toBe("cap");
|
|
});
|
|
test("embed alias becomes alt text", () => {
|
|
expect(findImageRefs("![[a.png|My alt]]")[0].alt).toBe("My alt");
|
|
});
|
|
});
|
|
|
|
describe("planImages flat-slug", () => {
|
|
test("single image drops the numeric suffix", () => {
|
|
const body = "![[only.png]]";
|
|
const refs = findImageRefs(body);
|
|
const { rewrittenBody, plan } = planImages(refs, { slug: "my-post", strategy: "flat-slug", imagesDir: "assets/img", body });
|
|
expect(plan).toEqual([{ linktext: "only.png", repoPath: "assets/img/my-post.png", siteUrl: "/assets/img/my-post.png" }]);
|
|
expect(rewrittenBody).toBe("");
|
|
});
|
|
test("multiple images get -1, -2 suffixes and body is rewritten", () => {
|
|
const body = "![[a.png]]\n";
|
|
const refs = findImageRefs(body);
|
|
const { rewrittenBody, plan } = planImages(refs, { slug: "post", strategy: "flat-slug", imagesDir: "assets/img", body });
|
|
expect(plan.map((p) => p.repoPath)).toEqual(["assets/img/post-1.png", "assets/img/post-2.jpeg"]);
|
|
expect(rewrittenBody).toBe("\n");
|
|
});
|
|
});
|
|
|
|
describe("planImages per-post-folder", () => {
|
|
test("keeps original basename under a slug folder", () => {
|
|
const body = "![[sub/dir/Photo.PNG|cap]]";
|
|
const refs = findImageRefs(body);
|
|
const { plan, rewrittenBody } = planImages(refs, { slug: "post", strategy: "per-post-folder", imagesDir: "assets/img", body });
|
|
expect(plan[0].repoPath).toBe("assets/img/post/Photo.PNG");
|
|
expect(rewrittenBody).toBe("");
|
|
});
|
|
test("basename collisions are de-duped with -1", () => {
|
|
const body = "![[x/p.png]]\n![[y/p.png]]";
|
|
const refs = findImageRefs(body);
|
|
const { plan } = planImages(refs, { slug: "post", strategy: "per-post-folder", imagesDir: "assets/img", body });
|
|
expect(plan.map((p) => p.repoPath)).toEqual(["assets/img/post/p.png", "assets/img/post/p-1.png"]);
|
|
});
|
|
});
|
|
|
|
describe("rewriteBody", () => {
|
|
test("rewrites all ref types to markdown image syntax", () => {
|
|
const body = '![[shot.png]]\n\n<img src="diagram.svg" alt="d">';
|
|
const refs = findImageRefs(body);
|
|
const plan = [
|
|
{ linktext: "shot.png", repoPath: "assets/img/post-1.png", siteUrl: "/assets/img/post-1.png" },
|
|
{ linktext: "pics/local.jpeg", repoPath: "assets/img/post-2.jpeg", siteUrl: "/assets/img/post-2.jpeg" },
|
|
{ linktext: "diagram.svg", repoPath: "assets/img/post-3.svg", siteUrl: "/assets/img/post-3.svg" },
|
|
];
|
|
const result = rewriteBody(body, refs, plan);
|
|
expect(result).toBe(
|
|
"\n\n"
|
|
);
|
|
});
|
|
|
|
test("alt text containing $ patterns is preserved verbatim (no replacement-pattern corruption)", () => {
|
|
const slug = "my-post";
|
|
const body = "";
|
|
const refs = findImageRefs(body);
|
|
const { rewrittenBody } = planImages(refs, { slug, strategy: "flat-slug", imagesDir: "assets/img", body });
|
|
expect(rewrittenBody).toBe("");
|
|
});
|
|
});
|