Add delete buttons and bar add/create to sub-objects pane

This commit is contained in:
c0dev0id
2026-06-30 13:18:29 +02:00
parent e011c9e7d8
commit 66c1f2c151
8 changed files with 261 additions and 39 deletions

View File

@@ -488,6 +488,43 @@ const artClean = [{ name: 'f', isDirty: false, properties: [{ name: 'add_stress'
const { text: artUntouched } = patchScore(ART_SCORE, [], [], null, artClean);
ok('clean articles section left verbatim', artUntouched.includes('{ add_stress: 3 }'));
// ── patchScore articlesModified flag ──────────────────────────────────────
section('patchScore articlesModified flag');
const artCleanForFlag = [{ name: 'f', isDirty: false, properties: [{ name: 'add_stress', value: 99, scope: 'defaults' }] }];
const { text: artFlagPatched, log: artFlagLog } = patchScore(ART_SCORE, [], [], null, artCleanForFlag, { articlesModified: true });
ok('articlesModified forces re-serialization', artFlagPatched.includes('add_stress: 99'));
ok('articlesModified: old flow-style replaced', !artFlagPatched.includes('{ add_stress: 3 }'));
// ── patchScore deleted bars ────────────────────────────────────────────────
section('patchScore deleted bars');
const delBar1 = { id: '001P1L1M1', isDirty: true, deleted: true, stressor: null, tempoLevels: null, upperStressBound: null, lowerStressBound: null, tempoShape: null };
const delBar2 = { id: '001P1L1M2', isDirty: false, stressor: null, tempoLevels: null, upperStressBound: null, lowerStressBound: null, tempoShape: null };
const { text: delBarPatched } = patchScore(RAW_SCORE_WITH_BARS, [], [delBar1, delBar2]);
ok('deleted bar removed from output', !delBarPatched.includes('_id: 001P1L1M1'));
ok('non-deleted bar preserved', delBarPatched.includes('_id: 001P1L1M2'));
ok('deleted bar reduces document count', (delBarPatched.match(/\n---\n/g) ?? []).length === 1);
// ── patchScore new bars ────────────────────────────────────────────────────
section('patchScore new bars');
const newBarEntry = { id: '001P1L1M3', isDirty: true, isNew: true, stressor: null, tempoLevels: 120, upperStressBound: null, lowerStressBound: null, tempoShape: null };
const { text: newBarPatched, log: newBarLog } = patchScore(RAW_SCORE_WITH_BARS, [], [newBarEntry]);
ok('new bar appended to output', newBarPatched.includes('_id: 001P1L1M3'));
ok('new bar has _meta with BPM', newBarPatched.includes('beats_per_minute: 120'));
ok('new bar appended as extra document', (newBarPatched.match(/\n---\n/g) ?? []).length === 3);
ok('new bar logged as changed', newBarLog.some(e => e.level === 'changed' && e.path === 'bar / 001P1L1M3'));
// ── patchScore deleted instrument ─────────────────────────────────────────
section('patchScore deleted instrument');
const delInstrScore = `instrument alpha:\n character:\n A: "1:0,10;1,0"\n\ninstrument ki:\n character:\n A: "1:0,5;1,0"\n`;
const delInstrList = [
{ name: 'alpha', deleted: true, isDirty: false, variations: [], basicProperties: null, volumes: null, timbre: null, fmModulations: [], amModulations: [] },
{ name: 'ki', deleted: false, isDirty: false, variations: [], basicProperties: null, volumes: null, timbre: null, fmModulations: [], amModulations: [] },
];
const { text: delInstrPatched, log: delInstrLog } = patchScore(delInstrScore, delInstrList);
ok('deleted instrument removed from output', !delInstrPatched.includes('instrument alpha:'));
ok('non-deleted instrument preserved', delInstrPatched.includes('instrument ki:'));
ok('deleted instrument logged', delInstrLog.some(e => e.level === 'changed' && e.path?.includes('alpha') && e.path?.includes('deleted')));
// ── Motif parsing ─────────────────────────────────────────────────────────
section('Motif parsing — dynamic motif');
const DYN_MOTIF = `00 bar '001P1L1M1'