81 lines
3 KiB
TypeScript
81 lines
3 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { computeHistogramDifference, compositeLayerOrder, selectBestReferenceFrame } from "./videoProcessor";
|
|
import type { CompositeLayer } from "./videoProcessor";
|
|
|
|
describe("videoProcessor", () => {
|
|
describe("computeHistogramDifference", () => {
|
|
it("returns 0 for identical histograms", () => {
|
|
const hist = [0.25, 0.25, 0.25, 0.25];
|
|
const diff = computeHistogramDifference(hist, hist);
|
|
expect(diff).toBe(0);
|
|
});
|
|
|
|
it("returns a positive value for different histograms", () => {
|
|
const histA = [0.5, 0.3, 0.1, 0.1];
|
|
const histB = [0.1, 0.1, 0.3, 0.5];
|
|
const diff = computeHistogramDifference(histA, histB);
|
|
expect(diff).toBeGreaterThan(0);
|
|
});
|
|
|
|
it("returns 1.0 for mismatched lengths", () => {
|
|
const histA = [0.5, 0.5];
|
|
const histB = [0.33, 0.33, 0.34];
|
|
const diff = computeHistogramDifference(histA, histB);
|
|
expect(diff).toBe(1.0);
|
|
});
|
|
|
|
it("is symmetric", () => {
|
|
const histA = [0.4, 0.3, 0.2, 0.1];
|
|
const histB = [0.1, 0.2, 0.3, 0.4];
|
|
expect(computeHistogramDifference(histA, histB)).toBe(computeHistogramDifference(histB, histA));
|
|
});
|
|
});
|
|
|
|
describe("compositeLayerOrder", () => {
|
|
it("filters invisible layers and sorts by order", () => {
|
|
const layers: CompositeLayer[] = [
|
|
{ imageUrl: "/a.png", opacity: 1, order: 3, visible: true },
|
|
{ imageUrl: "/b.png", opacity: 0.5, order: 1, visible: true },
|
|
{ imageUrl: "/c.png", opacity: 1, order: 2, visible: false },
|
|
];
|
|
const result = compositeLayerOrder(layers);
|
|
expect(result).toHaveLength(2);
|
|
expect(result[0].imageUrl).toBe("/b.png");
|
|
expect(result[1].imageUrl).toBe("/a.png");
|
|
});
|
|
|
|
it("returns empty array when all layers are invisible", () => {
|
|
const layers: CompositeLayer[] = [
|
|
{ imageUrl: "/a.png", opacity: 1, order: 1, visible: false },
|
|
];
|
|
expect(compositeLayerOrder(layers)).toHaveLength(0);
|
|
});
|
|
});
|
|
|
|
describe("selectBestReferenceFrame", () => {
|
|
it("selects the highest quality static frame", () => {
|
|
const analyses = [
|
|
{ frameIndex: 0, qualityScore: 60, isStaticBackground: true },
|
|
{ frameIndex: 10, qualityScore: 95, isStaticBackground: true },
|
|
{ frameIndex: 20, qualityScore: 80, isStaticBackground: false },
|
|
{ frameIndex: 30, qualityScore: 70, isStaticBackground: true },
|
|
];
|
|
const best = selectBestReferenceFrame(analyses);
|
|
expect(best).toBe(10);
|
|
});
|
|
|
|
it("falls back to first frame when no static backgrounds exist", () => {
|
|
const analyses = [
|
|
{ frameIndex: 5, qualityScore: 90, isStaticBackground: false },
|
|
{ frameIndex: 15, qualityScore: 85, isStaticBackground: false },
|
|
];
|
|
const best = selectBestReferenceFrame(analyses);
|
|
expect(best).toBe(5);
|
|
});
|
|
|
|
it("returns 0 for empty array", () => {
|
|
const best = selectBestReferenceFrame([]);
|
|
expect(best).toBe(0);
|
|
});
|
|
});
|
|
});
|