- Adicionado estrutura completa do projeto - Configurado MCP server para Premiere Pro - Adicionado documentação e skills - Configurado Gitignore para o projeto
57 lines
4.8 KiB
TypeScript
Executable File
57 lines
4.8 KiB
TypeScript
Executable File
import { describe, expect, it } from "vitest";
|
|
import { analyzeDialogueEditCandidates, getDialogueAnalysisTools } from "../../src/tools/dialogue-analysis.js";
|
|
|
|
const revision = `sha256:${"a".repeat(64)}`;
|
|
describe("dialogue candidate analysis", () => {
|
|
it("returns stable review candidates without applying edits", () => {
|
|
const input = { segments: [
|
|
{ id: "a", source_project_item_id: "clip", transcript_revision: revision, start_seconds: 0, end_seconds: 1, text: "Um hello world" },
|
|
{ id: "b", source_project_item_id: "clip", transcript_revision: revision, start_seconds: 1, end_seconds: 2, text: "hello world again" },
|
|
{ id: "c", source_project_item_id: "clip", transcript_revision: revision, start_seconds: 2, end_seconds: 3, text: "hello world again" },
|
|
], fillerWords: ["um"], silenceRanges: [{ source_project_item_id: "clip", start_seconds: 3, end_seconds: 4 }], minimumSilenceSeconds: .7 };
|
|
const first = analyzeDialogueEditCandidates(input), second = analyzeDialogueEditCandidates(input);
|
|
expect(first.analysis_revision).toBe(second.analysis_revision);
|
|
expect(first.candidates.map((x) => x.reason)).toEqual(["filler_word", "repeated_phrase", "long_silence"]);
|
|
expect(first.applied).toBe(false);
|
|
});
|
|
it("rejects unbound transcript input", () => expect(() => analyzeDialogueEditCandidates({ segments: [{ id: "a", source_project_item_id: "clip", transcript_revision: "bad", start_seconds: 0, end_seconds: 1, text: "hello" }] })).toThrow(/sha256/));
|
|
it.each([
|
|
[[], /between 1/], [[null], /must be an object/],
|
|
[[{ id: "a", source_project_item_id: "clip", transcript_revision: revision, start_seconds: 0, end_seconds: 1, text: "x", extra: 1 }], /unknown field/],
|
|
[[{ id: "a", source_project_item_id: "clip", transcript_revision: revision, start_seconds: 1, end_seconds: 1, text: "x" }], /greater/],
|
|
[[{ id: "a", source_project_item_id: "clip", transcript_revision: revision, start_seconds: 0, end_seconds: 1, text: 1 }], /text must/],
|
|
])("rejects malformed segments", (segments, message) => expect(() => analyzeDialogueEditCandidates({ segments })).toThrow(message));
|
|
it("validates optional analysis controls", () => {
|
|
const segments = [{ id: "a", source_project_item_id: "clip", transcript_revision: revision, start_seconds: 0, end_seconds: 1, text: "okay" }];
|
|
expect(() => analyzeDialogueEditCandidates({ segments, fillerWords: "um" })).toThrow(/filler_words/);
|
|
expect(() => analyzeDialogueEditCandidates({ segments, fillerWords: ["um", "um"] })).toThrow(/duplicates/);
|
|
expect(() => analyzeDialogueEditCandidates({ segments, minimumSilenceSeconds: 40 })).toThrow(/between/);
|
|
expect(() => analyzeDialogueEditCandidates({ segments, silenceRanges: "bad" })).toThrow(/silence_ranges/);
|
|
expect(() => analyzeDialogueEditCandidates({ segments, silenceRanges: [null] })).toThrow(/must be an object/);
|
|
expect(() => analyzeDialogueEditCandidates({ segments, silenceRanges: [{ source_project_item_id: "clip", start_seconds: 0, end_seconds: 1, extra: true }] })).toThrow(/unknown field/);
|
|
});
|
|
it("deduplicates time removal and ignores short silence", () => {
|
|
const segments = [
|
|
{ id: "a", source_project_item_id: "clip", transcript_revision: revision, start_seconds: 0, end_seconds: 2, text: "um okay" },
|
|
{ id: "b", source_project_item_id: "clip", transcript_revision: revision, start_seconds: 3, end_seconds: 4, text: "different" },
|
|
];
|
|
const result = analyzeDialogueEditCandidates({ segments, fillerWords: ["um"], silenceRanges: [{ source_project_item_id: "clip", start_seconds: 1, end_seconds: 3 }, { source_project_item_id: "clip", start_seconds: 5, end_seconds: 5.2 }], minimumSilenceSeconds: .5 });
|
|
expect(result.projected_removed_seconds).toBe(3);
|
|
expect(result.candidate_count).toBe(2);
|
|
});
|
|
it("rejects duplicate ids and invalid labels", () => {
|
|
const base = { id: "a", source_project_item_id: "clip", transcript_revision: revision, start_seconds: 0, end_seconds: 1, text: "x" };
|
|
expect(() => analyzeDialogueEditCandidates({ segments: [base, { ...base, start_seconds: 1, end_seconds: 2 }] })).toThrow(/duplicate id/);
|
|
expect(() => analyzeDialogueEditCandidates({ segments: [{ ...base, speaker_label: "" }] })).toThrow(/speaker_label/);
|
|
});
|
|
it("bounds very large candidate sets", () => {
|
|
const segments = Array.from({ length: 520 }, (_, index) => ({ id: String(index), source_project_item_id: "clip", transcript_revision: revision, start_seconds: index, end_seconds: index + .5, text: "um repeated phrase" }));
|
|
const result = analyzeDialogueEditCandidates({ segments, fillerWords: ["um"] });
|
|
expect(result.candidate_count).toBe(512);
|
|
expect(result.truncated).toBe(true);
|
|
});
|
|
it("normalizes handler failures", async () => {
|
|
expect((await getDialogueAnalysisTools().analyze_dialogue_edit_candidates.handler({ segments: [] })).success).toBe(false);
|
|
});
|
|
});
|