exporter: remove stage voice entries for deleted instruments

This commit is contained in:
c0dev0id
2026-07-13 21:16:02 +02:00
parent f18f07dc22
commit 19c89711be
2 changed files with 107 additions and 0 deletions

View File

@@ -570,6 +570,52 @@ ok('deleted instrument removed from output', !delInstrPatched.includes('instrume
ok('non-deleted instrument preserved', delInstrPatched.includes('instrument ki:'));
ok('ki re-serialized and logged', delInstrLog.some(e => e.level === 'changed' && e.path?.includes('ki')));
// ── patchScore stage section cleanup ─────────────────────────────────────
section('patchScore stage section: deleted instrument removes voice entry');
// pi → mapping form, instrument: dev/piano (present) → keep
// ki → mapping form, instrument: alpha (deleted) → remove
// alpha → string form, implicit name=alpha (deleted) → remove
const stageScore = [
'stage:',
' pi:',
' direction: 1|1',
' distance: 0',
' instrument: dev/piano',
' ki:',
' direction: 2|1',
' distance: 1',
' instrument: alpha',
' alpha: 2|3 0',
'',
'instrument dev/piano:',
' character:',
' A: "1:0,10;1,0"',
].join('\n');
const stageInstrList = [
{ name: 'dev/piano', variations: [], basicProperties: null, volumes: null, timbre: null, fmModulations: [], amModulations: [] },
];
const { text: stagePatched } = patchScore(stageScore, stageInstrList);
ok('voice with explicit deleted instrument (mapping form) removed', !stagePatched.includes(' ki:'));
ok('voice with implicit deleted name (string form) removed', !stagePatched.includes(' alpha:'));
ok('voice with explicit surviving instrument (mapping form) kept', stagePatched.includes(' pi:'));
ok('instrument dev/piano block re-serialized', stagePatched.includes('instrument dev/piano:'));
const stageScoreKeep = [
'stage:',
' pi:',
' direction: 1|1',
' distance: 0',
' instrument: dev/piano',
' ki: 2|1 1',
].join('\n');
const stageInstrKeep = [
{ name: 'dev/piano', variations: [], basicProperties: null, volumes: null, timbre: null, fmModulations: [], amModulations: [] },
{ name: 'ki', variations: [], basicProperties: null, volumes: null, timbre: null, fmModulations: [], amModulations: [] },
];
const { text: stageKeptPatched } = patchScore(stageScoreKeep, stageInstrKeep);
ok('retained voice with explicit instrument key kept', stageKeptPatched.includes(' pi:'));
ok('retained voice with implicit instrument name kept', stageKeptPatched.includes(' ki:'));
// ── Motif parsing ─────────────────────────────────────────────────────────
section('Motif parsing — dynamic motif');
const DYN_MOTIF = `00 bar '001P1L1M1'