mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-26 00:55:16 -07:00
06d0e3ed18
- Pass --macos-menu-shortcuts=no on Darwin so SubMiner bindings reach mpv - Replace queued IPC listener with latest-value variant for subtitle channels - Skip JSONC line/block comments in duplicate-key offset helpers - Preserve configured Anki note model name in selectPreferredNoteFieldModelName - Guard known-words deck rename against collision; add chooseKnownWordsDeckRenameValue - Apply asCssColor on hover token CSS compat reads
159 lines
4.0 KiB
TypeScript
159 lines
4.0 KiB
TypeScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { parse } from 'jsonc-parser';
|
|
import { DEFAULT_CONFIG } from '../definitions';
|
|
import { applyConfigSettingsPatchToContent, buildConfigSettingsSnapshot } from './jsonc-edit';
|
|
import { buildConfigSettingsRegistry } from './registry';
|
|
|
|
test('applyConfigSettingsPatchToContent preserves JSONC comments while setting nested values', () => {
|
|
const input = `{
|
|
// keep this comment
|
|
"subtitleStyle": {
|
|
"fontSize": 35,
|
|
},
|
|
}`;
|
|
|
|
const result = applyConfigSettingsPatchToContent({
|
|
content: input,
|
|
operations: [
|
|
{
|
|
op: 'set',
|
|
path: 'subtitleStyle.autoPauseVideoOnHover',
|
|
value: false,
|
|
},
|
|
],
|
|
previousWarnings: [],
|
|
});
|
|
|
|
assert.equal(result.ok, true);
|
|
assert.match(result.content, /keep this comment/);
|
|
const parsed = parse(result.content);
|
|
assert.equal(parsed.subtitleStyle.autoPauseVideoOnHover, false);
|
|
assert.equal(parsed.subtitleStyle.fontSize, 35);
|
|
});
|
|
|
|
test('applyConfigSettingsPatchToContent updates effective duplicate object path', () => {
|
|
const input = `{
|
|
"ankiConnect": {
|
|
"nPlusOne": {
|
|
"enabled": true
|
|
},
|
|
"knownWords": {
|
|
"highlightEnabled": true
|
|
},
|
|
"nPlusOne": {
|
|
"minSentenceWords": 3
|
|
}
|
|
}
|
|
}`;
|
|
|
|
const result = applyConfigSettingsPatchToContent({
|
|
content: input,
|
|
operations: [
|
|
{
|
|
op: 'set',
|
|
path: 'ankiConnect.nPlusOne.enabled',
|
|
value: true,
|
|
},
|
|
],
|
|
previousWarnings: [],
|
|
});
|
|
|
|
assert.equal(result.ok, true);
|
|
const parsed = parse(result.content);
|
|
assert.equal(parsed.ankiConnect.nPlusOne.enabled, true);
|
|
assert.equal(parsed.ankiConnect.nPlusOne.minSentenceWords, 3);
|
|
});
|
|
|
|
test('applyConfigSettingsPatchToContent removes duplicate properties across JSONC trivia', () => {
|
|
const input = `{
|
|
"ankiConnect": {
|
|
"nPlusOne": {
|
|
"enabled": false
|
|
} /* old value */ ,
|
|
// effective value follows
|
|
"nPlusOne": {
|
|
"minSentenceWords": 3
|
|
}
|
|
}
|
|
}`;
|
|
|
|
const result = applyConfigSettingsPatchToContent({
|
|
content: input,
|
|
operations: [
|
|
{
|
|
op: 'set',
|
|
path: 'ankiConnect.nPlusOne.enabled',
|
|
value: true,
|
|
},
|
|
],
|
|
previousWarnings: [],
|
|
});
|
|
|
|
assert.equal(result.ok, true);
|
|
const parsed = parse(result.content);
|
|
assert.equal(parsed.ankiConnect.nPlusOne.enabled, true);
|
|
assert.equal(parsed.ankiConnect.nPlusOne.minSentenceWords, 3);
|
|
});
|
|
|
|
test('applyConfigSettingsPatchToContent reset removes explicit path', () => {
|
|
const input = `{
|
|
"subtitleStyle": {
|
|
"fontSize": 41,
|
|
"autoPauseVideoOnHover": false
|
|
}
|
|
}`;
|
|
|
|
const result = applyConfigSettingsPatchToContent({
|
|
content: input,
|
|
operations: [{ op: 'reset', path: 'subtitleStyle.autoPauseVideoOnHover' }],
|
|
previousWarnings: [],
|
|
});
|
|
|
|
assert.equal(result.ok, true);
|
|
const parsed = parse(result.content);
|
|
assert.equal(Object.hasOwn(parsed.subtitleStyle, 'autoPauseVideoOnHover'), false);
|
|
assert.equal(parsed.subtitleStyle.fontSize, 41);
|
|
});
|
|
|
|
test('applyConfigSettingsPatchToContent rejects warnings caused by modified fields', () => {
|
|
const result = applyConfigSettingsPatchToContent({
|
|
content: '{}',
|
|
operations: [
|
|
{
|
|
op: 'set',
|
|
path: 'subtitleStyle.autoPauseVideoOnHover',
|
|
value: 'bad',
|
|
},
|
|
],
|
|
previousWarnings: [],
|
|
});
|
|
|
|
assert.equal(result.ok, false);
|
|
assert.equal(result.warnings[0]?.path, 'subtitleStyle.autoPauseVideoOnHover');
|
|
});
|
|
|
|
test('buildConfigSettingsSnapshot masks configured secret values', () => {
|
|
const fields = buildConfigSettingsRegistry(DEFAULT_CONFIG);
|
|
const snapshot = buildConfigSettingsSnapshot({
|
|
configPath: '/tmp/config.jsonc',
|
|
rawConfig: {
|
|
ai: {
|
|
apiKey: 'secret-key',
|
|
},
|
|
},
|
|
resolvedConfig: {
|
|
...DEFAULT_CONFIG,
|
|
ai: {
|
|
...DEFAULT_CONFIG.ai,
|
|
apiKey: 'secret-key',
|
|
},
|
|
},
|
|
warnings: [],
|
|
fields,
|
|
});
|
|
|
|
const apiKey = snapshot.values['ai.apiKey'];
|
|
assert.deepEqual(apiKey, { configured: true });
|
|
});
|