50 lines
1.9 KiB
TypeScript
50 lines
1.9 KiB
TypeScript
import { describe, expect, it } from "@suaveplan/testing/runner";
|
|
import { parsePipeline } from "../src/pipeline/parser.js";
|
|
|
|
/**
|
|
* Property-style tests: the same op chain produced via the pipe-form string
|
|
* and via the positional bare-op tokens MUST yield the same internal edit
|
|
* chain. This is the parser invariant that lets the bare-op CLI form and
|
|
* `batch --pipeline` share a single downstream code path.
|
|
*/
|
|
describe("parsePipeline determinism", () => {
|
|
const cases: Array<{ str: string; tokens: readonly string[] }> = [
|
|
{ str: "trim 30s", tokens: ["trim", "30s"] },
|
|
{ str: "normalize -16lufs", tokens: ["normalize", "-16lufs"] },
|
|
{
|
|
str: "trim 30s | normalize -16lufs",
|
|
tokens: ["trim", "30s", "normalize", "-16lufs"],
|
|
},
|
|
{
|
|
str: "trim 30s | normalize | fade 0.5s 1s",
|
|
tokens: ["trim", "30s", "normalize", "fade", "0.5s", "1s"],
|
|
},
|
|
{ str: "gain 6db", tokens: ["gain", "6db"] },
|
|
];
|
|
for (const { str, tokens } of cases) {
|
|
it(`pipe-form and bare-op produce the same chain for: ${str}`, {
|
|
timeout: 5000,
|
|
}, () => {
|
|
expect(parsePipeline(tokens)).toEqual(parsePipeline(str));
|
|
});
|
|
}
|
|
|
|
it("idempotent: parse(parse(x)) is the identity for chained pipe forms", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
const once = parsePipeline("trim 30s | normalize -16lufs");
|
|
const reSerialised = once
|
|
.map(([name, opts]) => {
|
|
const args = Object.entries(opts).map(([k, v]) => {
|
|
if (k === "start") return `${v}s`;
|
|
if (k === "lufs") return `${v}lufs`;
|
|
return `${k}=${v}`;
|
|
});
|
|
return [name, ...args].join(" ");
|
|
})
|
|
.join(" | ");
|
|
const twice = parsePipeline(reSerialised);
|
|
expect(twice).toEqual(once);
|
|
});
|
|
});
|