'use strict'; const { test } = require('node:test'); const assert = require('node:assert'); const VE = require('./video-edit'); test('parseTime: bare seconds, clock forms, fractions', () => { assert.strictEqual(VE.parseTime('90'), 90); assert.strictEqual(VE.parseTime('1:30'), 90); assert.strictEqual(VE.parseTime('1:00:00'), 3600); assert.strictEqual(VE.parseTime('0:05.5'), 5.5); assert.strictEqual(VE.parseTime(42), 42); }); test('parseTime: rejects garbage and negatives', () => { assert.strictEqual(VE.parseTime(''), null); assert.strictEqual(VE.parseTime('abc'), null); assert.strictEqual(VE.parseTime('1:99'), null); // seconds field out of range assert.strictEqual(VE.parseTime('-3'), null); assert.strictEqual(VE.parseTime('1:2:3:4'), null); }); test('normalizeCuts: clamps, drops zero-length, merges overlaps', () => { const cuts = [ { start: -5, end: 10 }, // clamps to 0-10 { start: 8, end: 15 }, // overlaps → merge to 0-15 { start: 40, end: 40 }, // zero-length → dropped { start: 200, end: 300 }, // clamps end to duration 120 → 120-120 dropped? start>dur { start: 50, end: 60 }, ]; const out = VE.normalizeCuts(cuts, 120); assert.deepStrictEqual(out, [ { start: 0, end: 15 }, { start: 50, end: 60 }, ]); }); test('normalizeCuts: reversed range tolerated', () => { assert.deepStrictEqual(VE.normalizeCuts([{ start: 30, end: 10 }], 60), [{ start: 10, end: 30 }]); }); test('invertCuts: complement over [0,duration]', () => { const keep = VE.invertCuts([{ start: 10, end: 20 }], 60); assert.deepStrictEqual(keep, [{ start: 0, end: 10 }, { start: 20, end: 60 }]); }); test('invertCuts: cut at the very start and end', () => { const keep = VE.invertCuts([{ start: 0, end: 5 }, { start: 55, end: 60 }], 60); assert.deepStrictEqual(keep, [{ start: 5, end: 55 }]); }); test('invertCuts: no cuts keeps whole video', () => { assert.deepStrictEqual(VE.invertCuts([], 60), [{ start: 0, end: 60 }]); }); test('invertCuts: cutting the entire video yields no keep segments', () => { assert.deepStrictEqual(VE.invertCuts([{ start: 0, end: 60 }], 60), []); }); test('invertCuts: needs a finite positive duration', () => { assert.deepStrictEqual(VE.invertCuts([{ start: 1, end: 2 }], 0), []); assert.deepStrictEqual(VE.invertCuts([{ start: 1, end: 2 }], Infinity), []); }); test('keepDuration sums surviving spans', () => { const keep = VE.invertCuts([{ start: 10, end: 20 }], 60); assert.strictEqual(VE.keepDuration(keep), 50); }); test('keepToParam / parseKeepParam round-trip', () => { const keep = [{ start: 12.5, end: 40 }, { start: 95, end: 130.2 }]; const param = VE.keepToParam(keep); assert.strictEqual(param, '12.5-40,95-130.2'); assert.deepStrictEqual(VE.parseKeepParam(param), keep); }); test('parseKeepParam skips malformed / non-increasing tokens', () => { assert.deepStrictEqual(VE.parseKeepParam('0-10,bad,20-15,30-40'), [ { start: 0, end: 10 }, { start: 30, end: 40 }, ]); assert.deepStrictEqual(VE.parseKeepParam(''), []); assert.deepStrictEqual(VE.parseKeepParam(null), []); }); test('hasEdits reflects whether a real cut exists', () => { assert.strictEqual(VE.hasEdits([], 60), false); assert.strictEqual(VE.hasEdits([{ start: 0, end: 0 }], 60), false); assert.strictEqual(VE.hasEdits([{ start: 5, end: 10 }], 60), true); });