github.com/derat/nup@v0.0.0-20230418113745-15592ba7c620/test/web/unit/common.test.js (about) 1 // Copyright 2021 Daniel Erat. 2 // All rights reserved. 3 4 import { expectEq, error, fatal, suite, test } from './test.js'; 5 import { 6 createElement, 7 formatDuration, 8 formatRelativeTime, 9 getRatingString, 10 moveItem, 11 wrapString, 12 } from './common.js'; 13 14 suite('common', () => { 15 test('createElement', () => { 16 const p = createElement('p', 'foo bar', null, 'Hi there'); 17 expectEq(p.nodeName, 'P', 'nodeName'); 18 expectEq(p.className, 'foo bar', 'className'); 19 expectEq(p.innerText, 'Hi there', 'innerText'); 20 expectEq(p.parentElement, null, 'parentElement'); 21 22 const br = createElement('br', null, p, null); 23 expectEq(br.nodeName, 'BR', 'nodeName'); 24 expectEq(br.className, '', 'className'); 25 expectEq(br.innerText, '', 'innerText'); 26 expectEq(br.parentElement, p, 'parentElement'); 27 }); 28 29 test('formatDuration', () => { 30 for (const [sec, want] of [ 31 [0, '0:00'], 32 [1, '0:01'], 33 [59, '0:59'], 34 [60, '1:00'], 35 [61, '1:01'], 36 [599, '9:59'], 37 [600, '10:00'], 38 [601, '10:01'], 39 [3599, '59:59'], 40 [3600, '60:00'], 41 [3601, '60:01'], 42 ]) { 43 const got = formatDuration(sec); 44 if (got !== want) { 45 error(`formatDuration(${sec}) = "${got}"; want "${want}"`); 46 } 47 } 48 }); 49 50 test('formatRelativeTime', () => { 51 for (const [sec, wantBase] of [ 52 [0, '0 seconds'], 53 [1, '1 second'], 54 [1.49, '1 second'], 55 [1.51, '2 seconds'], // -1.5 rounds to -1, not -2 56 [59.49, '59 seconds'], 57 [59.51, '1 minute'], 58 [60, '1 minute'], 59 [89, '1 minute'], 60 [91, '2 minutes'], 61 [3569, '59 minutes'], 62 [3571, '1 hour'], 63 [3600, '1 hour'], 64 [5399, '1 hour'], 65 [5401, '2 hours'], 66 [23 * 3600 + 1799, '23 hours'], 67 [23 * 3600 + 1801, '1 day'], 68 [86400, '1 day'], 69 [86400 + 43199, '1 day'], 70 [86400 + 43201, '2 days'], 71 ]) { 72 const gotPos = formatRelativeTime(sec); 73 const wantPos = `in ${wantBase}`; 74 if (gotPos !== wantPos) { 75 error(`formatRelativeTime(${sec}) = "${gotPos}"; want "${wantPos}"`); 76 } 77 78 if (sec !== 0) { 79 const gotNeg = formatRelativeTime(-sec); 80 const wantNeg = `${wantBase} ago`; 81 if (gotNeg !== wantNeg) { 82 error(`formatRelativeTime(${-sec}) = "${gotNeg}"; want "${wantNeg}"`); 83 } 84 } 85 } 86 }); 87 88 test('getRatingString', () => { 89 for (const [args, want] of [ 90 [[0], 'Unrated'], 91 [[1], '★☆☆☆☆'], 92 [[2], '★★☆☆☆'], 93 [[3], '★★★☆☆'], 94 [[4], '★★★★☆'], 95 [[5], '★★★★★'], 96 ]) { 97 const got = getRatingString.apply(null, args); 98 if (got !== want) { 99 error(`getRatingString(${args.join(', ')}) = ${got}; want ${want}`); 100 } 101 } 102 }); 103 104 test('moveItem', () => { 105 for (const [array, from, to, idx, wantArray, wantIdx] of [ 106 [[0, 1, 2, 3], 0, 0, 0, [0, 1, 2, 3], 0], 107 [[0, 1, 2, 3], 0, 1, 0, [1, 0, 2, 3], 1], 108 [[0, 1, 2, 3], 0, 2, 1, [1, 2, 0, 3], 0], 109 [[0, 1, 2, 3], 0, 3, 1, [1, 2, 3, 0], 0], 110 [[0, 1, 2, 3], 0, 3, 3, [1, 2, 3, 0], 2], 111 [[0, 1, 2, 3], 1, 0, 0, [1, 0, 2, 3], 1], 112 [[0, 1, 2, 3], 3, 0, 2, [3, 0, 1, 2], 3], 113 [[0, 1, 2, 3], 2, 1, 1, [0, 2, 1, 3], 2], 114 [[0, 1, 2, 3], 2, 1, undefined, [0, 2, 1, 3], undefined], 115 ]) { 116 const gotArray = array.slice(); 117 const gotIdx = moveItem(gotArray, from, to, idx); 118 const desc = `moveItem([${array.join(',')}], ${from}, ${to}, ${idx})`; 119 expectEq(gotArray, wantArray, desc); 120 expectEq(gotIdx, wantIdx, desc); 121 } 122 }); 123 124 test('wrapString', () => { 125 for (const [orig, max, want] of [ 126 ['abc def', 7, 'abc def'], 127 ['abc def', 3, 'abc\ndef'], 128 ['abc\n\ndef ghijklmno', 7, 'abc\n\ndef\nghijklmno'], 129 ]) { 130 const got = wrapString(orig, max); 131 const desc = `wrapString("${orig}", ${max})`; 132 expectEq(got, want, desc); 133 } 134 }); 135 });