Files
DemonGatanjieu-Anomalous_Mo…/tests/audio_node_targets.mjs
T
DemonGatanjieuandClaude Opus 5.5 7b09909e5b test: publish the plugin's tests, one command to run them
tests/ (Python backend tests, .mjs frontend rule tests) is no longer
ignored. tools/run_tests.mjs runs the structure check, every
tests/*.mjs and the Python tests with $PYTHON, the portable
python_embeded or python. docs/guides/testing.md says how to run and
write them; README links it. Developer notes no longer point at 18 test
files that were removed earlier (AGENTS.md table, backend, frontend and
update-guide notes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 17:47:35 +08:00

38 lines
2.2 KiB
JavaScript

// Run: node tests/audio_node_targets.mjs (pure rules, no DOM)
import assert from 'node:assert/strict';
import { fileURLToPath, pathToFileURL } from 'node:url';
import path from 'node:path';
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const { planVoiceDrop, targetForNode } =
await import(pathToFileURL(path.join(root, 'web/modules/audio_node_targets.js')).href);
const ttsNode = (values = ['阿罗娜/日配数据集制', '普拉娜']) => ({
type: 'AnomalousTTS_CharacterSpeech',
widgets: [{ name: 'character', value: '', options: { values } }, { name: 'text', value: '' }],
});
const group = { character: '阿罗娜/日配数据集制', node_value: '阿罗娜/日配数据集制', has_main: true };
// A character name goes into `character`, in the node's own spelling.
const plan = planVoiceDrop(ttsNode(), group);
assert.equal(plan.ok, true);
assert.equal(plan.value, '阿罗娜/日配数据集制');
assert.equal(plan.widget.name, 'character');
assert.equal(planVoiceDrop(ttsNode(['阿罗娜\\日配数据集制']), group).value, '阿罗娜\\日配数据集制', 'Windows spelling');
assert.equal(targetForNode(ttsNode()).speechWidget, 'text');
assert.equal(targetForNode({ comfyClass: 'AnomalousTTS_CharacterSpeech' })?.id, 'anomalous-tts');
// Anything not listed is refused, even with a matching widget name; Load Audio and F5-TTS included.
const lookalike = { type: 'SomeOtherTTS', widgets: [{ name: 'character', options: { values: [group.node_value] } }] };
for (const node of [lookalike, { type: 'LoadAudio', widgets: [] }, { type: 'F5TTSAudio', widgets: [] }]) {
assert.equal(targetForNode(node), null, node.type);
assert.equal(planVoiceDrop(node, group).reason, 'unsupported', node.type);
}
assert.equal(planVoiceDrop(null, group).reason, 'unsupported');
// Refusals that explain themselves.
assert.equal(planVoiceDrop(ttsNode(['普拉娜']), group).reason, 'notListed');
assert.equal(planVoiceDrop(ttsNode(['普拉娜']), group).path, group.node_value);
assert.equal(planVoiceDrop(ttsNode(), { ...group, has_main: false }).reason, 'noMainVoice');
assert.equal(planVoiceDrop({ type: 'AnomalousTTS_CharacterSpeech', widgets: [] }, group).reason, 'unsupported');
console.log('audio node target rules OK');