feat: initial commit - Jhonny Editor
- Adicionado estrutura completa do projeto - Configurado MCP server para Premiere Pro - Adicionado documentação e skills - Configurado Gitignore para o projeto
This commit is contained in:
+76
@@ -0,0 +1,76 @@
|
||||
import { mkdtempSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const { mockedExecFile, mockedExecFileAsync } = vi.hoisted(() => {
|
||||
const mockedExecFileAsync = vi.fn();
|
||||
const mockedExecFile = vi.fn();
|
||||
mockedExecFile[Symbol.for("nodejs.util.promisify.custom")] = mockedExecFileAsync;
|
||||
return { mockedExecFile, mockedExecFileAsync };
|
||||
});
|
||||
|
||||
vi.mock("node:child_process", () => ({ execFile: mockedExecFile }));
|
||||
|
||||
import { getExportTools, parseSceneChangeOutput } from "../../src/tools/export.js";
|
||||
|
||||
describe("parseSceneChangeOutput", () => {
|
||||
it("pairs times with scores and keeps the strongest nearby event", () => {
|
||||
const output = [
|
||||
"n:1 pts:100 pts_time:1.00",
|
||||
"lavfi.scene_score=0.40",
|
||||
"n:2 pts:110 pts_time:1.10",
|
||||
"lavfi.scene_score=0.75",
|
||||
"n:3 pts:300 pts_time:3.00",
|
||||
"lavfi.scene_score=0.55",
|
||||
].join("\n");
|
||||
expect(parseSceneChangeOutput(output, 0.25)).toEqual([
|
||||
{ timeSeconds: 1.1, score: 0.75 },
|
||||
{ timeSeconds: 3, score: 0.55 },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("detect_source_scene_changes boundary", () => {
|
||||
const tool = getExportTools({ tempDir: "/tmp/test" }).detect_source_scene_changes;
|
||||
beforeEach(() => vi.clearAllMocks());
|
||||
|
||||
it("rejects invalid thresholds and missing files", async () => {
|
||||
await expect(tool.handler({ media_path: "missing.mp4", threshold: 2 })).resolves.toMatchObject({ success: false });
|
||||
await expect(tool.handler({ media_path: "missing.mp4", minimum_interval_seconds: -1 })).resolves.toMatchObject({ success: false });
|
||||
await expect(tool.handler({ media_path: "missing.mp4", maximum_events: 0 })).resolves.toMatchObject({ success: false });
|
||||
await expect(tool.handler({ media_path: "missing.mp4" })).resolves.toMatchObject({ success: false, error: expect.stringContaining("not found") });
|
||||
});
|
||||
|
||||
it("returns bounded source-relative scene candidates from one local FFmpeg pass", async () => {
|
||||
const directory = mkdtempSync(join(tmpdir(), "premiere-scene-detect-"));
|
||||
const mediaPath = join(directory, "source.mp4");
|
||||
writeFileSync(mediaPath, "video-fixture");
|
||||
mockedExecFileAsync.mockResolvedValueOnce({
|
||||
stdout: "n:1 pts:100 pts_time:1.00\nlavfi.scene_score=0.40\nn:2 pts:300 pts_time:3.00\nlavfi.scene_score=0.55",
|
||||
stderr: "",
|
||||
});
|
||||
|
||||
await expect(tool.handler({ media_path: mediaPath, threshold: 0.3, minimum_interval_seconds: 0.25, maximum_events: 1 }))
|
||||
.resolves.toMatchObject({
|
||||
success: true,
|
||||
data: {
|
||||
mediaPath,
|
||||
totalDetected: 2,
|
||||
truncated: true,
|
||||
sceneChanges: [{ timeSeconds: 1, score: 0.4 }],
|
||||
},
|
||||
});
|
||||
expect(mockedExecFileAsync).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("keeps an FFmpeg scene-detection failure explicit", async () => {
|
||||
const directory = mkdtempSync(join(tmpdir(), "premiere-scene-error-"));
|
||||
const mediaPath = join(directory, "source.mp4");
|
||||
writeFileSync(mediaPath, "video-fixture");
|
||||
mockedExecFileAsync.mockRejectedValueOnce(Object.assign(new Error("decode failed"), { stderr: "bad video stream" }));
|
||||
|
||||
await expect(tool.handler({ media_path: mediaPath }))
|
||||
.resolves.toMatchObject({ success: false, error: expect.stringContaining("bad video stream") });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user