// crop 归一化纯函数单测:由 pytest 通过 node 执行(TDD 红阶段先失败)。 "use strict"; const assert = require("assert"); const { videoDisplayRect, rectToCrop, cropToRect } = require("../web/assets/crop.js"); // 1) 无留边(容器比例与视频一致):底部 20% 矩形 → crop [0, 0.8, 1, 0.2] let d = videoDisplayRect(1280, 720, 1280, 720); assert.deepStrictEqual(d, { x: 0, y: 0, w: 1280, h: 720 }); assert.deepStrictEqual( rectToCrop({ x: 0, y: 576, w: 1280, h: 144 }, 1280, 720, 1280, 720), [0, 0.8, 1, 0.2] ); // 2) letterbox(容器比视频宽):视频显示在中间,矩形映射要考虑左右留边 d = videoDisplayRect(1280, 720, 1600, 720); assert.deepStrictEqual(d, { x: 160, y: 0, w: 1280, h: 720 }); // 在渲染视频内框选右下 25% 区域 let crop = rectToCrop({ x: 160 + 640, y: 360, w: 640, h: 360 }, 1280, 720, 1600, 720); assert.deepStrictEqual(crop, [0.5, 0.5, 0.5, 0.5]); // 3) 回显一致性:crop → rect → crop 应还原(含 letterbox) let back = cropToRect(crop, 1280, 720, 1600, 720); assert.deepStrictEqual( rectToCrop(back, 1280, 720, 1600, 720), crop ); // 4) 越界钳制:矩形超出画面时 crop 值被限制在 0~1 crop = rectToCrop({ x: -100, y: -50, w: 2000, h: 900 }, 1280, 720, 1280, 720); assert.ok(crop.every((v) => v >= 0 && v <= 1)); console.log("crop.js 全部断言通过");