your personal website on atproto - mirror blento.app
25
fork

Configure Feed

Select the types of activity you want to include in your feed.

at fix/layout-stuff 184 lines 6.1 kB view raw
1import { describe, it, expect, vi } from 'vitest'; 2import type { Item } from '$lib/types'; 3 4// Mock CardDefinitionsByType — tests don't need real card definitions 5vi.mock('$lib/cards', () => ({ 6 CardDefinitionsByType: {} 7})); 8 9import { mirrorItemSize, mirrorLayout, shouldMirror } from './mirror'; 10 11function makeItem(overrides: Partial<Item> & { id: string }): Item { 12 return { 13 w: 2, 14 h: 2, 15 x: 0, 16 y: 0, 17 mobileW: 4, 18 mobileH: 4, 19 mobileX: 0, 20 mobileY: 0, 21 cardType: 'text', 22 cardData: {}, 23 ...overrides 24 }; 25} 26 27describe('shouldMirror', () => { 28 it('mirrors when editedOn is 0 (never edited) and no layoutMode', () => { 29 expect(shouldMirror(0, undefined, false)).toBe(true); 30 expect(shouldMirror(0, undefined, true)).toBe(true); 31 }); 32 33 it('mirrors when only one layout edited and no layoutMode', () => { 34 expect(shouldMirror(1, undefined, false)).toBe(true); 35 expect(shouldMirror(2, undefined, true)).toBe(true); 36 }); 37 38 it('does not mirror when both layouts edited and no layoutMode', () => { 39 expect(shouldMirror(3, undefined, false)).toBe(false); 40 expect(shouldMirror(3, undefined, true)).toBe(false); 41 }); 42 43 it('desktop-leads: mirrors only when editing desktop', () => { 44 expect(shouldMirror(3, 'desktop-leads', false)).toBe(true); 45 expect(shouldMirror(3, 'desktop-leads', true)).toBe(false); 46 }); 47 48 it('mobile-leads: mirrors only when editing mobile', () => { 49 expect(shouldMirror(3, 'mobile-leads', true)).toBe(true); 50 expect(shouldMirror(3, 'mobile-leads', false)).toBe(false); 51 }); 52 53 it('independent: never mirrors', () => { 54 expect(shouldMirror(0, 'independent', false)).toBe(false); 55 expect(shouldMirror(0, 'independent', true)).toBe(false); 56 }); 57}); 58 59describe('mirrorItemSize', () => { 60 it('desktop → mobile: doubles dimensions', () => { 61 const item = makeItem({ id: 'a', w: 3, h: 2 }); 62 mirrorItemSize(item, false); 63 expect(item.mobileW).toBe(6); 64 expect(item.mobileH).toBe(4); 65 }); 66 67 it('desktop → mobile: caps width at COLUMNS (8)', () => { 68 const item = makeItem({ id: 'a', w: 6, h: 2 }); 69 mirrorItemSize(item, false); 70 expect(item.mobileW).toBe(8); 71 expect(item.mobileH).toBe(4); 72 }); 73 74 it('mobile → desktop: halves dimensions with snap-even', () => { 75 const item = makeItem({ id: 'a', mobileW: 6, mobileH: 4 }); 76 mirrorItemSize(item, true); 77 // snapEven(6/2) = snapEven(3) = max(2, round(1.5)*2) = max(2, 4) = 4 78 expect(item.w).toBe(4); 79 expect(item.h).toBe(2); 80 }); 81 82 it('mobile → desktop: exact halves', () => { 83 const item = makeItem({ id: 'a', mobileW: 4, mobileH: 4 }); 84 mirrorItemSize(item, true); 85 // snapEven(4/2) = snapEven(2) = max(2, round(1)*2) = 2 86 expect(item.w).toBe(2); 87 expect(item.h).toBe(2); 88 }); 89 90 it('mobile → desktop: minimum width is 2', () => { 91 const item = makeItem({ id: 'a', mobileW: 2, mobileH: 2 }); 92 mirrorItemSize(item, true); 93 expect(item.w).toBe(2); // snapEven(1) = max(2, round(0.5)*2) = max(2, 1*2) = 2 94 expect(item.h).toBe(1); // round(2/2) = 1 95 }); 96}); 97 98describe('mirrorLayout desktop → mobile', () => { 99 it('two items that fit side-by-side on mobile stay side-by-side', () => { 100 // Two 2-wide items next to each other on desktop → 4-wide on mobile, should fit in 8 cols 101 const a = makeItem({ id: 'a', x: 0, y: 0, w: 2, h: 2 }); 102 const b = makeItem({ id: 'b', x: 2, y: 0, w: 2, h: 2 }); 103 const items = [a, b]; 104 105 mirrorLayout(items, false); 106 107 // Both should be on the same row 108 expect(a.mobileY).toBe(b.mobileY); 109 // They should not overlap 110 expect(a.mobileX + a.mobileW).toBeLessThanOrEqual(b.mobileX); 111 }); 112 113 it('preserves reading order', () => { 114 const a = makeItem({ id: 'a', x: 0, y: 0, w: 4, h: 2 }); 115 const b = makeItem({ id: 'b', x: 4, y: 0, w: 4, h: 2 }); 116 const c = makeItem({ id: 'c', x: 0, y: 2, w: 4, h: 2 }); 117 const items = [a, b, c]; 118 119 mirrorLayout(items, false); 120 121 // a and b are on the same desktop row but become full-width on mobile (8 cols each) 122 // So they must stack. a should come before b, and b before c. 123 expect(a.mobileY).toBeLessThan(b.mobileY); 124 expect(b.mobileY).toBeLessThan(c.mobileY); 125 }); 126 127 it('does not leave gaps when items fit next to each other', () => { 128 // Three 2-wide items on one desktop row → 4-wide on mobile, two fit per row 129 const a = makeItem({ id: 'a', x: 0, y: 0, w: 2, h: 2 }); 130 const b = makeItem({ id: 'b', x: 2, y: 0, w: 2, h: 2 }); 131 const c = makeItem({ id: 'c', x: 4, y: 0, w: 2, h: 2 }); 132 const items = [a, b, c]; 133 134 mirrorLayout(items, false); 135 136 // a and b should be on the same row 137 expect(a.mobileY).toBe(b.mobileY); 138 // c should be on the next row (only 4 cols left isn't enough... wait, 8 - 4 - 4 = 0) 139 // Actually a(4) + b(4) = 8, c must go to next row 140 expect(c.mobileY).toBe(a.mobileY + a.mobileH); 141 // c should start at x=0 142 expect(c.mobileX).toBe(0); 143 }); 144 145 it('full-width items stack vertically', () => { 146 const a = makeItem({ id: 'a', x: 0, y: 0, w: 8, h: 2 }); 147 const b = makeItem({ id: 'b', x: 0, y: 2, w: 8, h: 2 }); 148 const items = [a, b]; 149 150 mirrorLayout(items, false); 151 152 expect(a.mobileW).toBe(8); 153 expect(b.mobileW).toBe(8); 154 expect(a.mobileY).toBe(0); 155 expect(b.mobileY).toBe(a.mobileH); 156 }); 157}); 158 159describe('mirrorLayout mobile → desktop', () => { 160 it('two mobile items that fit side-by-side on desktop stay side-by-side', () => { 161 const a = makeItem({ id: 'a', mobileX: 0, mobileY: 0, mobileW: 4, mobileH: 4 }); 162 const b = makeItem({ id: 'b', mobileX: 4, mobileY: 0, mobileW: 4, mobileH: 4 }); 163 const items = [a, b]; 164 165 mirrorLayout(items, true); 166 167 // Both should be on the same desktop row 168 expect(a.y).toBe(b.y); 169 expect(a.x + a.w).toBeLessThanOrEqual(b.x); 170 }); 171 172 it('preserves reading order from mobile layout', () => { 173 const a = makeItem({ id: 'a', mobileX: 0, mobileY: 0, mobileW: 8, mobileH: 4 }); 174 const b = makeItem({ id: 'b', mobileX: 0, mobileY: 4, mobileW: 8, mobileH: 4 }); 175 const c = makeItem({ id: 'c', mobileX: 0, mobileY: 8, mobileW: 8, mobileH: 4 }); 176 const items = [a, b, c]; 177 178 mirrorLayout(items, true); 179 180 // a before b before c in desktop Y 181 expect(a.y).toBeLessThanOrEqual(b.y); 182 expect(b.y).toBeLessThanOrEqual(c.y); 183 }); 184});