feat: add OCR language extension configuration and documentation

- Introduced `compose.ocr-languages.yml` for installing additional Tesseract OCR language packs during container startup.
- Updated documentation to include new OCR language extension options and usage scenarios.
- Enhanced existing documentation with references to the new OCR language extension guide.
- Improved test coverage for the deark converter and formats, ensuring accurate format handling and error management.
- Refactored code to streamline file system operations and improve readability.
This commit is contained in:
Your Name 2026-01-24 00:16:32 +08:00
parent 737e925ac7
commit a4489f4945
11 changed files with 766 additions and 90 deletions

View file

@ -1,5 +1,6 @@
import { test, expect, describe, mock } from "bun:test";
import { convert, properties } from "../../src/converters/deark";
import type { ExecFileFn } from "../../src/converters/types";
describe("deark converter", () => {
test("properties should have correct structure", () => {
@ -9,32 +10,34 @@ describe("deark converter", () => {
expect(properties.outputMode).toBe("archive");
});
test("properties.from should contain archive formats", () => {
expect(properties.from.archive).toBeDefined();
expect(properties.from.archive).toContain("zip");
expect(properties.from.archive).toContain("lha");
expect(properties.from.archive).toContain("arc");
test("properties.from should contain supported formats", () => {
expect(properties.from.files).toBeDefined();
// Archive formats
expect(properties.from.files).toContain("zip");
expect(properties.from.files).toContain("lha");
expect(properties.from.files).toContain("arc");
// Image formats
expect(properties.from.files).toContain("ico");
expect(properties.from.files).toContain("bmp");
expect(properties.from.files).toContain("pcx");
});
test("properties.from should contain image formats", () => {
expect(properties.from.images).toBeDefined();
expect(properties.from.images).toContain("ico");
expect(properties.from.images).toContain("bmp");
expect(properties.from.images).toContain("pcx");
});
test("properties.to should have extract option for all categories", () => {
for (const category of Object.keys(properties.from)) {
expect(properties.to[category]).toBeDefined();
expect(properties.to[category]).toContain("extract");
}
test("properties.to should have extract option", () => {
expect(properties.to.files).toBeDefined();
expect(properties.to.files).toContain("extract");
});
test("convert resolves when execFile succeeds", async () => {
const mockExecFile = mock((cmd: string, args: string[], callback: Function) => {
// First call is deark, second call is tar
callback(null, "Success", "");
});
const mockExecFile = mock(
(
cmd: string,
args: string[],
callback: (error: Error | null, stdout: string, stderr: string) => void,
) => {
// First call is deark, second call is tar
callback(null, "Success", "");
},
);
// Mock fs functions would be needed for full test
// This is a simplified test
@ -45,7 +48,7 @@ describe("deark converter", () => {
"extract",
"/tmp/output/test",
{},
mockExecFile as any,
mockExecFile as ExecFileFn,
);
} catch (error) {
// Expected to fail due to fs operations not being mocked
@ -54,9 +57,15 @@ describe("deark converter", () => {
});
test("convert rejects when deark fails", async () => {
const mockExecFile = mock((cmd: string, args: string[], callback: Function) => {
callback(new Error("deark failed"), "", "Unknown or unsupported format");
});
const mockExecFile = mock(
(
cmd: string,
args: string[],
callback: (error: Error | null, stdout: string, stderr: string) => void,
) => {
callback(new Error("deark failed"), "", "Unknown or unsupported format");
},
);
try {
await convert(
@ -65,7 +74,7 @@ describe("deark converter", () => {
"extract",
"/tmp/output/test",
{},
mockExecFile as any,
mockExecFile as ExecFileFn,
);
expect(true).toBe(false); // Should not reach here
} catch (error) {