// Java's drawing of a device and a cable (JSidebarButton, JCablePanel). import { describe, expect, it } from 'vitest'; import { bounds, cablePath, deviceBox, iconOf, ICONS, JAVA_LABEL_FONT_HEIGHT } from '../src/canvas/layout.js'; describe("Java's drawing", () => { it('picks the icon of each kind, the cloud for a switch drawn as one', () => { expect((['pc', 'notebook', 'networkSwitch', 'router', 'gateway', 'remoteLink', 'unsupported'] as const).map((kind) => iconOf(kind, false))).toEqual([ 'server', 'laptop', 'switch', 'router', 'gateway', 'modem', 'cloud', ]); expect(iconOf('networkSwitch', true)).toBe('cloud'); expect(iconOf('router', true)).toBe('router'); }); it('makes a button as wide as its icon or its label, plus 5 and twice the border, and as high as both plus 5', () => { const short = deviceBox({ kind: 'pc', cloud: false, x: 100, y: 200 }, 30); expect(short).toMatchObject({ x: 100, y: 200, width: 64 + 21, height: JAVA_LABEL_FONT_HEIGHT + 94 + 5, icon: 'server' }); // The icon at the top, in the middle; the label's baseline under it, in the middle. expect(short.iconRect).toEqual({ x: 100 + (85 - 64) / 2, y: 200, width: 64, height: 94 }); expect(short.label).toEqual({ x: 100 + 85 / 2, y: 200 + 94 + 14 }); const long = deviceBox({ kind: 'router', cloud: false, x: 0, y: 0 }, 124.6); expect(long.width).toBe(125 + 21); expect(long.iconRect.x).toBe((146 - 77) / 2); }); it('meets cables in the middle of the button, in whole pixels as Java does', () => { const box = deviceBox({ kind: 'notebook', cloud: false, x: 11, y: 7 }, 10); // 84 + 21 = 105 wide, 17 + 80 + 5 = 102 high. expect(box.center).toEqual({ x: Math.trunc(11 + 52.5), y: Math.trunc(7 + 51) }); }); it("draws a cable as JCablePanel's curve", () => { // Rising to the right (y falls): the control point a quarter across the panel. // Panel from (98, 48); control (98 + trunc((2 + 302) / 4), 48 + trunc((52 + 2) / 4)) = (174, 61). expect(cablePath({ x: 100, y: 100 }, { x: 400, y: 50 })).toBe('M 100 100 Q 174 61 400 50'); // Falling to the right: three quarters across. expect(cablePath({ x: 100, y: 50 }, { x: 400, y: 100 })).toBe(`M 100 50 Q ${98 + 3 * Math.trunc(304 / 4)} 61 400 100`); // The same either way round. expect(cablePath({ x: 400, y: 100 }, { x: 100, y: 50 })).toBe(`M 400 100 Q ${98 + 3 * Math.trunc(304 / 4)} 61 100 50`); // Straight down: not falling (x does not change); the panel from (8, 8), control (8 + trunc(4 / 4), 8 + trunc(84 / 4)). expect(cablePath({ x: 10, y: 10 }, { x: 10, y: 90 })).toBe('M 10 10 Q 9 29 10 90'); }); it('knows every icon it draws', () => { expect(Object.keys(ICONS).sort()).toEqual(['cloud', 'gateway', 'laptop', 'modem', 'router', 'server', 'switch']); }); it('spans the rectangles around everything', () => { expect(bounds([])).toEqual({ x: 0, y: 0, width: 0, height: 0 }); expect(bounds([{ x: 10, y: 20, width: 5, height: 5 }, { x: -5, y: 30, width: 10, height: 10 }])).toEqual({ x: -5, y: 20, width: 20, height: 20 }); }); });