// A drag (moving.ts, M4): shown over the document while it lasts — a device // at its dragged place, an item in the frame the document will hold — and // written into the document once, as one change, when it is let go. import { randomUUID } from 'node:crypto'; import { describe, expect, it } from 'vitest'; import * as Y from 'yjs'; import { addDevice, addDocumentation, emptyProject, topologyView, writeProject } from '@mdg-filius/doc'; import { commitMove, movedView } from '../src/moving.js'; function project() { const doc = new Y.Doc(); writeProject(doc, emptyProject()); addDevice(doc, { kind: 'pc', id: 'pc', name: 'Rechner', x: 100, y: 100, newId: randomUUID }, 'me'); addDevice(doc, { kind: 'notebook', id: 'nb', name: 'Notebook', x: 300, y: 100, newId: randomUUID }, 'me'); addDocumentation(doc, { id: 'box', kind: 'rectangle', x: 50, y: 50 }, 'me'); return doc; } describe('a drag over the document', () => { it('is the view itself without a drag', () => { const view = topologyView(project()); expect(movedView(view, [])).toBe(view); }); it('shows a dragged device where it is dragged and leaves the others where they are', () => { const view = movedView(topologyView(project()), [{ kind: 'device', id: 'pc', x: 140.5, y: 260 }]); expect(view.nodes.map((node) => [node.id, node.x, node.y])).toEqual([ ['pc', 140.5, 260], ['nb', 300, 100], ]); }); it('shows the later of two drags of one device (this editor puts its own last)', () => { const view = movedView(topologyView(project()), [ { kind: 'device', id: 'pc', x: 1, y: 1 }, { kind: 'device', id: 'pc', x: 2, y: 2 }, ]); expect(view.nodes.find((node) => node.id === 'pc')).toMatchObject({ x: 2, y: 2 }); }); it('shows a dragged item in the frame the document will hold, and passes over what it does not know', () => { const doc = project(); const before = topologyView(doc); const view = movedView(before, [ { kind: 'doc', id: 'box', x: 200, y: 120, width: -80, height: 40 }, { kind: 'device', id: 'gone', x: 1, y: 1 }, ]); const box = view.docs.find((item) => item.id === 'box')!; expect([box.x, box.y, box.width, box.height]).toEqual([120, 120, 80, 40]); expect(view.nodes).toEqual(before.nodes); commitMove(doc, { kind: 'doc', id: 'box', x: 200, y: 120, width: -80, height: 40 }, 'me'); const stored = topologyView(doc).docs.find((item) => item.id === 'box')!; expect([stored.x, stored.y, stored.width, stored.height]).toEqual([box.x, box.y, box.width, box.height]); }); it('writes a drag into the document as one change, rounded as Java holds places', () => { const doc = project(); let changes = 0; doc.on('update', () => (changes += 1)); commitMove(doc, { kind: 'device', id: 'pc', x: 140.6, y: 259.4 }, 'me'); expect(changes).toBe(1); const pc = topologyView(doc).nodes.find((node) => node.id === 'pc')!; expect([pc.x, pc.y]).toEqual([141, 259]); }); });