MIRROR: javascript for 🐜's, a tiny runtime with big ambitions
1
fork

Configure Feed

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

at master 142 lines 5.4 kB view raw
1import { test, testDeep, summary } from './helpers.js'; 2 3console.log('String Tests\n'); 4 5let str = 'hello world'; 6test('indexOf found', str.indexOf('world'), 6); 7test('indexOf first occurrence', str.indexOf('o'), 4); 8test('indexOf not found', str.indexOf('xyz'), -1); 9test('indexOf empty string', str.indexOf(''), 0); 10 11let js = 'JavaScript'; 12test('substring start end', js.substring(0, 4), 'Java'); 13test('substring start only', js.substring(4), 'Script'); 14test('substring swaps if end < start', js.substring(10, 4), 'Script'); 15 16let fox = 'The quick brown fox'; 17test('slice start end', fox.slice(0, 3), 'The'); 18test('slice start only', fox.slice(10), 'brown fox'); 19test('slice negative start', fox.slice(-3), 'fox'); 20test('slice negative end', fox.slice(0, -4), 'The quick brown'); 21 22let csv = 'apple,banana,cherry'; 23let parts = csv.split(','); 24test('split length', parts.length, 3); 25test('split first', parts[0], 'apple'); 26test('split last', parts[2], 'cherry'); 27 28let chars = 'hello'.split(''); 29test('split empty', chars.length, 5); 30test('split empty first', chars[0], 'h'); 31 32test('includes true', 'quick brown fox'.includes('quick'), true); 33test('includes false', 'quick brown fox'.includes('cat'), false); 34test('includes empty', 'hello'.includes(''), true); 35 36test('startsWith true', 'Hello, World!'.startsWith('Hello'), true); 37test('startsWith false', 'Hello, World!'.startsWith('World'), false); 38 39test('endsWith true', 'index.html'.endsWith('.html'), true); 40test('endsWith false', 'index.html'.endsWith('.js'), false); 41 42test('toUpperCase', 'hello'.toUpperCase(), 'HELLO'); 43test('toLowerCase', 'HELLO'.toLowerCase(), 'hello'); 44 45test('trim', ' hello '.trim(), 'hello'); 46test('trimStart', ' hello'.trimStart(), 'hello'); 47test('trimEnd', 'hello '.trimEnd(), 'hello'); 48 49test('padStart', '5'.padStart(3, '0'), '005'); 50test('padEnd', '5'.padEnd(3, '0'), '500'); 51 52test('repeat', 'ab'.repeat(3), 'ababab'); 53 54test('charAt', 'hello'.charAt(1), 'e'); 55test('charAt default index', 'hello'.charAt(), 'h'); 56test('charAt coercion', 'hello'.charAt('1'), 'e'); 57test('charCodeAt', 'ABC'.charCodeAt(0), 65); 58test('charCodeAt default index', 'ABC'.charCodeAt(), 65); 59test('charCodeAt coercion', 'ABC'.charCodeAt('1'), 66); 60test('codePointAt ascii', 'ABC'.codePointAt(0), 65); 61test('codePointAt default index', 'ABC'.codePointAt(), 65); 62test('codePointAt coercion', 'ABC'.codePointAt('1'), 66); 63test('codePointAt out of bounds', 'ABC'.codePointAt(10), undefined); 64test('codePointAt utf8 2-byte', 'é'.codePointAt(0), 233); 65test('codePointAt utf8 3-byte', '中'.codePointAt(0), 20013); 66test('codePointAt utf8 4-byte', '😀'.codePointAt(0), 128512); 67test('charAt astral leading surrogate', '💙'.charAt(0).charCodeAt(0), 0xD83D); 68test('charAt astral trailing surrogate', '💙'.charAt(1).charCodeAt(0), 0xDC99); 69 70test('replace', 'hello world'.replace('world', 'there'), 'hello there'); 71test('replaceAll', 'a-b-c'.replaceAll('-', '_'), 'a_b_c'); 72 73test( 74 'template missing placeholders stay empty', 75 'Hello, {{name}}. Missing: {{missing}}.'.template({ name: 'Ant' }), 76 'Hello, Ant. Missing: .' 77); 78test( 79 'template placeholder values use normal string coercion', 80 '{{nil}}/{{undef}}/{{obj}}/{{arr}}/{{ok}}'.template({ 81 nil: null, 82 undef: undefined, 83 obj: { toString() { return 'custom'; } }, 84 arr: [1, 2], 85 ok: false 86 }), 87 'null/undefined/custom/1,2/false' 88); 89test( 90 'template unterminated placeholders remain literal', 91 'before {{name after'.template({ name: 'ignored' }), 92 'before {{name after' 93); 94 95testDeep('match', 'test123'.match(/\d+/), ['123']); 96 97test('at positive', 'hello'.at(1), 'e'); 98test('at negative', 'hello'.at(-1), 'o'); 99 100test('length', 'hello'.length, 5); 101test('bracket access', 'hello'[0], 'h'); 102test('bracket access astral leading surrogate', '💙'[0].charCodeAt(0), 0xD83D); 103test('bracket access astral trailing surrogate', '💙'[1].charCodeAt(0), 0xDC99); 104 105test('concat', 'hello'.concat(' ', 'world'), 'hello world'); 106 107test('lastIndexOf', 'hello world world'.lastIndexOf('world'), 12); 108 109test('String.fromCharCode', String.fromCharCode(65, 66, 67), 'ABC'); 110test('String.raw tagged template', String.raw`line1\nline2`, 'line1\\nline2'); 111test('String.raw substitutions', String.raw({ raw: ['a', 'b', 'c'] }, 1, 2), 'a1b2c'); 112 113test('empty string length', ''.length, 0); 114test('empty indexOf', ''.indexOf('x'), -1); 115test('empty includes empty', ''.includes(''), true); 116test('empty startsWith empty', ''.startsWith(''), true); 117 118let nfc = '\u0041\u006d\u0065\u0301\u006c\u0069\u0065'; 119test('normalize default (NFC)', nfc.normalize(), 'Am\u00E9lie'); 120test('normalize NFC explicit', nfc.normalize('NFC'), 'Am\u00E9lie'); 121 122let composed = 'Am\u00E9lie'; 123test('normalize NFD', composed.normalize('NFD'), 'Ame\u0301lie'); 124 125test('normalize NFKC fi ligature', '\uFB01'.normalize('NFKC'), 'fi'); 126test('normalize NFKC fullwidth', '\uFF21'.normalize('NFKC'), 'A'); 127 128test('normalize NFKD fi ligature', '\uFB01'.normalize('NFKD'), 'fi'); 129test('normalize NFKD fullwidth', '\uFF21'.normalize('NFKD'), 'A'); 130 131test('normalize empty string', ''.normalize(), ''); 132test('normalize ascii passthrough', 'hello'.normalize(), 'hello'); 133test('normalize no arg same as NFC', '\u00E9'.normalize(), '\u00E9'); 134 135let template = `Value: ${1 + 2}`; 136test('template literal', template, 'Value: 3'); 137 138let multi = `line1 139line2`; 140test('multiline template', multi.includes('\n'), true); 141 142summary();