Files
xterm.js/addons/xterm-addon-image/src/base64.test.ts
T
2023-08-19 15:21:42 -07:00

157 lines
5.0 KiB
TypeScript

import { assert } from 'chai';
import { Base64Decoder } from './base64.wasm';
// eslint-disable-next-line
declare const Buffer: any;
// some helpers
function toBs(bytes: Uint8Array): string {
let bs = '';
for (let i = 0; i < bytes.length; ++i) bs += String.fromCharCode(bytes[i]);
return bs;
}
function fromBs(bs: string): Uint8Array {
const r = new Uint8Array(bs.length);
for (let i = 0; i < r.length; ++i) r[i] = bs.charCodeAt(i);
return r;
}
function encNative(bytes: Uint8Array): string {
return typeof Buffer !== 'undefined' ? Buffer.from(bytes).toString('base64') : btoa(toBs(bytes));
}
function rtrim(x: string, c: string): string {
let end = x.length - 1;
while (c.indexOf(x[end]) >= 0) end -= 1;
return x.slice(0, end + 1);
}
const MAP = new Uint8Array(
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
.split('')
.map(el => el.charCodeAt(0))
);
describe('Base64Decoder', () => {
describe('decoding', () => {
it('single bytes', function() {
this.timeout(20000);
const dec = new Base64Decoder(0);
for (let i = 0; i < 256; ++i) {
dec.init(1);
const inp = new Uint8Array([i]);
const data = fromBs(encNative(inp));
assert.strictEqual(dec.put(data, 0, data.length), 0);
assert.strictEqual(dec.end(), 0);
assert.deepEqual(dec.data8, inp);
}
});
for (let a = 0; a < 256; ++a) {
it(`1+2 bytes (${a})`, function() {
const dec = new Base64Decoder(0);
for (let b = 0; b < 256; ++b) {
dec.init(2);
const inp = new Uint8Array([a, b]);
const data = fromBs(encNative(inp));
assert.strictEqual(dec.put(data, 0, data.length), 0);
assert.strictEqual(dec.end(), 0);
assert.deepEqual(dec.data8, inp);
}
});
}
for (let a = 0; a < 256; ++a) {
it(`2+3 bytes (${a})`, function() {
const dec = new Base64Decoder(0);
for (let b = 0; b < 256; ++b) {
dec.init(3);
const inp = new Uint8Array([0, a, b]);
const data = fromBs(encNative(inp));
assert.strictEqual(dec.put(data, 0, data.length), 0);
assert.strictEqual(dec.end(), 0);
assert.deepEqual(dec.data8, inp);
}
});
}
for (let a = 0; a < 256; ++a) {
it(`3+4 bytes (${a})`, function() {
const dec = new Base64Decoder(0);
for (let b = 0; b < 256; ++b) {
dec.init(4);
const inp = new Uint8Array([0, 0, a, b]);
const data = fromBs(encNative(inp));
assert.strictEqual(dec.put(data, 0, data.length), 0);
assert.strictEqual(dec.end(), 0);
assert.deepEqual(dec.data8, inp);
}
});
}
it('padding', () => {
const dec = new Base64Decoder(0);
const d = fromBs('Hello, here comes the mouse');
const encData = [];
const encDataTrimmed = [];
for (let i = 1; i < d.length; ++i) {
encData.push(encNative(d.slice(0, i)));
encDataTrimmed.push(rtrim(encNative(d.slice(0, i)), '='));
}
for (let i = 0; i < encData.length; ++i) {
// with padding
dec.init(i + 1);
let enc = fromBs(encData[i]);
assert.strictEqual(dec.put(enc, 0, enc.length), 0);
assert.strictEqual(dec.end(), 0);
assert.deepEqual(dec.data8, d.slice(0, i + 1));
// w'o padding
dec.init(i + 1);
enc = fromBs(encDataTrimmed[i]);
assert.strictEqual(dec.put(enc, 0, enc.length), 0);
assert.strictEqual(dec.end(), 0);
assert.deepEqual(dec.data8, d.slice(0, i + 1));
}
});
it('exit on false byte', function() {
this.timeout(20000);
const dec = new Base64Decoder(0);
for (let pos = 0; pos < 8; ++pos) {
const inp = new Uint8Array([65, 65, 65, 65, 65, 65, 65, 65]);
for (let i = 0; i < 256; ++i) {
dec.release();
dec.init(6);
inp[pos] = i;
dec.put(inp, 0, 8);
assert.strictEqual(dec.end(), MAP.includes(i) ? 0 : 1);
}
}
});
});
describe('memory', () => {
it('always release (keepSize 0)', () => {
const dec = new Base64Decoder(0);
dec.init(16);
dec.put(fromBs('A'.repeat(16)), 0, 16);
dec.end();
assert.strictEqual(dec.data8.length, 12);
dec.release();
assert.strictEqual(dec.data8.length, 0);
assert.isNull((dec as any)._mem);
});
it('keep 1 page (keepSize 65536)', () => {
const dec = new Base64Decoder(65536);
dec.init(384);
dec.put(fromBs('A'.repeat(512)), 0, 512);
dec.end();
assert.strictEqual(dec.data8.length, 384);
dec.release();
assert.strictEqual(dec.data8.length, 0);
assert.isNotNull((dec as any)._mem);
// grow to 2 pages + free afterwards
dec.init(65536);
dec.put(fromBs('A'.repeat(65536)), 0, 65536);
dec.end();
assert.strictEqual(dec.data8.length, 49152);
dec.release();
assert.strictEqual(dec.data8.length, 0);
assert.isNull((dec as any)._mem);
});
});
});