import assert from 'assert'; import { boundFlags, ltrb, xy, printBounds } from '../common'; import { WindowWidget } from '../window'; import { Widget } from '../widget'; describe('Widget', () => { describe('#minSize', () => { it('should be padding only for an empty widget', () => { const w = WindowWidget.make({ name: 'window' }); const empty = Widget.make(w, { name: 'empty', data: { padding: ltrb(2, 4, 2, 4) } }); assert.equal(empty.minSizeX(), 4); assert.equal(empty.minSizeY(), 8); }); it('should be padding + minSize for an empty widget with minimum size', () => { const w = WindowWidget.make({ name: 'window' }); const empty = Widget.make(w, { name: 'empty', data: { padding: ltrb(2, 4, 2, 4), minSize: xy(20, 4) } }); assert.equal(empty.minSizeX(), 24); assert.equal(empty.minSizeY(), 12); }); it('should be padding + content for a non-empty widget with larger content than minSize', () => { const w = WindowWidget.make({ name: 'window' }); const a = Widget.make(w, { name: 'container', data: { padding: ltrb(10, 10, 10, 10), minSize: xy(20, 20) } }); const b = Widget.make(a, { name: 'inside', data: { minSize: xy(30, 30) } }) assert.equal(a.minSizeX(), 50); assert.equal(a.minSizeY(), 50); }); it('should be padding + minSize for a non-empty widget with smaller content than minSize', () => { const w = WindowWidget.make({ name: 'window' }); const a = Widget.make(w, { name: 'container', data: { padding: ltrb(10, 10, 10, 10), minSize: xy(20, 20) } }); const b = Widget.make(a, { name: 'inside', data: { minSize: xy(10, 10) } }) assert.equal(a.minSizeX(), 40); assert.equal(a.minSizeY(), 40); }); }); describe('#getGlobalBounds', () => { it('should be the window\'s position and size for any window widget', () => { const w = WindowWidget.make({ name: 'window', data: { pos: xy(2, 2), size: xy(28, 28) } }); w.update(); assert.equal(w.getGlobalBounds().left, 2); assert.equal(w.getGlobalBounds().top, 2); assert.equal(w.getGlobalBounds().right, 30); assert.equal(w.getGlobalBounds().bottom, 30); }); it('should be the same as the window\'s, for a single sticky widget', () => { const w = WindowWidget.make({ name: 'window', data: { pos: xy(2, 2), size: xy(28, 28) } }); const a = Widget.make(w, { data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(0, 0), cellSize: xy(1, 1) } } }); w.update(); assert.equal(a.getGlobalBounds().left, 2); assert.equal(a.getGlobalBounds().top, 2); assert.equal(a.getGlobalBounds().right, 30); assert.equal(a.getGlobalBounds().bottom, 30); }); it('should be the same as a centered minSize, for a single, non-sticky widget', () => { const w = WindowWidget.make({ name: 'window', data: { pos: xy(0, 0), size: xy(30, 30) } }); const a = Widget.make(w, { data: { minSize: xy(10, 10) } }); w.update(); assert.equal(a.getGlobalBounds().left, 10); assert.equal(a.getGlobalBounds().top, 10); assert.equal(a.getGlobalBounds().right, 20); assert.equal(a.getGlobalBounds().bottom, 20); }); it('should be shifted, for a single widget in a shifted window', () => { const w = WindowWidget.make({ name: 'window', data: { pos: xy(10, 10), size: xy(30, 30) } }); const a = Widget.make(w, { data: { minSize: xy(10, 10) } }); w.update(); assert.equal(a.getGlobalBounds().left, 10 + 10); assert.equal(a.getGlobalBounds().top, 10 + 10); assert.equal(a.getGlobalBounds().right, 20 + 10); assert.equal(a.getGlobalBounds().bottom, 20 + 10); }); it('should be the same as a centered minSize, except for left, for a single, left-sticky widget', () => { const w = WindowWidget.make({ name: 'window', data: { pos: xy(0, 0), size: xy(30, 30) } }); const a = Widget.make(w, { data: { layout: { sticky: boundFlags('l'), cellPos: xy(0, 0), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); w.update(); assert.equal(a.getGlobalBounds().left, 0); assert.equal(a.getGlobalBounds().top, 10); assert.equal(a.getGlobalBounds().right, 20); assert.equal(a.getGlobalBounds().bottom, 20); }); it('should be half the width for a widget that shares its parent horizontally', () => { const w = WindowWidget.make({ name: 'window', data: { pos: xy(10, 10), size: xy(30, 30) } }); const a = Widget.make(w, { name: 'left', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(0, 0), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); const b = Widget.make(w, { name: 'right', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(1, 0), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); w.update(); assert.equal(a.getGlobalBounds().left, 10 + 0); assert.equal(a.getGlobalBounds().top, 10 + 0); assert.equal(a.getGlobalBounds().right, 10 + 15); assert.equal(a.getGlobalBounds().bottom, 10 + 30); assert.equal(b.getGlobalBounds().left, 10 + 15); assert.equal(b.getGlobalBounds().top, 10 + 0); assert.equal(b.getGlobalBounds().right, 10 + 30); assert.equal(b.getGlobalBounds().bottom, 10 + 30); }); it('should be half the height for a widget that shares its parent vertically', () => { const w = WindowWidget.make({ name: 'window', data: { pos: xy(10, 10), size: xy(30, 30) } }); const a = Widget.make(w, { name: 'left', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(0, 0), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); const b = Widget.make(w, { name: 'right', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(0, 1), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); w.update(); assert.equal(a.getGlobalBounds().left, 10 + 0); assert.equal(a.getGlobalBounds().top, 10 + 0); assert.equal(a.getGlobalBounds().right, 10 + 30); assert.equal(a.getGlobalBounds().bottom, 10 + 15); assert.equal(b.getGlobalBounds().left, 10 + 0); assert.equal(b.getGlobalBounds().top, 10 + 15); assert.equal(b.getGlobalBounds().right, 10 + 30); assert.equal(b.getGlobalBounds().bottom, 10 + 30); }); it('should be half the width and height for a widget that shares its parent diagonally', () => { const w = WindowWidget.make({ name: 'window', data: { pos: xy(10, 10), size: xy(30, 30) } }); const a = Widget.make(w, { name: 'left', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(0, 0), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); const b = Widget.make(w, { name: 'right', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(1, 1), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); w.update(); assert.equal(a.getGlobalBounds().left, 10 + 0); assert.equal(a.getGlobalBounds().top, 10 + 0); assert.equal(a.getGlobalBounds().right, 10 + 15); assert.equal(a.getGlobalBounds().bottom, 10 + 15); assert.equal(b.getGlobalBounds().left, 10 + 15); assert.equal(b.getGlobalBounds().top, 10 + 15); assert.equal(b.getGlobalBounds().right, 10 + 30); assert.equal(b.getGlobalBounds().bottom, 10 + 30); }); it('should skip empty rows and columns', () => { const w = WindowWidget.make({ name: 'window', data: { pos: xy(10, 10), size: xy(30, 30) } }); const a = Widget.make(w, { name: 'left', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(0, 0), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); const b = Widget.make(w, { name: 'right', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(20, 20), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); w.update(); assert.equal(a.getGlobalBounds().left, 10 + 0); assert.equal(a.getGlobalBounds().top, 10 + 0); assert.equal(a.getGlobalBounds().right, 10 + 15); assert.equal(a.getGlobalBounds().bottom, 10 + 15); assert.equal(b.getGlobalBounds().left, 10 + 15); assert.equal(b.getGlobalBounds().top, 10 + 15); assert.equal(b.getGlobalBounds().right, 10 + 30); assert.equal(b.getGlobalBounds().bottom, 10 + 30); }); it('should inherit its position from widget to widget', () => { const w = WindowWidget.make({ name: 'window', data: { pos: xy(10, 10), size: xy(40, 40) } }); const a = Widget.make(w, { name: 'left', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(0, 0), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); const b = Widget.make(w, { name: 'right', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(1, 1), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); const c = Widget.make(b, { name: 'inner', data: { minSize: xy(10, 10) } }); w.update(); assert.equal(c.getGlobalBounds().left, 10 + 25); assert.equal(c.getGlobalBounds().top, 10 + 25); assert.equal(c.getGlobalBounds().right, 10 + 35); assert.equal(c.getGlobalBounds().bottom, 10 + 35); }); it('should inherit its position from widget to widget, and still be able to share space', () => { const w = WindowWidget.make({ name: 'window', data: { pos: xy(10, 10), size: xy(80, 80) } }); const a = Widget.make(w, { name: 'left', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(0, 0), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); const b = Widget.make(w, { name: 'right', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(1, 1), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); const c = Widget.make(b, { name: 'inner left', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(0, 1), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); const d = Widget.make(b, { name: 'inner right', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(1, 1), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); w.update(); assert.equal(c.getGlobalBounds().left, 10 + 40); assert.equal(c.getGlobalBounds().top, 10 + 40); assert.equal(c.getGlobalBounds().right, 10 + 60); assert.equal(c.getGlobalBounds().bottom, 10 + 80); assert.equal(d.getGlobalBounds().left, 10 + 60); assert.equal(d.getGlobalBounds().top, 10 + 40); assert.equal(d.getGlobalBounds().right, 10 + 80); assert.equal(d.getGlobalBounds().bottom, 10 + 80); }); it('should inherit its position from widget to widget, and still be able to exclude padding', () => { const w = WindowWidget.make({ name: 'window', data: { pos: xy(10, 10), size: xy(80, 80) } }); const a = Widget.make(w, { name: 'left', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(0, 0), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); const b = Widget.make(w, { name: 'right', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(1, 1), cellSize: xy(1, 1) }, minSize: xy(10, 10), padding: ltrb(5, 5, 5, 5) } }); const c = Widget.make(b, { name: 'inner left', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(0, 1), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); const d = Widget.make(b, { name: 'inner right', data: { layout: { sticky: boundFlags('nswe'), cellPos: xy(1, 1), cellSize: xy(1, 1) }, minSize: xy(10, 10) } }); w.update(); assert.equal(c.getGlobalBounds().left, 10 + 40 + 5); assert.equal(c.getGlobalBounds().top, 10 + 40 + 5); assert.equal(c.getGlobalBounds().right, 10 + 60); assert.equal(c.getGlobalBounds().bottom, 10 + 80 - 5); assert.equal(d.getGlobalBounds().left, 10 + 60); assert.equal(d.getGlobalBounds().top, 10 + 40 + 5); assert.equal(d.getGlobalBounds().right, 10 + 80 - 5); assert.equal(d.getGlobalBounds().bottom, 10 + 80 - 5); }); }); });