summaryrefslogtreecommitdiff
path: root/apps/web/src/services/renderer/__tests__
diff options
context:
space:
mode:
authorcashmere <cashmere@autistici.org>2026-07-28 19:41:14 +0200
committercashmere <cashmere@autistici.org>2026-07-28 19:41:14 +0200
commite837e7504379e100ff3b56282577ec67bb88bec9 (patch)
treeeec7e6f964725a783a9e907e931862591bb46b55 /apps/web/src/services/renderer/__tests__
parentda99dec8a2de1f3849aebbf5695c1e812b2dbdf9 (diff)
downloadopencut-e837e7504379e100ff3b56282577ec67bb88bec9.tar.gz
feat: ripple-extend resize, timeline filmstrip, export hardening
Yesterday's verified web session (gates green: 316 tests, tsc, build): - ripple-extend pushes right-hand chain on static-element resize - per-position video filmstrip thumbnails with zoom-adaptive density - fps-aware export bitrate, 2s keyframes, even-dim export canvas - freeze frame uses fixed 3s duration, prompt removed
Diffstat (limited to 'apps/web/src/services/renderer/__tests__')
-rw-r--r--apps/web/src/services/renderer/__tests__/export-encoding.test.ts60
1 files changed, 60 insertions, 0 deletions
diff --git a/apps/web/src/services/renderer/__tests__/export-encoding.test.ts b/apps/web/src/services/renderer/__tests__/export-encoding.test.ts
new file mode 100644
index 00000000..fbf354eb
--- /dev/null
+++ b/apps/web/src/services/renderer/__tests__/export-encoding.test.ts
@@ -0,0 +1,60 @@
+import { describe, expect, test } from "bun:test";
+import { computeVideoBitrate } from "../export-encoding";
+
+describe("computeVideoBitrate", () => {
+ test("scales linearly with frame rate at the same resolution and quality", () => {
+ const at30 = computeVideoBitrate({
+ width: 1920,
+ height: 1080,
+ fps: 30,
+ quality: "high",
+ });
+ const at60 = computeVideoBitrate({
+ width: 1920,
+ height: 1080,
+ fps: 60,
+ quality: "high",
+ });
+
+ expect(at60).toBe(at30 * 2);
+ });
+
+ test("applies the bits-per-pixel ladder per quality tier", () => {
+ const params = { width: 1920, height: 1080, fps: 30 };
+
+ expect(computeVideoBitrate({ ...params, quality: "low" })).toBe(3_110_400);
+ expect(computeVideoBitrate({ ...params, quality: "medium" })).toBe(
+ 6_220_800,
+ );
+ expect(computeVideoBitrate({ ...params, quality: "high" })).toBe(
+ 12_441_600,
+ );
+ expect(computeVideoBitrate({ ...params, quality: "very_high" })).toBe(
+ 24_883_200,
+ );
+ });
+
+ test("increases monotonically across quality tiers", () => {
+ const params = { width: 1280, height: 720, fps: 30 };
+ const bitrates = (["low", "medium", "high", "very_high"] as const).map(
+ (quality) => computeVideoBitrate({ ...params, quality }),
+ );
+
+ for (let i = 1; i < bitrates.length; i++) {
+ expect(bitrates[i]).toBeGreaterThan(bitrates[i - 1]);
+ }
+ });
+
+ test("returns a positive integer for fractional frame rates", () => {
+ const bitrate = computeVideoBitrate({
+ width: 1920,
+ height: 1080,
+ fps: 29.97,
+ quality: "high",
+ });
+
+ expect(bitrate).toBe(12_429_158);
+ expect(Number.isInteger(bitrate)).toBe(true);
+ expect(bitrate).toBeGreaterThan(0);
+ });
+});