mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-22 12:11:27 -07:00
Overlay 2.0 (#12)
This commit is contained in:
@@ -13,6 +13,17 @@ function shouldAutoConnectJellyfinRemote(config: {
|
||||
return config.enabled && config.remoteControlEnabled && config.remoteControlAutoConnect;
|
||||
}
|
||||
|
||||
function createDeferred(): {
|
||||
promise: Promise<void>;
|
||||
resolve: () => void;
|
||||
} {
|
||||
let resolve!: () => void;
|
||||
const promise = new Promise<void>((nextResolve) => {
|
||||
resolve = nextResolve;
|
||||
});
|
||||
return { promise, resolve };
|
||||
}
|
||||
|
||||
test('launchBackgroundWarmupTask logs completion timing', async () => {
|
||||
const debugLogs: string[] = [];
|
||||
const launchTask = createLaunchBackgroundWarmupTaskHandler({
|
||||
@@ -41,6 +52,10 @@ test('startBackgroundWarmups no-ops when already started', () => {
|
||||
createMecabTokenizerAndCheck: async () => {},
|
||||
ensureYomitanExtensionLoaded: async () => {},
|
||||
prewarmSubtitleDictionaries: async () => {},
|
||||
shouldWarmupMecab: () => true,
|
||||
shouldWarmupYomitanExtension: () => true,
|
||||
shouldWarmupSubtitleDictionaries: () => true,
|
||||
shouldWarmupJellyfinRemoteSession: () => true,
|
||||
shouldAutoConnectJellyfinRemote: () => false,
|
||||
startJellyfinRemoteSession: async () => {},
|
||||
});
|
||||
@@ -49,7 +64,7 @@ test('startBackgroundWarmups no-ops when already started', () => {
|
||||
assert.equal(launches, 0);
|
||||
});
|
||||
|
||||
test('startBackgroundWarmups does not schedule jellyfin warmup when jellyfin.enabled is false', () => {
|
||||
test('startBackgroundWarmups respects per-integration warmup toggles', () => {
|
||||
const labels: string[] = [];
|
||||
let started = false;
|
||||
const startWarmups = createStartBackgroundWarmupsHandler({
|
||||
@@ -64,9 +79,13 @@ test('startBackgroundWarmups does not schedule jellyfin warmup when jellyfin.ena
|
||||
createMecabTokenizerAndCheck: async () => {},
|
||||
ensureYomitanExtensionLoaded: async () => {},
|
||||
prewarmSubtitleDictionaries: async () => {},
|
||||
shouldWarmupMecab: () => false,
|
||||
shouldWarmupYomitanExtension: () => true,
|
||||
shouldWarmupSubtitleDictionaries: () => false,
|
||||
shouldWarmupJellyfinRemoteSession: () => false,
|
||||
shouldAutoConnectJellyfinRemote: () =>
|
||||
shouldAutoConnectJellyfinRemote({
|
||||
enabled: false,
|
||||
enabled: true,
|
||||
remoteControlEnabled: true,
|
||||
remoteControlAutoConnect: true,
|
||||
}),
|
||||
@@ -75,7 +94,7 @@ test('startBackgroundWarmups does not schedule jellyfin warmup when jellyfin.ena
|
||||
|
||||
startWarmups();
|
||||
assert.equal(started, true);
|
||||
assert.deepEqual(labels, ['mecab', 'yomitan-extension', 'subtitle-dictionaries']);
|
||||
assert.deepEqual(labels, ['subtitle-tokenization']);
|
||||
});
|
||||
|
||||
test('startBackgroundWarmups schedules jellyfin warmup when all jellyfin flags are enabled', () => {
|
||||
@@ -93,6 +112,10 @@ test('startBackgroundWarmups schedules jellyfin warmup when all jellyfin flags a
|
||||
createMecabTokenizerAndCheck: async () => {},
|
||||
ensureYomitanExtensionLoaded: async () => {},
|
||||
prewarmSubtitleDictionaries: async () => {},
|
||||
shouldWarmupMecab: () => true,
|
||||
shouldWarmupYomitanExtension: () => true,
|
||||
shouldWarmupSubtitleDictionaries: () => true,
|
||||
shouldWarmupJellyfinRemoteSession: () => true,
|
||||
shouldAutoConnectJellyfinRemote: () =>
|
||||
shouldAutoConnectJellyfinRemote({
|
||||
enabled: true,
|
||||
@@ -104,10 +127,138 @@ test('startBackgroundWarmups schedules jellyfin warmup when all jellyfin flags a
|
||||
|
||||
startWarmups();
|
||||
assert.equal(started, true);
|
||||
assert.deepEqual(labels, [
|
||||
'mecab',
|
||||
'yomitan-extension',
|
||||
'subtitle-dictionaries',
|
||||
'jellyfin-remote-session',
|
||||
]);
|
||||
assert.deepEqual(labels, ['subtitle-tokenization', 'jellyfin-remote-session']);
|
||||
});
|
||||
|
||||
test('startBackgroundWarmups skips jellyfin warmup when warmup is deferred', () => {
|
||||
const labels: string[] = [];
|
||||
let started = false;
|
||||
const startWarmups = createStartBackgroundWarmupsHandler({
|
||||
getStarted: () => started,
|
||||
setStarted: (value) => {
|
||||
started = value;
|
||||
},
|
||||
isTexthookerOnlyMode: () => false,
|
||||
launchTask: (label) => {
|
||||
labels.push(label);
|
||||
},
|
||||
createMecabTokenizerAndCheck: async () => {},
|
||||
ensureYomitanExtensionLoaded: async () => {},
|
||||
prewarmSubtitleDictionaries: async () => {},
|
||||
shouldWarmupMecab: () => false,
|
||||
shouldWarmupYomitanExtension: () => true,
|
||||
shouldWarmupSubtitleDictionaries: () => false,
|
||||
shouldWarmupJellyfinRemoteSession: () => false,
|
||||
shouldAutoConnectJellyfinRemote: () =>
|
||||
shouldAutoConnectJellyfinRemote({
|
||||
enabled: true,
|
||||
remoteControlEnabled: true,
|
||||
remoteControlAutoConnect: true,
|
||||
}),
|
||||
startJellyfinRemoteSession: async () => {},
|
||||
});
|
||||
|
||||
startWarmups();
|
||||
assert.equal(started, true);
|
||||
assert.deepEqual(labels, ['subtitle-tokenization']);
|
||||
});
|
||||
|
||||
test('startBackgroundWarmups logs per-stage progress for enabled tokenization warmups', async () => {
|
||||
const debugLogs: string[] = [];
|
||||
const labels: string[] = [];
|
||||
let started = false;
|
||||
const startWarmups = createStartBackgroundWarmupsHandler({
|
||||
getStarted: () => started,
|
||||
setStarted: (value) => {
|
||||
started = value;
|
||||
},
|
||||
isTexthookerOnlyMode: () => false,
|
||||
launchTask: (label, task) => {
|
||||
labels.push(label);
|
||||
void task();
|
||||
},
|
||||
createMecabTokenizerAndCheck: async () => {},
|
||||
ensureYomitanExtensionLoaded: async () => {},
|
||||
prewarmSubtitleDictionaries: async () => {},
|
||||
shouldWarmupMecab: () => true,
|
||||
shouldWarmupYomitanExtension: () => true,
|
||||
shouldWarmupSubtitleDictionaries: () => true,
|
||||
shouldWarmupJellyfinRemoteSession: () => true,
|
||||
shouldAutoConnectJellyfinRemote: () => true,
|
||||
startJellyfinRemoteSession: async () => {},
|
||||
logDebug: (message) => {
|
||||
debugLogs.push(message);
|
||||
},
|
||||
});
|
||||
|
||||
startWarmups();
|
||||
await Promise.resolve();
|
||||
await Promise.resolve();
|
||||
|
||||
assert.deepEqual(labels, ['subtitle-tokenization', 'jellyfin-remote-session']);
|
||||
assert.ok(debugLogs.includes('[startup-warmup] stage start: yomitan-extension'));
|
||||
assert.ok(debugLogs.includes('[startup-warmup] stage ready: yomitan-extension'));
|
||||
assert.ok(debugLogs.includes('[startup-warmup] stage start: mecab'));
|
||||
assert.ok(debugLogs.includes('[startup-warmup] stage ready: mecab'));
|
||||
assert.ok(debugLogs.includes('[startup-warmup] stage start: subtitle-dictionaries'));
|
||||
assert.ok(debugLogs.includes('[startup-warmup] stage ready: subtitle-dictionaries'));
|
||||
assert.ok(debugLogs.includes('[startup-warmup] stage start: jellyfin-remote-session'));
|
||||
assert.ok(debugLogs.includes('[startup-warmup] stage ready: jellyfin-remote-session'));
|
||||
});
|
||||
|
||||
test('startBackgroundWarmups starts mecab and dictionary warmups without waiting for yomitan warmup', async () => {
|
||||
const startedStages: string[] = [];
|
||||
let started = false;
|
||||
let subtitleTokenizationTask: Promise<void> | null = null;
|
||||
const yomitanDeferred = createDeferred();
|
||||
const mecabDeferred = createDeferred();
|
||||
const subtitleDictionariesDeferred = createDeferred();
|
||||
|
||||
const startWarmups = createStartBackgroundWarmupsHandler({
|
||||
getStarted: () => started,
|
||||
setStarted: (value) => {
|
||||
started = value;
|
||||
},
|
||||
isTexthookerOnlyMode: () => false,
|
||||
launchTask: (label, task) => {
|
||||
if (label === 'subtitle-tokenization') {
|
||||
subtitleTokenizationTask = task();
|
||||
}
|
||||
},
|
||||
createMecabTokenizerAndCheck: async () => {
|
||||
startedStages.push('mecab');
|
||||
await mecabDeferred.promise;
|
||||
},
|
||||
ensureYomitanExtensionLoaded: async () => {
|
||||
startedStages.push('yomitan-extension');
|
||||
await yomitanDeferred.promise;
|
||||
},
|
||||
prewarmSubtitleDictionaries: async () => {
|
||||
startedStages.push('subtitle-dictionaries');
|
||||
await subtitleDictionariesDeferred.promise;
|
||||
},
|
||||
shouldWarmupMecab: () => true,
|
||||
shouldWarmupYomitanExtension: () => true,
|
||||
shouldWarmupSubtitleDictionaries: () => true,
|
||||
shouldWarmupJellyfinRemoteSession: () => false,
|
||||
shouldAutoConnectJellyfinRemote: () => false,
|
||||
startJellyfinRemoteSession: async () => {},
|
||||
});
|
||||
|
||||
startWarmups();
|
||||
await Promise.resolve();
|
||||
await Promise.resolve();
|
||||
|
||||
assert.ok(subtitleTokenizationTask);
|
||||
assert.equal(startedStages.includes('yomitan-extension'), true);
|
||||
assert.equal(startedStages.includes('mecab'), true);
|
||||
assert.equal(startedStages.includes('subtitle-dictionaries'), true);
|
||||
|
||||
yomitanDeferred.resolve();
|
||||
mecabDeferred.resolve();
|
||||
subtitleDictionariesDeferred.resolve();
|
||||
if (!subtitleTokenizationTask) {
|
||||
throw new Error('Expected subtitle tokenization warmup task');
|
||||
}
|
||||
await subtitleTokenizationTask;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user