mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-30 06:12:06 -07:00
test: extract mpv composer test fixture factory to reduce duplication
This commit is contained in:
@@ -30,37 +30,13 @@ function createDeferred(): { promise: Promise<void>; resolve: () => void } {
|
|||||||
return { promise, resolve };
|
return { promise, resolve };
|
||||||
}
|
}
|
||||||
|
|
||||||
test('composeMpvRuntimeHandlers returns callable handlers and forwards to injected deps', async () => {
|
class DefaultFakeMpvClient {
|
||||||
const calls: string[] = [];
|
connect(): void {}
|
||||||
let started = false;
|
on(): void {}
|
||||||
let metrics = BASE_METRICS;
|
}
|
||||||
let mecabTokenizer: { id: string } | null = null;
|
|
||||||
|
|
||||||
class FakeMpvClient {
|
function createDefaultMpvFixture() {
|
||||||
connected = false;
|
return {
|
||||||
|
|
||||||
constructor(
|
|
||||||
public socketPath: string,
|
|
||||||
public options: unknown,
|
|
||||||
) {
|
|
||||||
const autoStartOverlay = (options as { autoStartOverlay: boolean }).autoStartOverlay;
|
|
||||||
calls.push(`create-client:${socketPath}`);
|
|
||||||
calls.push(`auto-start:${String(autoStartOverlay)}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
on(): void {}
|
|
||||||
|
|
||||||
connect(): void {
|
|
||||||
this.connected = true;
|
|
||||||
calls.push('client-connect');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const composed = composeMpvRuntimeHandlers<
|
|
||||||
FakeMpvClient,
|
|
||||||
{ isKnownWord: (text: string) => boolean },
|
|
||||||
{ text: string }
|
|
||||||
>({
|
|
||||||
bindMpvMainEventHandlersMainDeps: {
|
bindMpvMainEventHandlersMainDeps: {
|
||||||
appState: {
|
appState: {
|
||||||
initialArgs: null,
|
initialArgs: null,
|
||||||
@@ -97,15 +73,119 @@ test('composeMpvRuntimeHandlers returns callable handlers and forwards to inject
|
|||||||
updateSubtitleRenderMetrics: () => {},
|
updateSubtitleRenderMetrics: () => {},
|
||||||
},
|
},
|
||||||
mpvClientRuntimeServiceFactoryMainDeps: {
|
mpvClientRuntimeServiceFactoryMainDeps: {
|
||||||
createClient: FakeMpvClient,
|
createClient: DefaultFakeMpvClient,
|
||||||
getSocketPath: () => '/tmp/mpv.sock',
|
getSocketPath: () => '/tmp/mpv.sock',
|
||||||
getResolvedConfig: () => ({ auto_start_overlay: false }),
|
getResolvedConfig: () => ({ auto_start_overlay: false }),
|
||||||
isAutoStartOverlayEnabled: () => true,
|
isAutoStartOverlayEnabled: () => false,
|
||||||
setOverlayVisible: () => {},
|
setOverlayVisible: () => {},
|
||||||
isVisibleOverlayVisible: () => false,
|
isVisibleOverlayVisible: () => false,
|
||||||
getReconnectTimer: () => null,
|
getReconnectTimer: () => null,
|
||||||
setReconnectTimer: () => {},
|
setReconnectTimer: () => {},
|
||||||
},
|
},
|
||||||
|
updateMpvSubtitleRenderMetricsMainDeps: {
|
||||||
|
getCurrentMetrics: () => BASE_METRICS,
|
||||||
|
setCurrentMetrics: () => {},
|
||||||
|
applyPatch: (current: MpvSubtitleRenderMetrics, patch: Partial<MpvSubtitleRenderMetrics>) => ({
|
||||||
|
next: { ...current, ...patch },
|
||||||
|
changed: true,
|
||||||
|
}),
|
||||||
|
broadcastMetrics: () => {},
|
||||||
|
},
|
||||||
|
tokenizer: {
|
||||||
|
buildTokenizerDepsMainDeps: {
|
||||||
|
getYomitanExt: () => null,
|
||||||
|
getYomitanParserWindow: () => null,
|
||||||
|
setYomitanParserWindow: () => {},
|
||||||
|
getYomitanParserReadyPromise: () => null,
|
||||||
|
setYomitanParserReadyPromise: () => {},
|
||||||
|
getYomitanParserInitPromise: () => null,
|
||||||
|
setYomitanParserInitPromise: () => {},
|
||||||
|
isKnownWord: () => false,
|
||||||
|
recordLookup: () => {},
|
||||||
|
getKnownWordMatchMode: () => 'headword' as const,
|
||||||
|
getNPlusOneEnabled: () => false,
|
||||||
|
getMinSentenceWordsForNPlusOne: () => 3,
|
||||||
|
getJlptLevel: () => null,
|
||||||
|
getJlptEnabled: () => false,
|
||||||
|
getFrequencyDictionaryEnabled: () => false,
|
||||||
|
getFrequencyDictionaryMatchMode: () => 'headword' as const,
|
||||||
|
getFrequencyRank: () => null,
|
||||||
|
getYomitanGroupDebugEnabled: () => false,
|
||||||
|
getMecabTokenizer: () => null,
|
||||||
|
},
|
||||||
|
createTokenizerRuntimeDeps: () => ({ isKnownWord: () => false }),
|
||||||
|
tokenizeSubtitle: async (text: string) => ({ text }),
|
||||||
|
createMecabTokenizerAndCheckMainDeps: {
|
||||||
|
getMecabTokenizer: () => null,
|
||||||
|
setMecabTokenizer: () => {},
|
||||||
|
createMecabTokenizer: () => ({ id: 'mecab' }),
|
||||||
|
checkAvailability: async () => {},
|
||||||
|
},
|
||||||
|
prewarmSubtitleDictionariesMainDeps: {
|
||||||
|
ensureJlptDictionaryLookup: async () => {},
|
||||||
|
ensureFrequencyDictionaryLookup: async () => {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
warmups: {
|
||||||
|
launchBackgroundWarmupTaskMainDeps: {
|
||||||
|
now: () => 0,
|
||||||
|
logDebug: () => {},
|
||||||
|
logWarn: () => {},
|
||||||
|
},
|
||||||
|
startBackgroundWarmupsMainDeps: {
|
||||||
|
getStarted: () => false,
|
||||||
|
setStarted: () => {},
|
||||||
|
isTexthookerOnlyMode: () => false,
|
||||||
|
ensureYomitanExtensionLoaded: async () => {},
|
||||||
|
shouldWarmupMecab: () => false,
|
||||||
|
shouldWarmupYomitanExtension: () => false,
|
||||||
|
shouldWarmupSubtitleDictionaries: () => false,
|
||||||
|
shouldWarmupJellyfinRemoteSession: () => false,
|
||||||
|
shouldAutoConnectJellyfinRemote: () => false,
|
||||||
|
startJellyfinRemoteSession: async () => {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
test('composeMpvRuntimeHandlers returns callable handlers and forwards to injected deps', async () => {
|
||||||
|
const calls: string[] = [];
|
||||||
|
let started = false;
|
||||||
|
let metrics = BASE_METRICS;
|
||||||
|
let mecabTokenizer: { id: string } | null = null;
|
||||||
|
|
||||||
|
class FakeMpvClient {
|
||||||
|
connected = false;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public socketPath: string,
|
||||||
|
public options: unknown,
|
||||||
|
) {
|
||||||
|
const autoStartOverlay = (options as { autoStartOverlay: boolean }).autoStartOverlay;
|
||||||
|
calls.push(`create-client:${socketPath}`);
|
||||||
|
calls.push(`auto-start:${String(autoStartOverlay)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
on(): void {}
|
||||||
|
|
||||||
|
connect(): void {
|
||||||
|
this.connected = true;
|
||||||
|
calls.push('client-connect');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fixture = createDefaultMpvFixture();
|
||||||
|
const composed = composeMpvRuntimeHandlers<
|
||||||
|
FakeMpvClient,
|
||||||
|
{ isKnownWord: (text: string) => boolean },
|
||||||
|
{ text: string }
|
||||||
|
>({
|
||||||
|
...fixture,
|
||||||
|
mpvClientRuntimeServiceFactoryMainDeps: {
|
||||||
|
...fixture.mpvClientRuntimeServiceFactoryMainDeps,
|
||||||
|
createClient: FakeMpvClient,
|
||||||
|
isAutoStartOverlayEnabled: () => true,
|
||||||
|
},
|
||||||
updateMpvSubtitleRenderMetricsMainDeps: {
|
updateMpvSubtitleRenderMetricsMainDeps: {
|
||||||
getCurrentMetrics: () => metrics,
|
getCurrentMetrics: () => metrics,
|
||||||
setCurrentMetrics: (next) => {
|
setCurrentMetrics: (next) => {
|
||||||
@@ -121,25 +201,12 @@ test('composeMpvRuntimeHandlers returns callable handlers and forwards to inject
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
tokenizer: {
|
tokenizer: {
|
||||||
|
...fixture.tokenizer,
|
||||||
buildTokenizerDepsMainDeps: {
|
buildTokenizerDepsMainDeps: {
|
||||||
getYomitanExt: () => null,
|
...fixture.tokenizer.buildTokenizerDepsMainDeps,
|
||||||
getYomitanParserWindow: () => null,
|
|
||||||
setYomitanParserWindow: () => {},
|
|
||||||
getYomitanParserReadyPromise: () => null,
|
|
||||||
setYomitanParserReadyPromise: () => {},
|
|
||||||
getYomitanParserInitPromise: () => null,
|
|
||||||
setYomitanParserInitPromise: () => {},
|
|
||||||
isKnownWord: (text) => text === 'known',
|
isKnownWord: (text) => text === 'known',
|
||||||
recordLookup: () => {},
|
|
||||||
getKnownWordMatchMode: () => 'headword',
|
|
||||||
getMinSentenceWordsForNPlusOne: () => 3,
|
|
||||||
getJlptLevel: () => null,
|
|
||||||
getJlptEnabled: () => true,
|
getJlptEnabled: () => true,
|
||||||
getFrequencyDictionaryEnabled: () => true,
|
getFrequencyDictionaryEnabled: () => true,
|
||||||
getFrequencyDictionaryMatchMode: () => 'headword',
|
|
||||||
getFrequencyRank: () => null,
|
|
||||||
getYomitanGroupDebugEnabled: () => false,
|
|
||||||
getMecabTokenizer: () => null,
|
|
||||||
},
|
},
|
||||||
createTokenizerRuntimeDeps: (deps) => {
|
createTokenizerRuntimeDeps: (deps) => {
|
||||||
calls.push('create-tokenizer-runtime-deps');
|
calls.push('create-tokenizer-runtime-deps');
|
||||||
@@ -184,12 +251,12 @@ test('composeMpvRuntimeHandlers returns callable handlers and forwards to inject
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
startBackgroundWarmupsMainDeps: {
|
startBackgroundWarmupsMainDeps: {
|
||||||
|
...fixture.warmups.startBackgroundWarmupsMainDeps,
|
||||||
getStarted: () => started,
|
getStarted: () => started,
|
||||||
setStarted: (next) => {
|
setStarted: (next) => {
|
||||||
started = next;
|
started = next;
|
||||||
calls.push(`set-started:${String(next)}`);
|
calls.push(`set-started:${String(next)}`);
|
||||||
},
|
},
|
||||||
isTexthookerOnlyMode: () => false,
|
|
||||||
ensureYomitanExtensionLoaded: async () => {
|
ensureYomitanExtensionLoaded: async () => {
|
||||||
calls.push('warmup-yomitan');
|
calls.push('warmup-yomitan');
|
||||||
},
|
},
|
||||||
@@ -197,7 +264,6 @@ test('composeMpvRuntimeHandlers returns callable handlers and forwards to inject
|
|||||||
shouldWarmupYomitanExtension: () => true,
|
shouldWarmupYomitanExtension: () => true,
|
||||||
shouldWarmupSubtitleDictionaries: () => true,
|
shouldWarmupSubtitleDictionaries: () => true,
|
||||||
shouldWarmupJellyfinRemoteSession: () => true,
|
shouldWarmupJellyfinRemoteSession: () => true,
|
||||||
shouldAutoConnectJellyfinRemote: () => false,
|
|
||||||
startJellyfinRemoteSession: async () => {
|
startJellyfinRemoteSession: async () => {
|
||||||
calls.push('warmup-jellyfin');
|
calls.push('warmup-jellyfin');
|
||||||
},
|
},
|
||||||
@@ -264,86 +330,20 @@ test('composeMpvRuntimeHandlers skips MeCab warmup when all POS-dependent annota
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fixture = createDefaultMpvFixture();
|
||||||
const composed = composeMpvRuntimeHandlers<
|
const composed = composeMpvRuntimeHandlers<
|
||||||
FakeMpvClient,
|
FakeMpvClient,
|
||||||
{ isKnownWord: (text: string) => boolean },
|
{ isKnownWord: (text: string) => boolean },
|
||||||
{ text: string }
|
{ text: string }
|
||||||
>({
|
>({
|
||||||
bindMpvMainEventHandlersMainDeps: {
|
...fixture,
|
||||||
appState: {
|
|
||||||
initialArgs: null,
|
|
||||||
overlayRuntimeInitialized: true,
|
|
||||||
mpvClient: null,
|
|
||||||
immersionTracker: null,
|
|
||||||
subtitleTimingTracker: null,
|
|
||||||
currentSubText: '',
|
|
||||||
currentSubAssText: '',
|
|
||||||
playbackPaused: null,
|
|
||||||
previousSecondarySubVisibility: null,
|
|
||||||
},
|
|
||||||
getQuitOnDisconnectArmed: () => false,
|
|
||||||
scheduleQuitCheck: () => {},
|
|
||||||
quitApp: () => {},
|
|
||||||
reportJellyfinRemoteStopped: () => {},
|
|
||||||
syncOverlayMpvSubtitleSuppression: () => {},
|
|
||||||
maybeRunAnilistPostWatchUpdate: async () => {},
|
|
||||||
logSubtitleTimingError: () => {},
|
|
||||||
broadcastToOverlayWindows: () => {},
|
|
||||||
onSubtitleChange: () => {},
|
|
||||||
refreshDiscordPresence: () => {},
|
|
||||||
ensureImmersionTrackerInitialized: () => {},
|
|
||||||
updateCurrentMediaPath: () => {},
|
|
||||||
restoreMpvSubVisibility: () => {},
|
|
||||||
getCurrentAnilistMediaKey: () => null,
|
|
||||||
resetAnilistMediaTracking: () => {},
|
|
||||||
maybeProbeAnilistDuration: () => {},
|
|
||||||
ensureAnilistMediaGuess: () => {},
|
|
||||||
syncImmersionMediaState: () => {},
|
|
||||||
updateCurrentMediaTitle: () => {},
|
|
||||||
resetAnilistMediaGuessState: () => {},
|
|
||||||
reportJellyfinRemoteProgress: () => {},
|
|
||||||
updateSubtitleRenderMetrics: () => {},
|
|
||||||
},
|
|
||||||
mpvClientRuntimeServiceFactoryMainDeps: {
|
mpvClientRuntimeServiceFactoryMainDeps: {
|
||||||
|
...fixture.mpvClientRuntimeServiceFactoryMainDeps,
|
||||||
createClient: FakeMpvClient,
|
createClient: FakeMpvClient,
|
||||||
getSocketPath: () => '/tmp/mpv.sock',
|
|
||||||
getResolvedConfig: () => ({ auto_start_overlay: false }),
|
|
||||||
isAutoStartOverlayEnabled: () => true,
|
isAutoStartOverlayEnabled: () => true,
|
||||||
setOverlayVisible: () => {},
|
|
||||||
isVisibleOverlayVisible: () => false,
|
|
||||||
getReconnectTimer: () => null,
|
|
||||||
setReconnectTimer: () => {},
|
|
||||||
},
|
|
||||||
updateMpvSubtitleRenderMetricsMainDeps: {
|
|
||||||
getCurrentMetrics: () => BASE_METRICS,
|
|
||||||
setCurrentMetrics: () => {},
|
|
||||||
applyPatch: (current, patch) => ({ next: { ...current, ...patch }, changed: true }),
|
|
||||||
broadcastMetrics: () => {},
|
|
||||||
},
|
},
|
||||||
tokenizer: {
|
tokenizer: {
|
||||||
buildTokenizerDepsMainDeps: {
|
...fixture.tokenizer,
|
||||||
getYomitanExt: () => null,
|
|
||||||
getYomitanParserWindow: () => null,
|
|
||||||
setYomitanParserWindow: () => {},
|
|
||||||
getYomitanParserReadyPromise: () => null,
|
|
||||||
setYomitanParserReadyPromise: () => {},
|
|
||||||
getYomitanParserInitPromise: () => null,
|
|
||||||
setYomitanParserInitPromise: () => {},
|
|
||||||
isKnownWord: () => false,
|
|
||||||
recordLookup: () => {},
|
|
||||||
getKnownWordMatchMode: () => 'headword',
|
|
||||||
getNPlusOneEnabled: () => false,
|
|
||||||
getMinSentenceWordsForNPlusOne: () => 3,
|
|
||||||
getJlptLevel: () => null,
|
|
||||||
getJlptEnabled: () => false,
|
|
||||||
getFrequencyDictionaryEnabled: () => false,
|
|
||||||
getFrequencyDictionaryMatchMode: () => 'headword',
|
|
||||||
getFrequencyRank: () => null,
|
|
||||||
getYomitanGroupDebugEnabled: () => false,
|
|
||||||
getMecabTokenizer: () => null,
|
|
||||||
},
|
|
||||||
createTokenizerRuntimeDeps: () => ({ isKnownWord: () => false }),
|
|
||||||
tokenizeSubtitle: async (text) => ({ text }),
|
|
||||||
createMecabTokenizerAndCheckMainDeps: {
|
createMecabTokenizerAndCheckMainDeps: {
|
||||||
getMecabTokenizer: () => mecabTokenizer,
|
getMecabTokenizer: () => mecabTokenizer,
|
||||||
setMecabTokenizer: (next) => {
|
setMecabTokenizer: (next) => {
|
||||||
@@ -358,29 +358,6 @@ test('composeMpvRuntimeHandlers skips MeCab warmup when all POS-dependent annota
|
|||||||
calls.push('check-mecab');
|
calls.push('check-mecab');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
prewarmSubtitleDictionariesMainDeps: {
|
|
||||||
ensureJlptDictionaryLookup: async () => {},
|
|
||||||
ensureFrequencyDictionaryLookup: async () => {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
warmups: {
|
|
||||||
launchBackgroundWarmupTaskMainDeps: {
|
|
||||||
now: () => 0,
|
|
||||||
logDebug: () => {},
|
|
||||||
logWarn: () => {},
|
|
||||||
},
|
|
||||||
startBackgroundWarmupsMainDeps: {
|
|
||||||
getStarted: () => false,
|
|
||||||
setStarted: () => {},
|
|
||||||
isTexthookerOnlyMode: () => false,
|
|
||||||
ensureYomitanExtensionLoaded: async () => {},
|
|
||||||
shouldWarmupMecab: () => false,
|
|
||||||
shouldWarmupYomitanExtension: () => false,
|
|
||||||
shouldWarmupSubtitleDictionaries: () => false,
|
|
||||||
shouldWarmupJellyfinRemoteSession: () => false,
|
|
||||||
shouldAutoConnectJellyfinRemote: () => false,
|
|
||||||
startJellyfinRemoteSession: async () => {},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -395,98 +372,19 @@ test('composeMpvRuntimeHandlers runs tokenization warmup once across sequential
|
|||||||
let prewarmFrequencyCalls = 0;
|
let prewarmFrequencyCalls = 0;
|
||||||
const tokenizeCalls: string[] = [];
|
const tokenizeCalls: string[] = [];
|
||||||
|
|
||||||
|
const fixture = createDefaultMpvFixture();
|
||||||
const composed = composeMpvRuntimeHandlers<
|
const composed = composeMpvRuntimeHandlers<
|
||||||
{ connect: () => void; on: () => void },
|
{ connect: () => void; on: () => void },
|
||||||
{ isKnownWord: () => boolean },
|
{ isKnownWord: () => boolean },
|
||||||
{ text: string }
|
{ text: string }
|
||||||
>({
|
>({
|
||||||
bindMpvMainEventHandlersMainDeps: {
|
...fixture,
|
||||||
appState: {
|
|
||||||
initialArgs: null,
|
|
||||||
overlayRuntimeInitialized: true,
|
|
||||||
mpvClient: null,
|
|
||||||
immersionTracker: null,
|
|
||||||
subtitleTimingTracker: null,
|
|
||||||
currentSubText: '',
|
|
||||||
currentSubAssText: '',
|
|
||||||
playbackPaused: null,
|
|
||||||
previousSecondarySubVisibility: null,
|
|
||||||
},
|
|
||||||
getQuitOnDisconnectArmed: () => false,
|
|
||||||
scheduleQuitCheck: () => {},
|
|
||||||
quitApp: () => {},
|
|
||||||
reportJellyfinRemoteStopped: () => {},
|
|
||||||
syncOverlayMpvSubtitleSuppression: () => {},
|
|
||||||
maybeRunAnilistPostWatchUpdate: async () => {},
|
|
||||||
logSubtitleTimingError: () => {},
|
|
||||||
broadcastToOverlayWindows: () => {},
|
|
||||||
onSubtitleChange: () => {},
|
|
||||||
refreshDiscordPresence: () => {},
|
|
||||||
ensureImmersionTrackerInitialized: () => {},
|
|
||||||
updateCurrentMediaPath: () => {},
|
|
||||||
restoreMpvSubVisibility: () => {},
|
|
||||||
getCurrentAnilistMediaKey: () => null,
|
|
||||||
resetAnilistMediaTracking: () => {},
|
|
||||||
maybeProbeAnilistDuration: () => {},
|
|
||||||
ensureAnilistMediaGuess: () => {},
|
|
||||||
syncImmersionMediaState: () => {},
|
|
||||||
updateCurrentMediaTitle: () => {},
|
|
||||||
resetAnilistMediaGuessState: () => {},
|
|
||||||
reportJellyfinRemoteProgress: () => {},
|
|
||||||
updateSubtitleRenderMetrics: () => {},
|
|
||||||
},
|
|
||||||
mpvClientRuntimeServiceFactoryMainDeps: {
|
|
||||||
createClient: class {
|
|
||||||
connect(): void {}
|
|
||||||
on(): void {}
|
|
||||||
},
|
|
||||||
getSocketPath: () => '/tmp/mpv.sock',
|
|
||||||
getResolvedConfig: () => ({ auto_start_overlay: false }),
|
|
||||||
isAutoStartOverlayEnabled: () => false,
|
|
||||||
setOverlayVisible: () => {},
|
|
||||||
isVisibleOverlayVisible: () => false,
|
|
||||||
getReconnectTimer: () => null,
|
|
||||||
setReconnectTimer: () => {},
|
|
||||||
},
|
|
||||||
updateMpvSubtitleRenderMetricsMainDeps: {
|
|
||||||
getCurrentMetrics: () => BASE_METRICS,
|
|
||||||
setCurrentMetrics: () => {},
|
|
||||||
applyPatch: (current, patch) => ({ next: { ...current, ...patch }, changed: true }),
|
|
||||||
broadcastMetrics: () => {},
|
|
||||||
},
|
|
||||||
tokenizer: {
|
tokenizer: {
|
||||||
buildTokenizerDepsMainDeps: {
|
...fixture.tokenizer,
|
||||||
getYomitanExt: () => null,
|
|
||||||
getYomitanParserWindow: () => null,
|
|
||||||
setYomitanParserWindow: () => {},
|
|
||||||
getYomitanParserReadyPromise: () => null,
|
|
||||||
setYomitanParserReadyPromise: () => {},
|
|
||||||
getYomitanParserInitPromise: () => null,
|
|
||||||
setYomitanParserInitPromise: () => {},
|
|
||||||
isKnownWord: () => false,
|
|
||||||
recordLookup: () => {},
|
|
||||||
getKnownWordMatchMode: () => 'headword',
|
|
||||||
getNPlusOneEnabled: () => false,
|
|
||||||
getMinSentenceWordsForNPlusOne: () => 3,
|
|
||||||
getJlptLevel: () => null,
|
|
||||||
getJlptEnabled: () => false,
|
|
||||||
getFrequencyDictionaryEnabled: () => false,
|
|
||||||
getFrequencyDictionaryMatchMode: () => 'headword',
|
|
||||||
getFrequencyRank: () => null,
|
|
||||||
getYomitanGroupDebugEnabled: () => false,
|
|
||||||
getMecabTokenizer: () => null,
|
|
||||||
},
|
|
||||||
createTokenizerRuntimeDeps: () => ({ isKnownWord: () => false }),
|
|
||||||
tokenizeSubtitle: async (text) => {
|
tokenizeSubtitle: async (text) => {
|
||||||
tokenizeCalls.push(text);
|
tokenizeCalls.push(text);
|
||||||
return { text };
|
return { text };
|
||||||
},
|
},
|
||||||
createMecabTokenizerAndCheckMainDeps: {
|
|
||||||
getMecabTokenizer: () => null,
|
|
||||||
setMecabTokenizer: () => {},
|
|
||||||
createMecabTokenizer: () => ({ id: 'mecab' }),
|
|
||||||
checkAvailability: async () => {},
|
|
||||||
},
|
|
||||||
prewarmSubtitleDictionariesMainDeps: {
|
prewarmSubtitleDictionariesMainDeps: {
|
||||||
ensureJlptDictionaryLookup: async () => {
|
ensureJlptDictionaryLookup: async () => {
|
||||||
prewarmJlptCalls += 1;
|
prewarmJlptCalls += 1;
|
||||||
@@ -497,24 +395,12 @@ test('composeMpvRuntimeHandlers runs tokenization warmup once across sequential
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
warmups: {
|
warmups: {
|
||||||
launchBackgroundWarmupTaskMainDeps: {
|
...fixture.warmups,
|
||||||
now: () => 0,
|
|
||||||
logDebug: () => {},
|
|
||||||
logWarn: () => {},
|
|
||||||
},
|
|
||||||
startBackgroundWarmupsMainDeps: {
|
startBackgroundWarmupsMainDeps: {
|
||||||
getStarted: () => false,
|
...fixture.warmups.startBackgroundWarmupsMainDeps,
|
||||||
setStarted: () => {},
|
|
||||||
isTexthookerOnlyMode: () => false,
|
|
||||||
ensureYomitanExtensionLoaded: async () => {
|
ensureYomitanExtensionLoaded: async () => {
|
||||||
yomitanWarmupCalls += 1;
|
yomitanWarmupCalls += 1;
|
||||||
},
|
},
|
||||||
shouldWarmupMecab: () => false,
|
|
||||||
shouldWarmupYomitanExtension: () => false,
|
|
||||||
shouldWarmupSubtitleDictionaries: () => false,
|
|
||||||
shouldWarmupJellyfinRemoteSession: () => false,
|
|
||||||
shouldAutoConnectJellyfinRemote: () => false,
|
|
||||||
startJellyfinRemoteSession: async () => {},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -534,93 +420,23 @@ test('composeMpvRuntimeHandlers does not block first tokenization on dictionary
|
|||||||
const mecabDeferred = createDeferred();
|
const mecabDeferred = createDeferred();
|
||||||
let tokenizeResolved = false;
|
let tokenizeResolved = false;
|
||||||
|
|
||||||
|
const fixture = createDefaultMpvFixture();
|
||||||
const composed = composeMpvRuntimeHandlers<
|
const composed = composeMpvRuntimeHandlers<
|
||||||
{ connect: () => void; on: () => void },
|
{ connect: () => void; on: () => void },
|
||||||
{ isKnownWord: () => boolean },
|
{ isKnownWord: () => boolean },
|
||||||
{ text: string }
|
{ text: string }
|
||||||
>({
|
>({
|
||||||
bindMpvMainEventHandlersMainDeps: {
|
...fixture,
|
||||||
appState: {
|
|
||||||
initialArgs: null,
|
|
||||||
overlayRuntimeInitialized: true,
|
|
||||||
mpvClient: null,
|
|
||||||
immersionTracker: null,
|
|
||||||
subtitleTimingTracker: null,
|
|
||||||
currentSubText: '',
|
|
||||||
currentSubAssText: '',
|
|
||||||
playbackPaused: null,
|
|
||||||
previousSecondarySubVisibility: null,
|
|
||||||
},
|
|
||||||
getQuitOnDisconnectArmed: () => false,
|
|
||||||
scheduleQuitCheck: () => {},
|
|
||||||
quitApp: () => {},
|
|
||||||
reportJellyfinRemoteStopped: () => {},
|
|
||||||
syncOverlayMpvSubtitleSuppression: () => {},
|
|
||||||
maybeRunAnilistPostWatchUpdate: async () => {},
|
|
||||||
logSubtitleTimingError: () => {},
|
|
||||||
broadcastToOverlayWindows: () => {},
|
|
||||||
onSubtitleChange: () => {},
|
|
||||||
refreshDiscordPresence: () => {},
|
|
||||||
ensureImmersionTrackerInitialized: () => {},
|
|
||||||
updateCurrentMediaPath: () => {},
|
|
||||||
restoreMpvSubVisibility: () => {},
|
|
||||||
getCurrentAnilistMediaKey: () => null,
|
|
||||||
resetAnilistMediaTracking: () => {},
|
|
||||||
maybeProbeAnilistDuration: () => {},
|
|
||||||
ensureAnilistMediaGuess: () => {},
|
|
||||||
syncImmersionMediaState: () => {},
|
|
||||||
updateCurrentMediaTitle: () => {},
|
|
||||||
resetAnilistMediaGuessState: () => {},
|
|
||||||
reportJellyfinRemoteProgress: () => {},
|
|
||||||
updateSubtitleRenderMetrics: () => {},
|
|
||||||
},
|
|
||||||
mpvClientRuntimeServiceFactoryMainDeps: {
|
|
||||||
createClient: class {
|
|
||||||
connect(): void {}
|
|
||||||
on(): void {}
|
|
||||||
},
|
|
||||||
getSocketPath: () => '/tmp/mpv.sock',
|
|
||||||
getResolvedConfig: () => ({ auto_start_overlay: false }),
|
|
||||||
isAutoStartOverlayEnabled: () => false,
|
|
||||||
setOverlayVisible: () => {},
|
|
||||||
isVisibleOverlayVisible: () => false,
|
|
||||||
getReconnectTimer: () => null,
|
|
||||||
setReconnectTimer: () => {},
|
|
||||||
},
|
|
||||||
updateMpvSubtitleRenderMetricsMainDeps: {
|
|
||||||
getCurrentMetrics: () => BASE_METRICS,
|
|
||||||
setCurrentMetrics: () => {},
|
|
||||||
applyPatch: (current, patch) => ({ next: { ...current, ...patch }, changed: true }),
|
|
||||||
broadcastMetrics: () => {},
|
|
||||||
},
|
|
||||||
tokenizer: {
|
tokenizer: {
|
||||||
|
...fixture.tokenizer,
|
||||||
buildTokenizerDepsMainDeps: {
|
buildTokenizerDepsMainDeps: {
|
||||||
getYomitanExt: () => null,
|
...fixture.tokenizer.buildTokenizerDepsMainDeps,
|
||||||
getYomitanParserWindow: () => null,
|
|
||||||
setYomitanParserWindow: () => {},
|
|
||||||
getYomitanParserReadyPromise: () => null,
|
|
||||||
setYomitanParserReadyPromise: () => {},
|
|
||||||
getYomitanParserInitPromise: () => null,
|
|
||||||
setYomitanParserInitPromise: () => {},
|
|
||||||
isKnownWord: () => false,
|
|
||||||
recordLookup: () => {},
|
|
||||||
getKnownWordMatchMode: () => 'headword',
|
|
||||||
getNPlusOneEnabled: () => true,
|
getNPlusOneEnabled: () => true,
|
||||||
getMinSentenceWordsForNPlusOne: () => 3,
|
|
||||||
getJlptLevel: () => null,
|
|
||||||
getJlptEnabled: () => true,
|
getJlptEnabled: () => true,
|
||||||
getFrequencyDictionaryEnabled: () => true,
|
getFrequencyDictionaryEnabled: () => true,
|
||||||
getFrequencyDictionaryMatchMode: () => 'headword',
|
|
||||||
getFrequencyRank: () => null,
|
|
||||||
getYomitanGroupDebugEnabled: () => false,
|
|
||||||
getMecabTokenizer: () => null,
|
|
||||||
},
|
},
|
||||||
createTokenizerRuntimeDeps: () => ({ isKnownWord: () => false }),
|
|
||||||
tokenizeSubtitle: async (text) => ({ text }),
|
|
||||||
createMecabTokenizerAndCheckMainDeps: {
|
createMecabTokenizerAndCheckMainDeps: {
|
||||||
getMecabTokenizer: () => null,
|
...fixture.tokenizer.createMecabTokenizerAndCheckMainDeps,
|
||||||
setMecabTokenizer: () => {},
|
|
||||||
createMecabTokenizer: () => ({ id: 'mecab' }),
|
|
||||||
checkAvailability: async () => mecabDeferred.promise,
|
checkAvailability: async () => mecabDeferred.promise,
|
||||||
},
|
},
|
||||||
prewarmSubtitleDictionariesMainDeps: {
|
prewarmSubtitleDictionariesMainDeps: {
|
||||||
@@ -628,25 +444,6 @@ test('composeMpvRuntimeHandlers does not block first tokenization on dictionary
|
|||||||
ensureFrequencyDictionaryLookup: async () => frequencyDeferred.promise,
|
ensureFrequencyDictionaryLookup: async () => frequencyDeferred.promise,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
warmups: {
|
|
||||||
launchBackgroundWarmupTaskMainDeps: {
|
|
||||||
now: () => 0,
|
|
||||||
logDebug: () => {},
|
|
||||||
logWarn: () => {},
|
|
||||||
},
|
|
||||||
startBackgroundWarmupsMainDeps: {
|
|
||||||
getStarted: () => false,
|
|
||||||
setStarted: () => {},
|
|
||||||
isTexthookerOnlyMode: () => false,
|
|
||||||
ensureYomitanExtensionLoaded: async () => undefined,
|
|
||||||
shouldWarmupMecab: () => false,
|
|
||||||
shouldWarmupYomitanExtension: () => false,
|
|
||||||
shouldWarmupSubtitleDictionaries: () => false,
|
|
||||||
shouldWarmupJellyfinRemoteSession: () => false,
|
|
||||||
shouldAutoConnectJellyfinRemote: () => false,
|
|
||||||
startJellyfinRemoteSession: async () => {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const tokenizePromise = composed.tokenizeSubtitle('first line').then(() => {
|
const tokenizePromise = composed.tokenizeSubtitle('first line').then(() => {
|
||||||
@@ -667,86 +464,19 @@ test('composeMpvRuntimeHandlers shows annotation loading OSD after tokenization-
|
|||||||
const frequencyDeferred = createDeferred();
|
const frequencyDeferred = createDeferred();
|
||||||
const osdMessages: string[] = [];
|
const osdMessages: string[] = [];
|
||||||
|
|
||||||
|
const fixture = createDefaultMpvFixture();
|
||||||
const composed = composeMpvRuntimeHandlers<
|
const composed = composeMpvRuntimeHandlers<
|
||||||
{ connect: () => void; on: () => void },
|
{ connect: () => void; on: () => void },
|
||||||
{ onTokenizationReady?: (text: string) => void },
|
{ onTokenizationReady?: (text: string) => void },
|
||||||
{ text: string }
|
{ text: string }
|
||||||
>({
|
>({
|
||||||
bindMpvMainEventHandlersMainDeps: {
|
...fixture,
|
||||||
appState: {
|
|
||||||
initialArgs: null,
|
|
||||||
overlayRuntimeInitialized: true,
|
|
||||||
mpvClient: null,
|
|
||||||
immersionTracker: null,
|
|
||||||
subtitleTimingTracker: null,
|
|
||||||
currentSubText: '',
|
|
||||||
currentSubAssText: '',
|
|
||||||
playbackPaused: null,
|
|
||||||
previousSecondarySubVisibility: null,
|
|
||||||
},
|
|
||||||
getQuitOnDisconnectArmed: () => false,
|
|
||||||
scheduleQuitCheck: () => {},
|
|
||||||
quitApp: () => {},
|
|
||||||
reportJellyfinRemoteStopped: () => {},
|
|
||||||
syncOverlayMpvSubtitleSuppression: () => {},
|
|
||||||
maybeRunAnilistPostWatchUpdate: async () => {},
|
|
||||||
logSubtitleTimingError: () => {},
|
|
||||||
broadcastToOverlayWindows: () => {},
|
|
||||||
onSubtitleChange: () => {},
|
|
||||||
refreshDiscordPresence: () => {},
|
|
||||||
ensureImmersionTrackerInitialized: () => {},
|
|
||||||
updateCurrentMediaPath: () => {},
|
|
||||||
restoreMpvSubVisibility: () => {},
|
|
||||||
getCurrentAnilistMediaKey: () => null,
|
|
||||||
resetAnilistMediaTracking: () => {},
|
|
||||||
maybeProbeAnilistDuration: () => {},
|
|
||||||
ensureAnilistMediaGuess: () => {},
|
|
||||||
syncImmersionMediaState: () => {},
|
|
||||||
updateCurrentMediaTitle: () => {},
|
|
||||||
resetAnilistMediaGuessState: () => {},
|
|
||||||
reportJellyfinRemoteProgress: () => {},
|
|
||||||
updateSubtitleRenderMetrics: () => {},
|
|
||||||
},
|
|
||||||
mpvClientRuntimeServiceFactoryMainDeps: {
|
|
||||||
createClient: class {
|
|
||||||
connect(): void {}
|
|
||||||
on(): void {}
|
|
||||||
},
|
|
||||||
getSocketPath: () => '/tmp/mpv.sock',
|
|
||||||
getResolvedConfig: () => ({ auto_start_overlay: false }),
|
|
||||||
isAutoStartOverlayEnabled: () => false,
|
|
||||||
setOverlayVisible: () => {},
|
|
||||||
isVisibleOverlayVisible: () => false,
|
|
||||||
getReconnectTimer: () => null,
|
|
||||||
setReconnectTimer: () => {},
|
|
||||||
},
|
|
||||||
updateMpvSubtitleRenderMetricsMainDeps: {
|
|
||||||
getCurrentMetrics: () => BASE_METRICS,
|
|
||||||
setCurrentMetrics: () => {},
|
|
||||||
applyPatch: (current, patch) => ({ next: { ...current, ...patch }, changed: true }),
|
|
||||||
broadcastMetrics: () => {},
|
|
||||||
},
|
|
||||||
tokenizer: {
|
tokenizer: {
|
||||||
|
...fixture.tokenizer,
|
||||||
buildTokenizerDepsMainDeps: {
|
buildTokenizerDepsMainDeps: {
|
||||||
getYomitanExt: () => null,
|
...fixture.tokenizer.buildTokenizerDepsMainDeps,
|
||||||
getYomitanParserWindow: () => null,
|
|
||||||
setYomitanParserWindow: () => {},
|
|
||||||
getYomitanParserReadyPromise: () => null,
|
|
||||||
setYomitanParserReadyPromise: () => {},
|
|
||||||
getYomitanParserInitPromise: () => null,
|
|
||||||
setYomitanParserInitPromise: () => {},
|
|
||||||
isKnownWord: () => false,
|
|
||||||
recordLookup: () => {},
|
|
||||||
getKnownWordMatchMode: () => 'headword',
|
|
||||||
getNPlusOneEnabled: () => false,
|
|
||||||
getMinSentenceWordsForNPlusOne: () => 3,
|
|
||||||
getJlptLevel: () => null,
|
|
||||||
getJlptEnabled: () => true,
|
getJlptEnabled: () => true,
|
||||||
getFrequencyDictionaryEnabled: () => true,
|
getFrequencyDictionaryEnabled: () => true,
|
||||||
getFrequencyDictionaryMatchMode: () => 'headword',
|
|
||||||
getFrequencyRank: () => null,
|
|
||||||
getYomitanGroupDebugEnabled: () => false,
|
|
||||||
getMecabTokenizer: () => null,
|
|
||||||
},
|
},
|
||||||
createTokenizerRuntimeDeps: (deps) =>
|
createTokenizerRuntimeDeps: (deps) =>
|
||||||
deps as unknown as { onTokenizationReady?: (text: string) => void },
|
deps as unknown as { onTokenizationReady?: (text: string) => void },
|
||||||
@@ -754,12 +484,6 @@ test('composeMpvRuntimeHandlers shows annotation loading OSD after tokenization-
|
|||||||
deps.onTokenizationReady?.(text);
|
deps.onTokenizationReady?.(text);
|
||||||
return { text };
|
return { text };
|
||||||
},
|
},
|
||||||
createMecabTokenizerAndCheckMainDeps: {
|
|
||||||
getMecabTokenizer: () => null,
|
|
||||||
setMecabTokenizer: () => {},
|
|
||||||
createMecabTokenizer: () => ({ id: 'mecab' }),
|
|
||||||
checkAvailability: async () => {},
|
|
||||||
},
|
|
||||||
prewarmSubtitleDictionariesMainDeps: {
|
prewarmSubtitleDictionariesMainDeps: {
|
||||||
ensureJlptDictionaryLookup: async () => jlptDeferred.promise,
|
ensureJlptDictionaryLookup: async () => jlptDeferred.promise,
|
||||||
ensureFrequencyDictionaryLookup: async () => frequencyDeferred.promise,
|
ensureFrequencyDictionaryLookup: async () => frequencyDeferred.promise,
|
||||||
@@ -768,25 +492,6 @@ test('composeMpvRuntimeHandlers shows annotation loading OSD after tokenization-
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
warmups: {
|
|
||||||
launchBackgroundWarmupTaskMainDeps: {
|
|
||||||
now: () => 0,
|
|
||||||
logDebug: () => {},
|
|
||||||
logWarn: () => {},
|
|
||||||
},
|
|
||||||
startBackgroundWarmupsMainDeps: {
|
|
||||||
getStarted: () => false,
|
|
||||||
setStarted: () => {},
|
|
||||||
isTexthookerOnlyMode: () => false,
|
|
||||||
ensureYomitanExtensionLoaded: async () => undefined,
|
|
||||||
shouldWarmupMecab: () => false,
|
|
||||||
shouldWarmupYomitanExtension: () => false,
|
|
||||||
shouldWarmupSubtitleDictionaries: () => false,
|
|
||||||
shouldWarmupJellyfinRemoteSession: () => false,
|
|
||||||
shouldAutoConnectJellyfinRemote: () => false,
|
|
||||||
startJellyfinRemoteSession: async () => {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const warmupPromise = composed.startTokenizationWarmups();
|
const warmupPromise = composed.startTokenizationWarmups();
|
||||||
@@ -814,89 +519,22 @@ test('composeMpvRuntimeHandlers reuses completed background tokenization warmups
|
|||||||
let frequencyWarmupCalls = 0;
|
let frequencyWarmupCalls = 0;
|
||||||
let mecabTokenizer: { tokenize: () => Promise<never[]> } | null = null;
|
let mecabTokenizer: { tokenize: () => Promise<never[]> } | null = null;
|
||||||
|
|
||||||
|
const fixture = createDefaultMpvFixture();
|
||||||
const composed = composeMpvRuntimeHandlers<
|
const composed = composeMpvRuntimeHandlers<
|
||||||
{ connect: () => void; on: () => void },
|
{ connect: () => void; on: () => void },
|
||||||
{ isKnownWord: () => boolean },
|
{ isKnownWord: () => boolean },
|
||||||
{ text: string }
|
{ text: string }
|
||||||
>({
|
>({
|
||||||
bindMpvMainEventHandlersMainDeps: {
|
...fixture,
|
||||||
appState: {
|
|
||||||
initialArgs: null,
|
|
||||||
overlayRuntimeInitialized: true,
|
|
||||||
mpvClient: null,
|
|
||||||
immersionTracker: null,
|
|
||||||
subtitleTimingTracker: null,
|
|
||||||
currentSubText: '',
|
|
||||||
currentSubAssText: '',
|
|
||||||
playbackPaused: null,
|
|
||||||
previousSecondarySubVisibility: null,
|
|
||||||
},
|
|
||||||
getQuitOnDisconnectArmed: () => false,
|
|
||||||
scheduleQuitCheck: () => {},
|
|
||||||
quitApp: () => {},
|
|
||||||
reportJellyfinRemoteStopped: () => {},
|
|
||||||
syncOverlayMpvSubtitleSuppression: () => {},
|
|
||||||
maybeRunAnilistPostWatchUpdate: async () => {},
|
|
||||||
logSubtitleTimingError: () => {},
|
|
||||||
broadcastToOverlayWindows: () => {},
|
|
||||||
onSubtitleChange: () => {},
|
|
||||||
refreshDiscordPresence: () => {},
|
|
||||||
ensureImmersionTrackerInitialized: () => {},
|
|
||||||
updateCurrentMediaPath: () => {},
|
|
||||||
restoreMpvSubVisibility: () => {},
|
|
||||||
getCurrentAnilistMediaKey: () => null,
|
|
||||||
resetAnilistMediaTracking: () => {},
|
|
||||||
maybeProbeAnilistDuration: () => {},
|
|
||||||
ensureAnilistMediaGuess: () => {},
|
|
||||||
syncImmersionMediaState: () => {},
|
|
||||||
updateCurrentMediaTitle: () => {},
|
|
||||||
resetAnilistMediaGuessState: () => {},
|
|
||||||
reportJellyfinRemoteProgress: () => {},
|
|
||||||
updateSubtitleRenderMetrics: () => {},
|
|
||||||
},
|
|
||||||
mpvClientRuntimeServiceFactoryMainDeps: {
|
|
||||||
createClient: class {
|
|
||||||
connect(): void {}
|
|
||||||
on(): void {}
|
|
||||||
},
|
|
||||||
getSocketPath: () => '/tmp/mpv.sock',
|
|
||||||
getResolvedConfig: () => ({ auto_start_overlay: false }),
|
|
||||||
isAutoStartOverlayEnabled: () => false,
|
|
||||||
setOverlayVisible: () => {},
|
|
||||||
isVisibleOverlayVisible: () => false,
|
|
||||||
getReconnectTimer: () => null,
|
|
||||||
setReconnectTimer: () => {},
|
|
||||||
},
|
|
||||||
updateMpvSubtitleRenderMetricsMainDeps: {
|
|
||||||
getCurrentMetrics: () => BASE_METRICS,
|
|
||||||
setCurrentMetrics: () => {},
|
|
||||||
applyPatch: (current, patch) => ({ next: { ...current, ...patch }, changed: true }),
|
|
||||||
broadcastMetrics: () => {},
|
|
||||||
},
|
|
||||||
tokenizer: {
|
tokenizer: {
|
||||||
|
...fixture.tokenizer,
|
||||||
buildTokenizerDepsMainDeps: {
|
buildTokenizerDepsMainDeps: {
|
||||||
getYomitanExt: () => null,
|
...fixture.tokenizer.buildTokenizerDepsMainDeps,
|
||||||
getYomitanParserWindow: () => null,
|
|
||||||
setYomitanParserWindow: () => {},
|
|
||||||
getYomitanParserReadyPromise: () => null,
|
|
||||||
setYomitanParserReadyPromise: () => {},
|
|
||||||
getYomitanParserInitPromise: () => null,
|
|
||||||
setYomitanParserInitPromise: () => {},
|
|
||||||
isKnownWord: () => false,
|
|
||||||
recordLookup: () => {},
|
|
||||||
getKnownWordMatchMode: () => 'headword',
|
|
||||||
getNPlusOneEnabled: () => true,
|
getNPlusOneEnabled: () => true,
|
||||||
getMinSentenceWordsForNPlusOne: () => 3,
|
|
||||||
getJlptLevel: () => null,
|
|
||||||
getJlptEnabled: () => true,
|
getJlptEnabled: () => true,
|
||||||
getFrequencyDictionaryEnabled: () => true,
|
getFrequencyDictionaryEnabled: () => true,
|
||||||
getFrequencyDictionaryMatchMode: () => 'headword',
|
|
||||||
getFrequencyRank: () => null,
|
|
||||||
getYomitanGroupDebugEnabled: () => false,
|
|
||||||
getMecabTokenizer: () => mecabTokenizer,
|
getMecabTokenizer: () => mecabTokenizer,
|
||||||
},
|
},
|
||||||
createTokenizerRuntimeDeps: () => ({ isKnownWord: () => false }),
|
|
||||||
tokenizeSubtitle: async (text) => ({ text }),
|
|
||||||
createMecabTokenizerAndCheckMainDeps: {
|
createMecabTokenizerAndCheckMainDeps: {
|
||||||
getMecabTokenizer: () => mecabTokenizer,
|
getMecabTokenizer: () => mecabTokenizer,
|
||||||
setMecabTokenizer: (next) => {
|
setMecabTokenizer: (next) => {
|
||||||
@@ -917,26 +555,19 @@ test('composeMpvRuntimeHandlers reuses completed background tokenization warmups
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
warmups: {
|
warmups: {
|
||||||
launchBackgroundWarmupTaskMainDeps: {
|
...fixture.warmups,
|
||||||
now: () => 0,
|
|
||||||
logDebug: () => {},
|
|
||||||
logWarn: () => {},
|
|
||||||
},
|
|
||||||
startBackgroundWarmupsMainDeps: {
|
startBackgroundWarmupsMainDeps: {
|
||||||
|
...fixture.warmups.startBackgroundWarmupsMainDeps,
|
||||||
getStarted: () => started,
|
getStarted: () => started,
|
||||||
setStarted: (next) => {
|
setStarted: (next) => {
|
||||||
started = next;
|
started = next;
|
||||||
},
|
},
|
||||||
isTexthookerOnlyMode: () => false,
|
|
||||||
ensureYomitanExtensionLoaded: async () => {
|
ensureYomitanExtensionLoaded: async () => {
|
||||||
yomitanWarmupCalls += 1;
|
yomitanWarmupCalls += 1;
|
||||||
},
|
},
|
||||||
shouldWarmupMecab: () => true,
|
shouldWarmupMecab: () => true,
|
||||||
shouldWarmupYomitanExtension: () => true,
|
shouldWarmupYomitanExtension: () => true,
|
||||||
shouldWarmupSubtitleDictionaries: () => true,
|
shouldWarmupSubtitleDictionaries: () => true,
|
||||||
shouldWarmupJellyfinRemoteSession: () => false,
|
|
||||||
shouldAutoConnectJellyfinRemote: () => false,
|
|
||||||
startJellyfinRemoteSession: async () => {},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user