test: add download mime, quality verification

This commit is contained in:
2026-09-26 03:33:09 +05:00
parent 746d6a6c8f
commit 712fd3cb2e
10 changed files with 181 additions and 33 deletions
+35 -1
View File
@@ -1,5 +1,9 @@
import { describe, expect, it } from "vitest";
import { isSupportedImage, unsupportedImageError } from "./io";
import {
isSupportedImage,
unsupportedImageError,
validateOutputQuality,
} from "./io";
describe("isSupportedImage", () => {
it.each([
@@ -38,3 +42,33 @@ describe("unsupportedImageError", () => {
expect(err.vars?.type).toBe("unknown");
});
});
describe("validateOutputQuality", () => {
it.each(["image/jpeg", "image/webp"] as const)(
"принимает границы 0 и 1 для %s",
(mime) => {
expect(() => validateOutputQuality(mime, 0)).not.toThrow();
expect(() => validateOutputQuality(mime, 1)).not.toThrow();
},
);
it.each(["image/jpeg", "image/webp"] as const)(
"отклоняет значение вне 0..1 для %s",
(mime) => {
expect(() => validateOutputQuality(mime, -0.01)).toThrow(
"errors.qualityRange",
);
expect(() => validateOutputQuality(mime, 1.01)).toThrow(
"errors.qualityRange",
);
expect(() => validateOutputQuality(mime, Number.NaN)).toThrow(
"errors.qualityRange",
);
},
);
it("не применяет quality к PNG и BMP", () => {
expect(() => validateOutputQuality("image/png", 2)).not.toThrow();
expect(() => validateOutputQuality("image/bmp", 2)).not.toThrow();
});
});
+14 -5
View File
@@ -84,6 +84,19 @@ export async function decodeTextImage(text: string): Promise<PixelImage> {
return await decodeBytes(bytes);
}
export function validateOutputQuality(
mime: OutputMime,
quality?: number,
): void {
if (mime !== "image/jpeg" && mime !== "image/webp") return;
if (
quality !== undefined &&
(!Number.isFinite(quality) || quality < 0 || quality > 1)
) {
throw new ToolError("errors.qualityRange");
}
}
export async function encode(
img: PixelImage,
mime: OutputMime = "image/png",
@@ -92,11 +105,7 @@ export async function encode(
if (mime === "image/bmp") {
return new Blob([encodeBmpBytes(img)], { type: mime });
}
if (mime === "image/jpeg" || mime === "image/webp") {
if (quality !== undefined && (quality < 0 || quality > 1)) {
throw new ToolError("errors.qualityRange");
}
}
validateOutputQuality(mime, quality);
const canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
+34
View File
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
import { TOOLS } from ".";
import { PREVIEW_GROUPS } from "../catalog";
import type { PixelImage } from "../core/types";
import type { OutputMime } from "../core/io";
import { defaultSchemaParams, sanitizeSchemaParams } from "../registry-schema";
import type { FileResult, ToolResult } from "./types";
@@ -78,6 +79,39 @@ describe("registry-new (переведённые инструменты)", () =>
}
});
it("output metadata согласован с MIME и quality-схемой", () => {
const extensions: Record<OutputMime, string> = {
"image/png": "png",
"image/jpeg": "jpg",
"image/webp": "webp",
"image/bmp": "bmp",
};
for (const tool of TOOLS) {
const output = tool.output;
if (!output) continue;
expect(extensions[output.mime], `${tool.id}: mime`).toBe(output.ext);
if (output.qualityParamId) {
const qualityField = tool.schema.fields[output.qualityParamId];
expect(
qualityField,
`${tool.id}.${output.qualityParamId}`,
).toBeDefined();
expect(["number", "slider"], `${tool.id}: quality kind`).toContain(
qualityField?.spec.kind,
);
} else if (output.mime === "image/jpeg" || output.mime === "image/webp") {
expect(output.qualityParamId, `${tool.id}: quality`).toBeTruthy();
}
if (output.mime === "image/bmp") {
expect(
output.qualityParamId,
`${tool.id}: bmp quality`,
).toBeUndefined();
}
}
});
it("source-aware dimension defaults применяются только к image tools", () => {
for (const tool of TOOLS) {
for (const field of Object.values(tool.schema.fields)) {