feat: 发布 v0.4.0 桌面端
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
APP_VERSION,
|
||||
APP_VERSION_LABEL
|
||||
} from "../src/app-version";
|
||||
|
||||
describe("应用版本", () => {
|
||||
it("从统一构建版本生成标题徽标", () => {
|
||||
expect(APP_VERSION).toBe("0.4.0");
|
||||
expect(APP_VERSION_LABEL).toBe("v0.4.0");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,124 @@
|
||||
import {
|
||||
afterEach,
|
||||
describe,
|
||||
expect,
|
||||
it,
|
||||
vi
|
||||
} from "vitest";
|
||||
import {
|
||||
getThemeCss,
|
||||
listThemes,
|
||||
renderMarkdownDocument
|
||||
} from "../src/application-backend";
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
describe("应用后端适配器", () => {
|
||||
it("在桌面环境通过窄 IPC 调用共享服务", async () => {
|
||||
const rendered = {
|
||||
rendererVersion: 1 as const,
|
||||
articleHtml: '<article id="write">测试</article>',
|
||||
bodyHtml: "测试",
|
||||
metadata: {
|
||||
title: "测试",
|
||||
author: "",
|
||||
subject: "",
|
||||
keywords: [],
|
||||
language: "zh-CN"
|
||||
},
|
||||
features: [],
|
||||
warnings: []
|
||||
};
|
||||
const renderMarkdown = vi.fn(async () => rendered);
|
||||
const listDesktopThemes = vi.fn(async () => ({
|
||||
themes: [
|
||||
{
|
||||
id: "test",
|
||||
name: "测试",
|
||||
version: "1",
|
||||
description: "",
|
||||
bundled: true,
|
||||
source: "bundled" as const
|
||||
}
|
||||
]
|
||||
}));
|
||||
const getDesktopThemeCss = vi.fn(async () => "#write {}");
|
||||
vi.stubGlobal("window", {
|
||||
mdToPdfDesktop: {
|
||||
renderMarkdown,
|
||||
listThemes: listDesktopThemes,
|
||||
getThemeCss: getDesktopThemeCss
|
||||
}
|
||||
});
|
||||
|
||||
await expect(
|
||||
renderMarkdownDocument({
|
||||
markdown: "# 测试",
|
||||
language: "zh-CN"
|
||||
})
|
||||
).resolves.toBe(rendered);
|
||||
await expect(listThemes()).resolves.toEqual({
|
||||
themes: [expect.objectContaining({ id: "test" })]
|
||||
});
|
||||
await expect(getThemeCss("test")).resolves.toBe("#write {}");
|
||||
expect(renderMarkdown).toHaveBeenCalledWith({
|
||||
markdown: "# 测试",
|
||||
language: "zh-CN"
|
||||
});
|
||||
expect(getDesktopThemeCss).toHaveBeenCalledWith("test");
|
||||
});
|
||||
|
||||
it("在浏览器环境保持现有 HTTP 协议", async () => {
|
||||
vi.stubGlobal("window", {});
|
||||
const fetcher = vi
|
||||
.fn()
|
||||
.mockResolvedValueOnce(
|
||||
Response.json({
|
||||
rendererVersion: 1,
|
||||
articleHtml: '<article id="write">测试</article>',
|
||||
bodyHtml: "测试",
|
||||
metadata: {
|
||||
title: "测试",
|
||||
author: "",
|
||||
subject: "",
|
||||
keywords: [],
|
||||
language: "zh-CN"
|
||||
},
|
||||
features: [],
|
||||
warnings: []
|
||||
})
|
||||
)
|
||||
.mockResolvedValueOnce(
|
||||
Response.json({ themes: [] })
|
||||
)
|
||||
.mockResolvedValueOnce(
|
||||
new Response("#write {}", { status: 200 })
|
||||
);
|
||||
vi.stubGlobal("fetch", fetcher);
|
||||
|
||||
await renderMarkdownDocument({
|
||||
markdown: "# 测试",
|
||||
language: "zh-CN"
|
||||
});
|
||||
await listThemes();
|
||||
await getThemeCss("typora-like");
|
||||
|
||||
expect(fetcher).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
"/api/render",
|
||||
expect.objectContaining({ method: "POST" })
|
||||
);
|
||||
expect(fetcher).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
"/api/themes",
|
||||
{}
|
||||
);
|
||||
expect(fetcher).toHaveBeenNthCalledWith(
|
||||
3,
|
||||
"/api/themes/typora-like/css",
|
||||
{}
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,15 +1,30 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { defaultExportConfig } from "@md-to-pdf/core";
|
||||
import {
|
||||
afterEach,
|
||||
describe,
|
||||
expect,
|
||||
it,
|
||||
vi
|
||||
} from "vitest";
|
||||
import {
|
||||
createPagedDocumentPayload,
|
||||
defaultExportConfig
|
||||
} from "@md-to-pdf/core";
|
||||
import {
|
||||
createPdfExportCacheKey,
|
||||
downloadPdf,
|
||||
getCachedPdfExport,
|
||||
getOrRequestPdfExport,
|
||||
parseContentDispositionFileName,
|
||||
requestDesktopPdfExport,
|
||||
requestPdfExport,
|
||||
type CachedPdfExport,
|
||||
type PdfExportRequest
|
||||
} from "../src/pdf-export";
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
describe("PDF 导出客户端", () => {
|
||||
it("仅复用与当前文档和导出配置完全匹配的 PDF", () => {
|
||||
const request: PdfExportRequest = {
|
||||
@@ -178,4 +193,49 @@ describe("PDF 导出客户端", () => {
|
||||
)
|
||||
).rejects.toThrow("PDF 生成队列已满");
|
||||
});
|
||||
|
||||
it("桌面端使用共享分页载荷生成并保存 PDF", async () => {
|
||||
const payload = createPagedDocumentPayload({
|
||||
document: {
|
||||
rendererVersion: 1,
|
||||
articleHtml: '<article id="write">测试</article>',
|
||||
bodyHtml: "测试",
|
||||
metadata: {
|
||||
title: "测试",
|
||||
author: "",
|
||||
subject: "",
|
||||
keywords: [],
|
||||
language: "zh-CN"
|
||||
},
|
||||
features: [],
|
||||
warnings: []
|
||||
},
|
||||
fileName: "测试.md",
|
||||
themeCss: "",
|
||||
exportConfig: defaultExportConfig
|
||||
});
|
||||
const generatePdf = vi.fn(async () => ({
|
||||
pdf: new TextEncoder().encode("%PDF-desktop"),
|
||||
pageCount: 2,
|
||||
echartsErrors: [],
|
||||
mermaidErrors: ["图表 1"]
|
||||
}));
|
||||
const savePdf = vi.fn(async () => true);
|
||||
vi.stubGlobal("window", {
|
||||
mdToPdfDesktop: { generatePdf, savePdf }
|
||||
});
|
||||
|
||||
const generated = await requestDesktopPdfExport(payload);
|
||||
const saved = await downloadPdf(generated.blob, generated.fileName);
|
||||
|
||||
expect(generatePdf).toHaveBeenCalledWith(payload);
|
||||
expect(generated.fileName).toBe("测试.pdf");
|
||||
expect(generated.pageCount).toBe(2);
|
||||
expect(generated.mermaidErrorCount).toBe(1);
|
||||
expect(savePdf).toHaveBeenCalledWith(
|
||||
"测试.pdf",
|
||||
expect.any(Uint8Array)
|
||||
);
|
||||
expect(saved).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user