- before copy paste

This commit is contained in:
wkh
2026-09-02 09:45:44 +02:00
parent c7885067e7
commit 31108977b9
12 changed files with 708 additions and 44 deletions
+143
View File
@@ -515,6 +515,149 @@ describe('per-object background & text colour', () => {
});
});
describe('full-fidelity JSON export — backgrounds, formats, sheet settings', () => {
/** Populate *every* persisted setting, then verify the export string carries
* it and a round-trip is byte-for-byte identical. */
function loadEverything(s: DocumentStore) {
const analyse = s.doc.sheets[0].id;
const blatt2 = s.doc.sheets[1].id;
const umsatzId = tableId(s, 'Umsatz');
const chartId = s.doc.sheets[0].objects.find((o) => o.kind === 'chart')!.id;
// document
s.setDocumentLocale('en-GB');
s.setCsvDelimiter(';');
// sheet ("Arbeitsblatt") settings — on both sheets
s.setSheetLocale(analyse, 'de-CH');
s.setSheetBackground(analyse, '#eef2ff');
s.setSheetForeground(analyse, '#101828');
s.setSheetShowGrid(analyse, false);
s.setSheetZoom(analyse, 1.25);
s.renameSheet(blatt2, 'Notizen');
s.setSheetBackground(blatt2, '#fff7ed');
// table object: colours + geometry + view + per-row/col + cell formats
s.setObjectBg(umsatzId, '#0b1220');
s.setObjectTextColor(umsatzId, '#f8fafc');
s.setObjectLocale(umsatzId, 'fr-FR');
s.setTableView(umsatzId, { mode: 'fixed', width: 520, height: 300, frozenRows: 1, frozenCols: 1 });
s.setTableRowHeight(umsatzId, 30);
s.setRowHeight(umsatzId, 4, 52);
s.setColWidth(umsatzId, 0, 130);
s.setRangeFormat(umsatzId, { col: 1, row: 1 }, { col: 3, row: 4 }, {
align: 'right',
valign: 'middle',
numFmt: 'pct2',
color: '#dc2626',
bg: '#fee2e2',
bold: true,
italic: true,
});
// chart object
s.setObjectBg(chartId, '#111827');
s.setObjectTextColor(chartId, '#e5e7eb');
s.setChartView(chartId, 'line');
s.resizeChart(chartId, 600, 360);
// text object with full formatting
const txtId = s.addText(analyse);
s.setTextContent(txtId, 'Bericht\nZeile 2');
s.setTextFormat(txtId, { fontSize: 20, bold: true, italic: true, align: 'center' });
s.setObjectTextColor(txtId, '#334155');
s.setObjectBg(txtId, '#f1f5f9');
// multi-range selection
s.setSelection({ tableId: umsatzId, anchor: { col: 0, row: 0 }, focus: { col: 0, row: 0 } });
s.addToSelection(umsatzId, 2, 2);
s.addToSelection(umsatzId, 4, 5);
return { analyse, umsatzId, chartId, txtId };
}
it('the exported JSON text literally contains every setting', () => {
const s = fresh();
loadEverything(s);
const json = serializeDocument(s.snapshot());
const doc = JSON.parse(json);
// document
expect(doc.locale).toBe('en-GB');
expect(doc.csvDelimiter).toBe(';');
// sheet settings
const a = doc.sheets[0];
expect(a).toMatchObject({
locale: 'de-CH',
background: '#eef2ff',
foreground: '#101828',
showGrid: false,
zoom: 1.25,
});
expect(doc.sheets[1]).toMatchObject({ name: 'Notizen', background: '#fff7ed' });
// table object
const tbl = a.objects.find((o: { kind: string }) => o.kind === 'table');
expect(tbl).toMatchObject({
bg: '#0b1220',
fg: '#f8fafc',
locale: 'fr-FR',
rowHeight: 30,
rowHeights: { '4': 52 },
colWidths: { '0': 130 },
view: { mode: 'fixed', width: 520, height: 300, frozenRows: 1, frozenCols: 1 },
});
expect(tbl.formats['1,1']).toEqual({
align: 'right',
valign: 'middle',
numFmt: 'pct2',
color: '#dc2626',
bg: '#fee2e2',
bold: true,
italic: true,
});
// chart object
const cht = a.objects.find((o: { kind: string }) => o.kind === 'chart');
expect(cht).toMatchObject({ bg: '#111827', fg: '#e5e7eb', view: 'line', width: 600, height: 360 });
// text object
const txt = a.objects.find((o: { kind: string }) => o.kind === 'text');
expect(txt).toMatchObject({
text: 'Bericht\nZeile 2',
fontSize: 20,
bold: true,
italic: true,
align: 'center',
color: '#334155',
bg: '#f1f5f9',
});
// multi-range selection
expect(doc.selection.ranges).toHaveLength(2);
});
it('export -> import is lossless for the fully-loaded document', () => {
const s = fresh();
loadEverything(s);
const before = s.snapshot();
s.replaceDocument(parseDocument(serializeDocument(before)));
expect(s.snapshot()).toEqual(before);
});
it('resetToSeed then re-import the exported file restores the exact state', () => {
const s = fresh();
loadEverything(s);
const exported = serializeDocument(s.snapshot());
const before = s.snapshot();
s.resetToSeed();
expect(s.snapshot()).not.toEqual(before);
s.replaceDocument(parseDocument(exported));
expect(s.snapshot()).toEqual(before);
});
});
describe('v1 -> v2 migration', () => {
it('turns each old sheet into a canvas sheet holding one table of the same name', async () => {
const { migrateToV2 } = await import('../../io/json');