feat(260929-dmx): Widget-Raster horizontal doppelt so fein (48 Spalten, Version 3)
- COLS lg 48 / md 40 / sm 24 / xs 16 / xxs 4, Zeilenhoehe und Abstand unveraendert - Migration stufenweise: v1->v2 wie bisher, v2->v3 nur x/w/minW/maxW x2 - Rueckfallwerte fuer Widgets ohne Eintrag auf 8 Einheiten Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,13 +8,14 @@ import {
|
||||
} from './grid-layout-migration';
|
||||
|
||||
/**
|
||||
* grid-layout-migration.test — NEU (quick-260916-bwo, feineres Dashboard-Raster).
|
||||
* grid-layout-migration.test (quick-260916-bwo, erweitert quick-260929-dmx).
|
||||
*
|
||||
* Sieben Tests fuer die einmalige Umrechnung gespeicherter Anordnungen von
|
||||
* den alten Einheiten (12 Spalten / 40 px) in die neuen (24 Spalten / 20 px).
|
||||
* Kern ist T-BWO-02: die Verdopplung darf GENAU EINMAL geschehen. Der Marker
|
||||
* `__gridVersion` steht dafuer im gespeicherten JSON, nie im Zustand — Test 4
|
||||
* (Idempotenz) wird rot, sobald jemand die Marker-Pruefung entfernt.
|
||||
* Tests fuer die stufenweise Umrechnung gespeicherter Anordnungen:
|
||||
* v1 (12 Spalten / 40 px) -> v2 (24 / 20 px, alles x2) -> v3 (48 Spalten,
|
||||
* nur Breite x2). Kern ist T-BWO-02: jede Stufe darf GENAU EINMAL geschehen.
|
||||
* Der Marker `__gridVersion` steht dafuer im gespeicherten JSON, nie im
|
||||
* Zustand — der Idempotenz-Test wird rot, sobald jemand die Marker-Pruefung
|
||||
* entfernt.
|
||||
*/
|
||||
|
||||
function altLayouts() {
|
||||
@@ -31,14 +32,14 @@ function altLayouts() {
|
||||
}
|
||||
|
||||
describe('grid-layout-migration (quick-260916-bwo)', () => {
|
||||
it('Test 1: alte Anordnung ohne Marker -> alle Positionen und Groessen x2, migrated true, kein Marker im Ergebnis', () => {
|
||||
it('Test 1: v1-Anordnung ohne Marker -> beide Stufen: x/w/minW/maxW x4, y/h/minH/maxH x2, migrated true, kein Marker im Ergebnis', () => {
|
||||
const { layouts, migrated } = migrateGridLayouts(altLayouts());
|
||||
|
||||
expect(layouts.lg[0]).toEqual({
|
||||
i: 'a', x: 2, y: 4, w: 4, h: 6, minW: 4, minH: 4, moved: false, static: false,
|
||||
i: 'a', x: 4, y: 4, w: 8, h: 6, minW: 8, minH: 4, moved: false, static: false,
|
||||
});
|
||||
expect(layouts.lg[1]).toEqual({ i: 'b', x: 4, y: 0, w: 12, h: 4, maxW: 24, maxH: 16 });
|
||||
expect(layouts.md[0]).toEqual({ i: 'a', x: 0, y: 0, w: 4, h: 4 });
|
||||
expect(layouts.lg[1]).toEqual({ i: 'b', x: 8, y: 0, w: 24, h: 4, maxW: 48, maxH: 16 });
|
||||
expect(layouts.md[0]).toEqual({ i: 'a', x: 0, y: 0, w: 8, h: 4 });
|
||||
expect(layouts.sm).toEqual([]);
|
||||
expect(layouts.xs).toEqual([]);
|
||||
expect(layouts.xxs).toEqual([]);
|
||||
@@ -47,15 +48,44 @@ describe('grid-layout-migration (quick-260916-bwo)', () => {
|
||||
expect(GRID_SCALE_FACTOR).toBe(2);
|
||||
});
|
||||
|
||||
it('Test 2: markierte Anordnung (__gridVersion 2) bleibt unveraendert, migrated false', () => {
|
||||
it('Test 2: v2-Anordnung (__gridVersion 2) -> nur die zweite Stufe: x/w/minW/maxW x2, y/h/minH/maxH unveraendert, migrated true', () => {
|
||||
const alt = altLayouts();
|
||||
const { layouts, migrated } = migrateGridLayouts({ ...alt, __gridVersion: 2 });
|
||||
|
||||
expect(layouts.lg[0]).toEqual({
|
||||
i: 'a', x: 2, y: 2, w: 4, h: 3, minW: 4, minH: 2, moved: false, static: false,
|
||||
});
|
||||
expect(layouts.lg[1]).toEqual({ i: 'b', x: 4, y: 0, w: 12, h: 2, maxW: 24, maxH: 8 });
|
||||
expect(layouts.md[0]).toEqual({ i: 'a', x: 0, y: 0, w: 4, h: 2 });
|
||||
expect(migrated).toBe(true);
|
||||
expect(Object.keys(layouts)).not.toContain(GRID_VERSION_KEY);
|
||||
});
|
||||
|
||||
it('Test 2b: v3-Anordnung (__gridVersion 3) bleibt unveraendert, migrated false', () => {
|
||||
const alt = altLayouts();
|
||||
const { layouts, migrated } = migrateGridLayouts({ ...alt, __gridVersion: 3 });
|
||||
|
||||
expect(layouts).toEqual(alt);
|
||||
expect(migrated).toBe(false);
|
||||
expect(Object.keys(layouts)).not.toContain(GRID_VERSION_KEY);
|
||||
});
|
||||
|
||||
it('Test 2c: v1 und v2 -> v3 ergeben dieselbe Anordnung, wenn die v2-Eingabe die v1-Eingabe x2 ist', () => {
|
||||
const v1 = altLayouts();
|
||||
const v2 = {
|
||||
lg: [
|
||||
{ i: 'a', x: 2, y: 4, w: 4, h: 6, minW: 4, minH: 4, moved: false, static: false },
|
||||
{ i: 'b', x: 4, y: 0, w: 12, h: 4, maxW: 24, maxH: 16 },
|
||||
],
|
||||
md: [{ i: 'a', x: 0, y: 0, w: 4, h: 4 }],
|
||||
sm: [],
|
||||
xs: [],
|
||||
xxs: [],
|
||||
__gridVersion: 2,
|
||||
};
|
||||
expect(migrateGridLayouts(v2).layouts).toEqual(migrateGridLayouts(v1).layouts);
|
||||
});
|
||||
|
||||
it('Test 3: leere Anordnung bleibt leer, migrated false (kein Speichern noetig)', () => {
|
||||
const empty = { lg: [], md: [], sm: [], xs: [], xxs: [] };
|
||||
const r1 = migrateGridLayouts(empty);
|
||||
@@ -73,6 +103,14 @@ describe('grid-layout-migration (quick-260916-bwo)', () => {
|
||||
|
||||
expect(twice.layouts).toEqual(once.layouts);
|
||||
expect(twice.migrated).toBe(false);
|
||||
|
||||
// Auch die einstufige v2 -> v3 ist idempotent, und der Marker 3 wird geschrieben.
|
||||
const onceV2 = migrateGridLayouts({ ...altLayouts(), __gridVersion: 2 });
|
||||
const marked = withGridVersion(onceV2.layouts);
|
||||
expect(marked[GRID_VERSION_KEY]).toBe(3);
|
||||
const twiceV2 = migrateGridLayouts(marked);
|
||||
expect(twiceV2.layouts).toEqual(onceV2.layouts);
|
||||
expect(twiceV2.migrated).toBe(false);
|
||||
});
|
||||
|
||||
it('Test 5: withGridVersion haengt den Marker an, ohne die Eingabe zu veraendern', () => {
|
||||
@@ -80,30 +118,30 @@ describe('grid-layout-migration (quick-260916-bwo)', () => {
|
||||
const marked = withGridVersion(layouts);
|
||||
|
||||
expect(marked[GRID_VERSION_KEY]).toBe(GRID_VERSION);
|
||||
expect(GRID_VERSION).toBe(2);
|
||||
expect(GRID_VERSION).toBe(3);
|
||||
expect(marked.lg).toBe(layouts.lg);
|
||||
expect(marked.md).toBe(layouts.md);
|
||||
expect(Object.keys(layouts)).not.toContain(GRID_VERSION_KEY);
|
||||
expect((layouts as Record<string, unknown>)[GRID_VERSION_KEY]).toBeUndefined();
|
||||
});
|
||||
|
||||
it('Test 6: Zukunft und Robustheit — Marker 3 bleibt, Zeichenketten-Marker zaehlt nicht, nicht-numerische Felder bleiben', () => {
|
||||
it('Test 6: Zukunft und Robustheit — Marker 4 bleibt, Zeichenketten-Marker zaehlt nicht, nicht-numerische Felder bleiben', () => {
|
||||
const alt = altLayouts();
|
||||
|
||||
const future = migrateGridLayouts({ ...alt, __gridVersion: 3 });
|
||||
const future = migrateGridLayouts({ ...alt, __gridVersion: 4 });
|
||||
expect(future.layouts).toEqual(alt);
|
||||
expect(future.migrated).toBe(false);
|
||||
|
||||
const stringMarker = migrateGridLayouts({ ...alt, __gridVersion: '2' });
|
||||
expect(stringMarker.migrated).toBe(true);
|
||||
expect(stringMarker.layouts.lg[0].x).toBe(2);
|
||||
expect(stringMarker.layouts.lg[0].x).toBe(4);
|
||||
expect(Object.keys(stringMarker.layouts)).not.toContain(GRID_VERSION_KEY);
|
||||
|
||||
const odd = migrateGridLayouts({
|
||||
lg: [{ i: 'c', x: 'kaputt', y: 1, w: 2, h: 2, resizeHandles: ['se'], moved: true, static: false }],
|
||||
});
|
||||
expect(odd.layouts.lg[0]).toEqual({
|
||||
i: 'c', x: 'kaputt', y: 2, w: 4, h: 4, resizeHandles: ['se'], moved: true, static: false,
|
||||
i: 'c', x: 'kaputt', y: 2, w: 8, h: 4, resizeHandles: ['se'], moved: true, static: false,
|
||||
});
|
||||
expect(Number.isNaN(odd.layouts.lg[0].x)).toBe(false);
|
||||
expect(odd.migrated).toBe(true);
|
||||
@@ -112,7 +150,7 @@ describe('grid-layout-migration (quick-260916-bwo)', () => {
|
||||
it('Test 7: Fremdwerte — Nicht-Arrays werden weggelassen, Nicht-Objekte liefern eine leere Anordnung', () => {
|
||||
const r = migrateGridLayouts({ lg: 'kaputt', md: null, sm: [{ i: 'a', x: 1, y: 1, w: 1, h: 1 }] });
|
||||
expect(Object.keys(r.layouts)).toEqual(['sm']);
|
||||
expect(r.layouts.sm[0]).toEqual({ i: 'a', x: 2, y: 2, w: 2, h: 2 });
|
||||
expect(r.layouts.sm[0]).toEqual({ i: 'a', x: 4, y: 2, w: 4, h: 2 });
|
||||
expect(r.migrated).toBe(true);
|
||||
|
||||
expect(migrateGridLayouts(null)).toEqual({ layouts: {}, migrated: false });
|
||||
|
||||
Reference in New Issue
Block a user