mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-27 18:22:41 -08:00
pretty
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import * as fs from "fs";
|
||||
import * as os from "os";
|
||||
import * as path from "path";
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import {
|
||||
TriggerSubsyncFromConfigDeps,
|
||||
runSubsyncManual,
|
||||
triggerSubsyncFromConfig,
|
||||
} from "./subsync";
|
||||
} from './subsync';
|
||||
|
||||
function makeDeps(
|
||||
overrides: Partial<TriggerSubsyncFromConfigDeps> = {},
|
||||
@@ -17,21 +17,21 @@ function makeDeps(
|
||||
currentAudioStreamIndex: null,
|
||||
send: () => {},
|
||||
requestProperty: async (name: string) => {
|
||||
if (name === "path") return "/tmp/video.mkv";
|
||||
if (name === "sid") return 1;
|
||||
if (name === "secondary-sid") return null;
|
||||
if (name === "track-list") {
|
||||
if (name === 'path') return '/tmp/video.mkv';
|
||||
if (name === 'sid') return 1;
|
||||
if (name === 'secondary-sid') return null;
|
||||
if (name === 'track-list') {
|
||||
return [
|
||||
{ id: 1, type: "sub", selected: true, lang: "jpn" },
|
||||
{ id: 1, type: 'sub', selected: true, lang: 'jpn' },
|
||||
{
|
||||
id: 2,
|
||||
type: "sub",
|
||||
type: 'sub',
|
||||
selected: false,
|
||||
external: true,
|
||||
lang: "eng",
|
||||
"external-filename": "/tmp/ref.srt",
|
||||
lang: 'eng',
|
||||
'external-filename': '/tmp/ref.srt',
|
||||
},
|
||||
{ id: 3, type: "audio", selected: true, "ff-index": 1 },
|
||||
{ id: 3, type: 'audio', selected: true, 'ff-index': 1 },
|
||||
];
|
||||
}
|
||||
return null;
|
||||
@@ -41,10 +41,10 @@ function makeDeps(
|
||||
return {
|
||||
getMpvClient: () => mpvClient,
|
||||
getResolvedConfig: () => ({
|
||||
defaultMode: "manual",
|
||||
alassPath: "/usr/bin/alass",
|
||||
ffsubsyncPath: "/usr/bin/ffsubsync",
|
||||
ffmpegPath: "/usr/bin/ffmpeg",
|
||||
defaultMode: 'manual',
|
||||
alassPath: '/usr/bin/alass',
|
||||
ffsubsyncPath: '/usr/bin/ffsubsync',
|
||||
ffmpegPath: '/usr/bin/ffmpeg',
|
||||
}),
|
||||
isSubsyncInProgress: () => false,
|
||||
setSubsyncInProgress: () => {},
|
||||
@@ -55,7 +55,7 @@ function makeDeps(
|
||||
};
|
||||
}
|
||||
|
||||
test("triggerSubsyncFromConfig returns early when already in progress", async () => {
|
||||
test('triggerSubsyncFromConfig returns early when already in progress', async () => {
|
||||
const osd: string[] = [];
|
||||
await triggerSubsyncFromConfig(
|
||||
makeDeps({
|
||||
@@ -65,10 +65,10 @@ test("triggerSubsyncFromConfig returns early when already in progress", async ()
|
||||
},
|
||||
}),
|
||||
);
|
||||
assert.deepEqual(osd, ["Subsync already running"]);
|
||||
assert.deepEqual(osd, ['Subsync already running']);
|
||||
});
|
||||
|
||||
test("triggerSubsyncFromConfig opens manual picker in manual mode", async () => {
|
||||
test('triggerSubsyncFromConfig opens manual picker in manual mode', async () => {
|
||||
const osd: string[] = [];
|
||||
let payloadTrackCount = 0;
|
||||
let inProgressState: boolean | null = null;
|
||||
@@ -88,11 +88,11 @@ test("triggerSubsyncFromConfig opens manual picker in manual mode", async () =>
|
||||
);
|
||||
|
||||
assert.equal(payloadTrackCount, 1);
|
||||
assert.ok(osd.includes("Subsync: choose engine and source"));
|
||||
assert.ok(osd.includes('Subsync: choose engine and source'));
|
||||
assert.equal(inProgressState, false);
|
||||
});
|
||||
|
||||
test("triggerSubsyncFromConfig reports failures to OSD", async () => {
|
||||
test('triggerSubsyncFromConfig reports failures to OSD', async () => {
|
||||
const osd: string[] = [];
|
||||
await triggerSubsyncFromConfig(
|
||||
makeDeps({
|
||||
@@ -103,34 +103,29 @@ test("triggerSubsyncFromConfig reports failures to OSD", async () => {
|
||||
}),
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
osd.some((line) => line.startsWith("Subsync failed: MPV not connected")),
|
||||
);
|
||||
assert.ok(osd.some((line) => line.startsWith('Subsync failed: MPV not connected')));
|
||||
});
|
||||
|
||||
test("runSubsyncManual requires a source track for alass", async () => {
|
||||
const result = await runSubsyncManual(
|
||||
{ engine: "alass", sourceTrackId: null },
|
||||
makeDeps(),
|
||||
);
|
||||
test('runSubsyncManual requires a source track for alass', async () => {
|
||||
const result = await runSubsyncManual({ engine: 'alass', sourceTrackId: null }, makeDeps());
|
||||
|
||||
assert.deepEqual(result, {
|
||||
ok: false,
|
||||
message: "Select a subtitle source track for alass",
|
||||
message: 'Select a subtitle source track for alass',
|
||||
});
|
||||
});
|
||||
|
||||
test("triggerSubsyncFromConfig reports path validation failures", async () => {
|
||||
test('triggerSubsyncFromConfig reports path validation failures', async () => {
|
||||
const osd: string[] = [];
|
||||
const inProgress: boolean[] = [];
|
||||
|
||||
await triggerSubsyncFromConfig(
|
||||
makeDeps({
|
||||
getResolvedConfig: () => ({
|
||||
defaultMode: "auto",
|
||||
alassPath: "/missing/alass",
|
||||
ffsubsyncPath: "/missing/ffsubsync",
|
||||
ffmpegPath: "/missing/ffmpeg",
|
||||
defaultMode: 'auto',
|
||||
alassPath: '/missing/alass',
|
||||
ffsubsyncPath: '/missing/ffsubsync',
|
||||
ffmpegPath: '/missing/ffmpeg',
|
||||
}),
|
||||
setSubsyncInProgress: (value) => {
|
||||
inProgress.push(value);
|
||||
@@ -143,30 +138,28 @@ test("triggerSubsyncFromConfig reports path validation failures", async () => {
|
||||
|
||||
assert.deepEqual(inProgress, [true, false]);
|
||||
assert.ok(
|
||||
osd.some((line) =>
|
||||
line.startsWith("Subsync failed: Configured ffmpeg executable not found"),
|
||||
),
|
||||
osd.some((line) => line.startsWith('Subsync failed: Configured ffmpeg executable not found')),
|
||||
);
|
||||
});
|
||||
|
||||
function writeExecutableScript(filePath: string, content: string): void {
|
||||
fs.writeFileSync(filePath, content, { encoding: "utf8", mode: 0o755 });
|
||||
fs.writeFileSync(filePath, content, { encoding: 'utf8', mode: 0o755 });
|
||||
fs.chmodSync(filePath, 0o755);
|
||||
}
|
||||
|
||||
test("runSubsyncManual constructs ffsubsync command and returns success", async () => {
|
||||
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "subsync-ffsubsync-"));
|
||||
const ffsubsyncLogPath = path.join(tmpDir, "ffsubsync-args.log");
|
||||
const ffsubsyncPath = path.join(tmpDir, "ffsubsync.sh");
|
||||
const ffmpegPath = path.join(tmpDir, "ffmpeg.sh");
|
||||
const alassPath = path.join(tmpDir, "alass.sh");
|
||||
const videoPath = path.join(tmpDir, "video.mkv");
|
||||
const primaryPath = path.join(tmpDir, "primary.srt");
|
||||
test('runSubsyncManual constructs ffsubsync command and returns success', async () => {
|
||||
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'subsync-ffsubsync-'));
|
||||
const ffsubsyncLogPath = path.join(tmpDir, 'ffsubsync-args.log');
|
||||
const ffsubsyncPath = path.join(tmpDir, 'ffsubsync.sh');
|
||||
const ffmpegPath = path.join(tmpDir, 'ffmpeg.sh');
|
||||
const alassPath = path.join(tmpDir, 'alass.sh');
|
||||
const videoPath = path.join(tmpDir, 'video.mkv');
|
||||
const primaryPath = path.join(tmpDir, 'primary.srt');
|
||||
|
||||
fs.writeFileSync(videoPath, "video");
|
||||
fs.writeFileSync(primaryPath, "sub");
|
||||
writeExecutableScript(ffmpegPath, "#!/bin/sh\nexit 0\n");
|
||||
writeExecutableScript(alassPath, "#!/bin/sh\nexit 0\n");
|
||||
fs.writeFileSync(videoPath, 'video');
|
||||
fs.writeFileSync(primaryPath, 'sub');
|
||||
writeExecutableScript(ffmpegPath, '#!/bin/sh\nexit 0\n');
|
||||
writeExecutableScript(alassPath, '#!/bin/sh\nexit 0\n');
|
||||
writeExecutableScript(
|
||||
ffsubsyncPath,
|
||||
`#!/bin/sh\n: > "${ffsubsyncLogPath}"\nfor arg in "$@"; do printf '%s\\n' "$arg" >> "${ffsubsyncLogPath}"; done\nout=\"\"\nprev=\"\"\nfor arg in \"$@\"; do\n if [ \"$prev\" = \"-o\" ]; then out=\"$arg\"; fi\n prev=\"$arg\"\ndone\nif [ -n \"$out\" ]; then : > \"$out\"; fi\nexit 0\n`,
|
||||
@@ -181,17 +174,17 @@ test("runSubsyncManual constructs ffsubsync command and returns success", async
|
||||
sentCommands.push(payload.command);
|
||||
},
|
||||
requestProperty: async (name: string) => {
|
||||
if (name === "path") return videoPath;
|
||||
if (name === "sid") return 1;
|
||||
if (name === "secondary-sid") return null;
|
||||
if (name === "track-list") {
|
||||
if (name === 'path') return videoPath;
|
||||
if (name === 'sid') return 1;
|
||||
if (name === 'secondary-sid') return null;
|
||||
if (name === 'track-list') {
|
||||
return [
|
||||
{
|
||||
id: 1,
|
||||
type: "sub",
|
||||
type: 'sub',
|
||||
selected: true,
|
||||
external: true,
|
||||
"external-filename": primaryPath,
|
||||
'external-filename': primaryPath,
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -199,45 +192,42 @@ test("runSubsyncManual constructs ffsubsync command and returns success", async
|
||||
},
|
||||
}),
|
||||
getResolvedConfig: () => ({
|
||||
defaultMode: "manual",
|
||||
defaultMode: 'manual',
|
||||
alassPath,
|
||||
ffsubsyncPath,
|
||||
ffmpegPath,
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await runSubsyncManual(
|
||||
{ engine: "ffsubsync", sourceTrackId: null },
|
||||
deps,
|
||||
);
|
||||
const result = await runSubsyncManual({ engine: 'ffsubsync', sourceTrackId: null }, deps);
|
||||
|
||||
assert.equal(result.ok, true);
|
||||
assert.equal(result.message, "Subtitle synchronized with ffsubsync");
|
||||
const ffArgs = fs.readFileSync(ffsubsyncLogPath, "utf8").trim().split("\n");
|
||||
assert.equal(result.message, 'Subtitle synchronized with ffsubsync');
|
||||
const ffArgs = fs.readFileSync(ffsubsyncLogPath, 'utf8').trim().split('\n');
|
||||
assert.equal(ffArgs[0], videoPath);
|
||||
assert.ok(ffArgs.includes("-i"));
|
||||
assert.ok(ffArgs.includes('-i'));
|
||||
assert.ok(ffArgs.includes(primaryPath));
|
||||
assert.ok(ffArgs.includes("--reference-stream"));
|
||||
assert.ok(ffArgs.includes("0:2"));
|
||||
assert.equal(sentCommands[0]?.[0], "sub_add");
|
||||
assert.deepEqual(sentCommands[1], ["set_property", "sub-delay", 0]);
|
||||
assert.ok(ffArgs.includes('--reference-stream'));
|
||||
assert.ok(ffArgs.includes('0:2'));
|
||||
assert.equal(sentCommands[0]?.[0], 'sub_add');
|
||||
assert.deepEqual(sentCommands[1], ['set_property', 'sub-delay', 0]);
|
||||
});
|
||||
|
||||
test("runSubsyncManual constructs alass command and returns failure on non-zero exit", async () => {
|
||||
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "subsync-alass-"));
|
||||
const alassLogPath = path.join(tmpDir, "alass-args.log");
|
||||
const alassPath = path.join(tmpDir, "alass.sh");
|
||||
const ffmpegPath = path.join(tmpDir, "ffmpeg.sh");
|
||||
const ffsubsyncPath = path.join(tmpDir, "ffsubsync.sh");
|
||||
const videoPath = path.join(tmpDir, "video.mkv");
|
||||
const primaryPath = path.join(tmpDir, "primary.srt");
|
||||
const sourcePath = path.join(tmpDir, "source.srt");
|
||||
test('runSubsyncManual constructs alass command and returns failure on non-zero exit', async () => {
|
||||
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'subsync-alass-'));
|
||||
const alassLogPath = path.join(tmpDir, 'alass-args.log');
|
||||
const alassPath = path.join(tmpDir, 'alass.sh');
|
||||
const ffmpegPath = path.join(tmpDir, 'ffmpeg.sh');
|
||||
const ffsubsyncPath = path.join(tmpDir, 'ffsubsync.sh');
|
||||
const videoPath = path.join(tmpDir, 'video.mkv');
|
||||
const primaryPath = path.join(tmpDir, 'primary.srt');
|
||||
const sourcePath = path.join(tmpDir, 'source.srt');
|
||||
|
||||
fs.writeFileSync(videoPath, "video");
|
||||
fs.writeFileSync(primaryPath, "sub");
|
||||
fs.writeFileSync(sourcePath, "sub2");
|
||||
writeExecutableScript(ffmpegPath, "#!/bin/sh\nexit 0\n");
|
||||
writeExecutableScript(ffsubsyncPath, "#!/bin/sh\nexit 0\n");
|
||||
fs.writeFileSync(videoPath, 'video');
|
||||
fs.writeFileSync(primaryPath, 'sub');
|
||||
fs.writeFileSync(sourcePath, 'sub2');
|
||||
writeExecutableScript(ffmpegPath, '#!/bin/sh\nexit 0\n');
|
||||
writeExecutableScript(ffsubsyncPath, '#!/bin/sh\nexit 0\n');
|
||||
writeExecutableScript(
|
||||
alassPath,
|
||||
`#!/bin/sh\n: > "${alassLogPath}"\nfor arg in "$@"; do printf '%s\\n' "$arg" >> "${alassLogPath}"; done\nexit 1\n`,
|
||||
@@ -249,24 +239,24 @@ test("runSubsyncManual constructs alass command and returns failure on non-zero
|
||||
currentAudioStreamIndex: null,
|
||||
send: () => {},
|
||||
requestProperty: async (name: string) => {
|
||||
if (name === "path") return videoPath;
|
||||
if (name === "sid") return 1;
|
||||
if (name === "secondary-sid") return null;
|
||||
if (name === "track-list") {
|
||||
if (name === 'path') return videoPath;
|
||||
if (name === 'sid') return 1;
|
||||
if (name === 'secondary-sid') return null;
|
||||
if (name === 'track-list') {
|
||||
return [
|
||||
{
|
||||
id: 1,
|
||||
type: "sub",
|
||||
type: 'sub',
|
||||
selected: true,
|
||||
external: true,
|
||||
"external-filename": primaryPath,
|
||||
'external-filename': primaryPath,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
type: "sub",
|
||||
type: 'sub',
|
||||
selected: false,
|
||||
external: true,
|
||||
"external-filename": sourcePath,
|
||||
'external-filename': sourcePath,
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -274,39 +264,36 @@ test("runSubsyncManual constructs alass command and returns failure on non-zero
|
||||
},
|
||||
}),
|
||||
getResolvedConfig: () => ({
|
||||
defaultMode: "manual",
|
||||
defaultMode: 'manual',
|
||||
alassPath,
|
||||
ffsubsyncPath,
|
||||
ffmpegPath,
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await runSubsyncManual(
|
||||
{ engine: "alass", sourceTrackId: 2 },
|
||||
deps,
|
||||
);
|
||||
const result = await runSubsyncManual({ engine: 'alass', sourceTrackId: 2 }, deps);
|
||||
|
||||
assert.equal(result.ok, false);
|
||||
assert.equal(typeof result.message, "string");
|
||||
assert.equal(result.message.startsWith("alass synchronization failed"), true);
|
||||
const alassArgs = fs.readFileSync(alassLogPath, "utf8").trim().split("\n");
|
||||
assert.equal(typeof result.message, 'string');
|
||||
assert.equal(result.message.startsWith('alass synchronization failed'), true);
|
||||
const alassArgs = fs.readFileSync(alassLogPath, 'utf8').trim().split('\n');
|
||||
assert.equal(alassArgs[0], sourcePath);
|
||||
assert.equal(alassArgs[1], primaryPath);
|
||||
});
|
||||
|
||||
test("runSubsyncManual resolves string sid values from mpv stream properties", async () => {
|
||||
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "subsync-stream-sid-"));
|
||||
const ffsubsyncPath = path.join(tmpDir, "ffsubsync.sh");
|
||||
const ffsubsyncLogPath = path.join(tmpDir, "ffsubsync-args.log");
|
||||
const ffmpegPath = path.join(tmpDir, "ffmpeg.sh");
|
||||
const alassPath = path.join(tmpDir, "alass.sh");
|
||||
const videoPath = path.join(tmpDir, "video.mkv");
|
||||
const primaryPath = path.join(tmpDir, "primary.srt");
|
||||
test('runSubsyncManual resolves string sid values from mpv stream properties', async () => {
|
||||
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'subsync-stream-sid-'));
|
||||
const ffsubsyncPath = path.join(tmpDir, 'ffsubsync.sh');
|
||||
const ffsubsyncLogPath = path.join(tmpDir, 'ffsubsync-args.log');
|
||||
const ffmpegPath = path.join(tmpDir, 'ffmpeg.sh');
|
||||
const alassPath = path.join(tmpDir, 'alass.sh');
|
||||
const videoPath = path.join(tmpDir, 'video.mkv');
|
||||
const primaryPath = path.join(tmpDir, 'primary.srt');
|
||||
|
||||
fs.writeFileSync(videoPath, "video");
|
||||
fs.writeFileSync(primaryPath, "subtitle");
|
||||
writeExecutableScript(ffmpegPath, "#!/bin/sh\nexit 0\n");
|
||||
writeExecutableScript(alassPath, "#!/bin/sh\nexit 0\n");
|
||||
fs.writeFileSync(videoPath, 'video');
|
||||
fs.writeFileSync(primaryPath, 'subtitle');
|
||||
writeExecutableScript(ffmpegPath, '#!/bin/sh\nexit 0\n');
|
||||
writeExecutableScript(alassPath, '#!/bin/sh\nexit 0\n');
|
||||
writeExecutableScript(
|
||||
ffsubsyncPath,
|
||||
`#!/bin/sh\nmkdir -p "${tmpDir}"\n: > "${ffsubsyncLogPath}"\nfor arg in "$@"; do printf '%s\\n' "$arg" >> "${ffsubsyncLogPath}"; done\nprev=""\nout=""\nfor arg in "$@"; do\n if [ "$prev" = "--reference-stream" ]; then :; fi\n if [ "$prev" = "-o" ]; then out="$arg"; fi\n prev="$arg"\ndone\nif [ -n "$out" ]; then : > "$out"; fi`,
|
||||
@@ -318,17 +305,17 @@ test("runSubsyncManual resolves string sid values from mpv stream properties", a
|
||||
currentAudioStreamIndex: null,
|
||||
send: () => {},
|
||||
requestProperty: async (name: string) => {
|
||||
if (name === "path") return videoPath;
|
||||
if (name === "sid") return "1";
|
||||
if (name === "secondary-sid") return "2";
|
||||
if (name === "track-list") {
|
||||
if (name === 'path') return videoPath;
|
||||
if (name === 'sid') return '1';
|
||||
if (name === 'secondary-sid') return '2';
|
||||
if (name === 'track-list') {
|
||||
return [
|
||||
{
|
||||
id: "1",
|
||||
type: "sub",
|
||||
id: '1',
|
||||
type: 'sub',
|
||||
selected: true,
|
||||
external: true,
|
||||
"external-filename": primaryPath,
|
||||
'external-filename': primaryPath,
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -336,25 +323,22 @@ test("runSubsyncManual resolves string sid values from mpv stream properties", a
|
||||
},
|
||||
}),
|
||||
getResolvedConfig: () => ({
|
||||
defaultMode: "manual",
|
||||
defaultMode: 'manual',
|
||||
alassPath,
|
||||
ffsubsyncPath,
|
||||
ffmpegPath,
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await runSubsyncManual(
|
||||
{ engine: "ffsubsync", sourceTrackId: null },
|
||||
deps,
|
||||
);
|
||||
const result = await runSubsyncManual({ engine: 'ffsubsync', sourceTrackId: null }, deps);
|
||||
|
||||
assert.equal(result.ok, true);
|
||||
assert.equal(result.message, "Subtitle synchronized with ffsubsync");
|
||||
const ffArgs = fs.readFileSync(ffsubsyncLogPath, "utf8").trim().split("\n");
|
||||
const syncOutputIndex = ffArgs.indexOf("-o");
|
||||
assert.equal(result.message, 'Subtitle synchronized with ffsubsync');
|
||||
const ffArgs = fs.readFileSync(ffsubsyncLogPath, 'utf8').trim().split('\n');
|
||||
const syncOutputIndex = ffArgs.indexOf('-o');
|
||||
assert.equal(syncOutputIndex >= 0, true);
|
||||
const outputPath = ffArgs[syncOutputIndex + 1];
|
||||
assert.equal(typeof outputPath, "string");
|
||||
assert.equal(typeof outputPath, 'string');
|
||||
assert.ok(outputPath.length > 0);
|
||||
assert.equal(fs.readFileSync(outputPath, "utf8"), "");
|
||||
assert.equal(fs.readFileSync(outputPath, 'utf8'), '');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user