Something went wrong. Try again.
MIRROR: javascript for 🐜's, a tiny runtime with big ambitions ant.themackabu.dev
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434import { test, testThrows, summary } from './helpers.js';import * as buffer from 'node:buffer';
console.log('Buffer Tests\n');
const ab = new ArrayBuffer(16);test('ArrayBuffer byteLength', ab.byteLength, 16);
const ab2 = ab.slice(4, 12);test('ArrayBuffer slice byteLength', ab2.byteLength, 8);
const u8 = new Uint8Array(8);test('Uint8Array length', u8.length, 8);test('Uint8Array byteLength', u8.byteLength, 8);test('Uint8Array BYTES_PER_ELEMENT', u8.BYTES_PER_ELEMENT, 1);test('Uint8Array constructor', u8.constructor, Uint8Array);test('Uint8Array with new', new Uint8Array(5).length, 5);test('Uint8Array via Reflect.construct', Reflect.construct(Uint8Array, [5]).length, 5);testThrows('Uint8Array without new throws', () => Uint8Array(5));
const typedArrayCtor = Object.getPrototypeOf(Int8Array);const typedArrayTagDesc = Object.getOwnPropertyDescriptor(typedArrayCtor.prototype, Symbol.toStringTag);test('TypedArray constructors share abstract parent', typedArrayCtor === Function.prototype, false);test('TypedArray shared toStringTag getter', typeof typedArrayTagDesc.get, 'function');test('TypedArray toStringTag value', new Int8Array(1)[Symbol.toStringTag], 'Int8Array');
const i16 = new Int16Array(4);test('Int16Array length', i16.length, 4);test('Int16Array byteLength', i16.byteLength, 8);test('Int16Array BYTES_PER_ELEMENT', i16.BYTES_PER_ELEMENT, 2);
const i32 = new Int32Array(2);test('Int32Array length', i32.length, 2);test('Int32Array byteLength', i32.byteLength, 8);test('Int32Array BYTES_PER_ELEMENT', i32.BYTES_PER_ELEMENT, 4);
const f32 = new Float32Array(4);test('Float32Array length', f32.length, 4);test('Float32Array byteLength', f32.byteLength, 16);test('Float32Array BYTES_PER_ELEMENT', f32.BYTES_PER_ELEMENT, 4);
const f64 = new Float64Array(2);test('Float64Array length', f64.length, 2);test('Float64Array byteLength', f64.byteLength, 16);test('Float64Array BYTES_PER_ELEMENT', f64.BYTES_PER_ELEMENT, 8);
const u16 = new Uint16Array(4);test('Uint16Array length', u16.length, 4);test('Uint16Array BYTES_PER_ELEMENT', u16.BYTES_PER_ELEMENT, 2);
const u32 = new Uint32Array(2);test('Uint32Array length', u32.length, 2);test('Uint32Array BYTES_PER_ELEMENT', u32.BYTES_PER_ELEMENT, 4);
const wrapI32 = new Int32Array(1);wrapI32[0] = 0x80000000;test('Int32Array wraps int32 writes', wrapI32[0], -0x80000000);
const wrapU32 = new Uint32Array(1);wrapU32[0] = 0x100000000;test('Uint32Array wraps uint32 writes', wrapU32[0], 0);
const f16 = new Float16Array(4);test('Float16Array length', f16.length, 4);test('Float16Array byteLength', f16.byteLength, 8);test('Float16Array BYTES_PER_ELEMENT', f16.BYTES_PER_ELEMENT, 2);test('Float16Array constructor', f16.constructor, Float16Array);f16[0] = 1.5;f16[1] = -0.5;test('Float16Array index read approx positive', Math.abs(f16[0] - 1.5) < 0.001, true);test('Float16Array index read approx negative', Math.abs(f16[1] + 0.5) < 0.001, true);
const i8 = new Int8Array(8);test('Int8Array length', i8.length, 8);test('Int8Array BYTES_PER_ELEMENT', i8.BYTES_PER_ELEMENT, 1);
const u8c = new Uint8ClampedArray(8);test('Uint8ClampedArray length', u8c.length, 8);test('Uint8ClampedArray BYTES_PER_ELEMENT', u8c.BYTES_PER_ELEMENT, 1);
const clampU8 = new Uint8ClampedArray(1);clampU8[0] = 0x100;test('Uint8ClampedArray clamps writes', clampU8[0], 0xff);
const bi64 = new BigInt64Array(2);test('BigInt64Array length', bi64.length, 2);test('BigInt64Array BYTES_PER_ELEMENT', bi64.BYTES_PER_ELEMENT, 8);
const bu64 = new BigUint64Array(2);test('BigUint64Array length', bu64.length, 2);test('BigUint64Array BYTES_PER_ELEMENT', bu64.BYTES_PER_ELEMENT, 8);
const backingBuffer = new ArrayBuffer(16);const view8 = new Uint8Array(backingBuffer);const view16 = new Uint16Array(backingBuffer);const view32 = new Uint32Array(backingBuffer);const view16f = new Float16Array(backingBuffer);
test('Uint8Array view length', view8.length, 16);test('Uint16Array view length', view16.length, 8);test('Uint32Array view length', view32.length, 4);test('Float16Array view length', view16f.length, 8);
const viewWithOffset = new Uint8Array(backingBuffer, 4);test('view with offset length', viewWithOffset.length, 12);test('view with offset byteOffset', viewWithOffset.byteOffset, 4);
const viewWithOffsetAndLength = new Uint8Array(backingBuffer, 4, 8);test('view offset+length length', viewWithOffsetAndLength.length, 8);test('view offset+length byteOffset', viewWithOffsetAndLength.byteOffset, 4);
const dv = new DataView(backingBuffer);test('DataView byteLength', dv.byteLength, 16);test('DataView byteOffset', dv.byteOffset, 0);
const dv2 = new DataView(backingBuffer, 4);test('DataView offset byteLength', dv2.byteLength, 12);test('DataView offset byteOffset', dv2.byteOffset, 4);
const dv3 = new DataView(backingBuffer, 4, 8);test('DataView offset+length byteLength', dv3.byteLength, 8);test('DataView offset+length byteOffset', dv3.byteOffset, 4);
dv.setUint8(0, 42);test('DataView set/get Uint8', dv.getUint8(0), 42);
dv.setUint8(0, 0x12);dv.setUint8(1, 0x34);test('DataView Int16 LE', dv.getInt16(0, true), 0x3412);test('DataView Int16 BE', dv.getInt16(0, false), 0x1234);
const buf1 = Buffer.alloc(10);test('Buffer.alloc length', buf1.length, 10);
const buf2 = Buffer.from('Hello');test('Buffer.from string length', buf2.length, 5);test('Buffer.from string toString', buf2.toString(), 'Hello');
const buf3 = Buffer.from([72, 101, 108, 108, 111]);test('Buffer.from array length', buf3.length, 5);test('Buffer.from array toString', buf3.toString(), 'Hello');
const buf4 = Buffer.alloc(10);const written = buf4.write('Hello', 0);test('Buffer write bytes', written, 5);
const buf5 = Buffer.from('Hello');test('Buffer toString hex', buf5.toString('hex'), '48656c6c6f');
const original = new Uint8Array(10);const sliced = original.slice(2, 8);test('TypedArray slice length', sliced.length, 6);
const subarrayed = original.subarray(2, 8);test('TypedArray subarray length', subarrayed.length, 6);test('TypedArray subarray byteOffset', subarrayed.byteOffset, 2);
test('Int8Array.of length', Int8Array.of(1, 2).length, 2);test('Int8Array.of value', Int8Array.of(1, 2)[1], 2);test('Int32Array prototype BYTES_PER_ELEMENT own', Object.getOwnPropertyNames(Int32Array.prototype).includes('BYTES_PER_ELEMENT'), true);
const methodSource = new Int8Array([3, 1, 2]);test('TypedArray map result', methodSource.map(x => x + 1).join(), '4,2,3');test('TypedArray filter result', methodSource.filter(x => x > 1).join(), '3,2');test( 'TypedArray find result', methodSource.find(x => x === 1), 1);test( 'TypedArray findIndex result', methodSource.findIndex(x => x === 2), 2);
let typedForEachSum = 0;methodSource.forEach(x => (typedForEachSum += x));test('TypedArray forEach result', typedForEachSum, 6);
test( 'TypedArray reduce result', methodSource.reduce((prev, cur) => prev + cur, 0), 6);test( 'TypedArray reduceRight result', methodSource.reduceRight((prev, cur) => prev + String(cur), ''), '213');test( 'TypedArray some result', methodSource.some(x => x === 3), true);test('TypedArray lastIndexOf result', methodSource.lastIndexOf(1), 1);test('TypedArray reverse result', new Int8Array([3, 1, 2]).reverse().join(), '2,1,3');test('TypedArray sort result', new Int8Array([3, 1, 2]).sort().join(), '1,2,3');
const f16Source = new Float16Array([1.5, -0.5, 2.25, 4.5]);const f16Sliced = f16Source.slice(1, 3);test('Float16Array slice length', f16Sliced.length, 2);test('Float16Array slice first approx', Math.abs(f16Sliced[0] + 0.5) < 0.001, true);test('Float16Array slice second approx', Math.abs(f16Sliced[1] - 2.25) < 0.001, true);
const f16Cloned = structuredClone(f16Source);test('Float16Array structuredClone constructor', f16Cloned.constructor, Float16Array);test('Float16Array structuredClone distinct', f16Cloned !== f16Source, true);test('Float16Array structuredClone first approx', Math.abs(f16Cloned[0] - 1.5) < 0.001, true);test('Float16Array structuredClone second approx', Math.abs(f16Cloned[1] + 0.5) < 0.001, true);
test('Buffer.isBuffer with Buffer', Buffer.isBuffer(Buffer.from('test')), true);test('Buffer.isBuffer with string', Buffer.isBuffer('test'), false);test('Buffer.isBuffer with number', Buffer.isBuffer(123), false);test('Buffer.isBuffer with object', Buffer.isBuffer({}), false);test('Buffer.isBuffer with Uint8Array', Buffer.isBuffer(new Uint8Array(4)), false);
test('Buffer.isEncoding utf8', Buffer.isEncoding('utf8'), true);test('Buffer.isEncoding utf-8', Buffer.isEncoding('utf-8'), true);test('Buffer.isEncoding hex', Buffer.isEncoding('hex'), true);test('Buffer.isEncoding base64', Buffer.isEncoding('base64'), true);test('Buffer.isEncoding ascii', Buffer.isEncoding('ascii'), true);test('Buffer.isEncoding latin1', Buffer.isEncoding('latin1'), true);test('Buffer.isEncoding binary', Buffer.isEncoding('binary'), true);test('Buffer.isEncoding invalid', Buffer.isEncoding('invalid'), false);test('Buffer.isEncoding empty', Buffer.isEncoding(''), false);
test('Buffer.byteLength string', Buffer.byteLength('Hello'), 5);test('Buffer.byteLength buffer', Buffer.byteLength(Buffer.from('Hello')), 5);test('Buffer.byteLength empty', Buffer.byteLength(''), 0);test('buffer.constants exists', typeof buffer.constants, 'object');test('buffer.constants.MAX_STRING_LENGTH exists', typeof buffer.constants.MAX_STRING_LENGTH, 'number');test('buffer kStringMaxLength mirrors constants', buffer.kStringMaxLength, buffer.constants.MAX_STRING_LENGTH);test('buffer kMaxLength mirrors constants', buffer.kMaxLength, buffer.constants.MAX_LENGTH);
const concatBuf1 = Buffer.from('Hello');const concatBuf2 = Buffer.from(' ');const concatBuf3 = Buffer.from('World');const concatenated = Buffer.concat([concatBuf1, concatBuf2, concatBuf3]);test('Buffer.concat length', concatenated.length, 11);test('Buffer.concat toString', concatenated.toString(), 'Hello World');
const emptyConcat = Buffer.concat([]);test('Buffer.concat empty array', emptyConcat.length, 0);
const singleConcat = Buffer.concat([Buffer.from('Only')]);test('Buffer.concat single buffer', singleConcat.toString(), 'Only');
const limitedConcat = Buffer.concat([concatBuf1, concatBuf2, concatBuf3], 5);test('Buffer.concat with totalLength', limitedConcat.length, 5);test('Buffer.concat with totalLength content', limitedConcat.toString(), 'Hello');
const cmpA = Buffer.from('abc');const cmpB = Buffer.from('abc');const cmpC = Buffer.from('abd');const cmpD = Buffer.from('ab');test('Buffer.compare equal', Buffer.compare(cmpA, cmpB), 0);test('Buffer.compare less', Buffer.compare(cmpA, cmpC), -1);test('Buffer.compare greater', Buffer.compare(cmpC, cmpA), 1);test('Buffer.compare shorter', Buffer.compare(cmpD, cmpA), -1);test('Buffer.compare longer', Buffer.compare(cmpA, cmpD), 1);test('Buffer.prototype.compare less', cmpA.compare(cmpC), -1);test('Buffer.prototype.compare equal', cmpA.compare(cmpB), 0);test('Buffer.prototype.equals true', cmpA.equals(cmpB), true);test('Buffer.prototype.equals false', cmpA.equals(cmpC), false);
console.log('\nBuffer Encoding Tests\n');
const b64Buf = Buffer.from('Hello, World!');test('Buffer.toString base64', b64Buf.toString('base64'), 'SGVsbG8sIFdvcmxkIQ==');test('Buffer.toString BASE64 (case insensitive)', b64Buf.toString('BASE64'), 'SGVsbG8sIFdvcmxkIQ==');
const b64Decoded = Buffer.from('SGVsbG8sIFdvcmxkIQ==', 'base64');test('Buffer.from base64', b64Decoded.toString(), 'Hello, World!');test('Buffer.from BASE64 (case insensitive)', Buffer.from('SGVsbG8=', 'BASE64').toString(), 'Hello');
const b64Roundtrip = Buffer.from(Buffer.from('hello').toString('base64'), 'base64').toString();test('Buffer base64 roundtrip', b64Roundtrip, 'hello');
const hexBuf = Buffer.from('Hello');test('Buffer.toString hex', hexBuf.toString('hex'), '48656c6c6f');test('Buffer.toString HEX (case insensitive)', hexBuf.toString('HEX'), '48656c6c6f');test('Buffer.toString utf8 start/end', Buffer.from('ABCD').toString('utf8', 1, 3), 'BC');test('Buffer.toString hex start/end', Buffer.from([0xab, 0xcd, 0xef]).toString('hex', 1, 3), 'cdef');
const hexDecoded = Buffer.from('48656c6c6f', 'hex');test('Buffer.from hex', hexDecoded.toString(), 'Hello');test('Buffer.from HEX (case insensitive)', Buffer.from('48656C6C6F', 'HEX').toString(), 'Hello');
const hexRoundtrip = Buffer.from(Buffer.from('world').toString('hex'), 'hex').toString();test('Buffer hex roundtrip', hexRoundtrip, 'world');
const utf8Buf = Buffer.from('Hello', 'utf8');test('Buffer.from utf8', utf8Buf.toString(), 'Hello');test('Buffer.from utf-8', Buffer.from('Hello', 'utf-8').toString(), 'Hello');test('Buffer.from UTF8 (case insensitive)', Buffer.from('Hello', 'UTF8').toString(), 'Hello');test('Buffer.from UTF-8 (case insensitive)', Buffer.from('Hello', 'UTF-8').toString(), 'Hello');
test('Buffer.toString utf8', utf8Buf.toString('utf8'), 'Hello');test('Buffer.toString utf-8', utf8Buf.toString('utf-8'), 'Hello');
const asciiBuf = Buffer.from('Hello', 'ascii');test('Buffer.from ascii', asciiBuf.toString(), 'Hello');test('Buffer.from ASCII (case insensitive)', Buffer.from('Hello', 'ASCII').toString(), 'Hello');test('Buffer.toString ascii', asciiBuf.toString('ascii'), 'Hello');
const latin1Buf = Buffer.from('Hello', 'latin1');test('Buffer.from latin1', latin1Buf.toString(), 'Hello');test('Buffer.from LATIN1 (case insensitive)', Buffer.from('Hello', 'LATIN1').toString(), 'Hello');test('Buffer.from binary', Buffer.from('Hello', 'binary').toString(), 'Hello');test('Buffer.from BINARY (case insensitive)', Buffer.from('Hello', 'BINARY').toString(), 'Hello');
test('Buffer.toString latin1', latin1Buf.toString('latin1'), 'Hello');test('Buffer.toString binary', latin1Buf.toString('binary'), 'Hello');
const latin1Bytes = Buffer.from([0x80, 0x91, 0xa3, 0xff]);test('Buffer.toString latin1 preserves high bytes', latin1Bytes.toString('latin1'), '\u0080\u0091\u00A3\u00FF');test('Buffer.toString binary preserves high bytes', latin1Bytes.toString('binary'), '\u0080\u0091\u00A3\u00FF');
const ucs2Buf = Buffer.from('Hi', 'ucs2');test('Buffer.from ucs2 length', ucs2Buf.length, 4); // 2 chars * 2 bytestest('Buffer.from ucs-2 length', Buffer.from('Hi', 'ucs-2').length, 4);test('Buffer.from utf16le length', Buffer.from('Hi', 'utf16le').length, 4);test('Buffer.from utf-16le length', Buffer.from('Hi', 'utf-16le').length, 4);test('Buffer.from UCS2 (case insensitive)', Buffer.from('Hi', 'UCS2').length, 4);
test('Buffer.from ucs2 byte 0', ucs2Buf[0], 0x48);test('Buffer.from ucs2 byte 1', ucs2Buf[1], 0x00);test('Buffer.from ucs2 byte 2', ucs2Buf[2], 0x69);test('Buffer.from ucs2 byte 3', ucs2Buf[3], 0x00);
test('Buffer.toString ucs2', ucs2Buf.toString('ucs2'), 'Hi');test('Buffer.toString ucs-2', ucs2Buf.toString('ucs-2'), 'Hi');test('Buffer.toString utf16le', ucs2Buf.toString('utf16le'), 'Hi');test('Buffer.toString utf-16le', ucs2Buf.toString('utf-16le'), 'Hi');
const binaryBuf = Buffer.from([0x00, 0x01, 0x02, 0xff]);test('Buffer binary toString base64', binaryBuf.toString('base64'), 'AAEC/w==');test('Buffer binary toString hex', binaryBuf.toString('hex'), '000102ff');
const binaryFromB64 = Buffer.from('AAEC/w==', 'base64');test('Buffer binary from base64 byte 0', binaryFromB64[0], 0x00);test('Buffer binary from base64 byte 1', binaryFromB64[1], 0x01);test('Buffer binary from base64 byte 2', binaryFromB64[2], 0x02);test('Buffer binary from base64 byte 3', binaryFromB64[3], 0xff);
const binaryFromHex = Buffer.from('000102ff', 'hex');test('Buffer binary from hex byte 0', binaryFromHex[0], 0x00);test('Buffer binary from hex byte 1', binaryFromHex[1], 0x01);test('Buffer binary from hex byte 2', binaryFromHex[2], 0x02);test('Buffer binary from hex byte 3', binaryFromHex[3], 0xff);
console.log('\nArrayBuffer Transfer Tests\n');
const transferBuf = new ArrayBuffer(16);const transferView = new Uint8Array(transferBuf);transferView[0] = 42;transferView[1] = 123;test('ArrayBuffer detached initial', transferBuf.detached, false);
const newBuf = transferBuf.transfer(32);test('ArrayBuffer transfer - old detached', transferBuf.detached, true);test('ArrayBuffer transfer - old byteLength', transferBuf.byteLength, 0);test('ArrayBuffer transfer - new detached', newBuf.detached, false);test('ArrayBuffer transfer - new byteLength', newBuf.byteLength, 32);
const newView = new Uint8Array(newBuf);test('ArrayBuffer transfer - data preserved [0]', newView[0], 42);test('ArrayBuffer transfer - data preserved [1]', newView[1], 123);
test('TypedArray on detached buffer read', transferView[0], undefined);transferView[0] = 99;test('TypedArray on detached buffer write ignored', transferView[0], undefined);
const shrinkBuf = new ArrayBuffer(100);const shrunkBuf = shrinkBuf.transfer(50);test('ArrayBuffer transfer shrink - old detached', shrinkBuf.detached, true);test('ArrayBuffer transfer shrink - new byteLength', shrunkBuf.byteLength, 50);
const sameSizeBuf = new ArrayBuffer(64);const sameSizeView = new Uint8Array(sameSizeBuf);sameSizeView[0] = 255;const transferredSame = sameSizeBuf.transfer();test('ArrayBuffer transfer no arg - uses same size', transferredSame.byteLength, 64);test('ArrayBuffer transfer no arg - data preserved', new Uint8Array(transferredSame)[0], 255);
const fixedBuf = new ArrayBuffer(32);const fixedTransferred = fixedBuf.transferToFixedLength(16);test('ArrayBuffer transferToFixedLength - old detached', fixedBuf.detached, true);test('ArrayBuffer transferToFixedLength - new byteLength', fixedTransferred.byteLength, 16);
let transferError = false;try { transferBuf.transfer();} catch (e) { transferError = e instanceof TypeError;}test('ArrayBuffer transfer detached throws TypeError', transferError, true);
let sliceError = false;try { transferBuf.slice(0, 10);} catch (e) { sliceError = e instanceof TypeError;}test('ArrayBuffer slice detached throws TypeError', sliceError, true);
const sharedBuf = new SharedArrayBuffer(16);test('SharedArrayBuffer detached', sharedBuf.detached, undefined);
// latin1/ascii encode one byte per UTF-16 code unit (unit & 0xff); ascii// decode strips the high bitconst l1 = Buffer.alloc(4);test('latin1 write é is one byte', l1.write('é', 0, 4, 'latin1'), 1);test('latin1 write é byte value', l1[0], 0xe9);test('ascii write é matches latin1', (l1.write('é', 1, 3, 'ascii'), l1[1]), 0xe9);test('latin1 write astral masks units', (l1.write('😀', 0, 4, 'latin1'), l1[0] * 256 + l1[1]), 0x3d00);test('latin1 byteLength is unit count', Buffer.byteLength('é😀', 'latin1'), 3);test('latin1 from é byte', Buffer.from('é', 'latin1')[0], 0xe9);test('latin1 round trip', Buffer.from('héllo', 'latin1').toString('latin1'), 'héllo');test('latin1 toString maps bytes', Buffer.from([0xe9, 0x41]).toString('latin1'), 'éA');test('ascii toString strips high bit', Buffer.from([0xe9, 0x41]).toString('ascii'), 'iA');test('latin1 indexOf encodes search string', Buffer.from([0xe9]).indexOf('é', 0, 'latin1'), 0);test('ascii indexOf encodes like latin1', Buffer.from([0xe9]).indexOf('é', 0, 'ascii'), 0);
// utf8 write/from must emit U+FFFD for lone surrogates, never raw WTF-8const loneBuf = Buffer.alloc(4);test('utf8 write lone surrogate length', loneBuf.write('\uD800', 0, 4, 'utf8'), 3);test('utf8 write lone surrogate bytes', [loneBuf[0], loneBuf[1], loneBuf[2]].map(x => x.toString(16)).join(' '), 'ef bf bd');test('utf8 from lone surrogate', [...Buffer.from('a\uD800b', 'utf8')].map(x => x.toString(16)).join(' '), '61 ef bf bd 62');test('utf8 lone surrogate round trip', Buffer.from('\uD800', 'utf8').toString('utf8'), '�');test('utf8 real pair unchanged', [...Buffer.from('😀', 'utf8')].map(x => x.toString(16)).join(' '), 'f0 9f 98 80');
summary();