@cloudpss/ubjson
Version:
Opinionated UBJSON encoder/decoder for CloudPSS.
127 lines (112 loc) • 5.15 kB
JavaScript
import { Encoder } from '../dist/encoder.js';
import { decode, jsDecode } from '../dist/helper/string-decoder.js';
/**
* 测试编码
* @param {Pick<TextEncoder, 'encode'>} encoder encoder
* @param {Pick<TextDecoder, 'decode'>} decoder decoder
*/
function testEncoding(encoder, decoder) {
expect(decoder.decode(encoder.encode(''))).toEqual('');
expect(decoder.decode(encoder.encode('a'))).toEqual('a');
expect(decoder.decode(encoder.encode('p4'))).toEqual('p4');
expect(decoder.decode(encoder.encode('t0'))).toEqual('t0');
expect(decoder.decode(encoder.encode('qwe'))).toEqual('qwe');
expect(decoder.decode(encoder.encode('1qaz'))).toEqual('1qaz');
expect(decoder.decode(encoder.encode('123456'))).toEqual('123456');
expect(decoder.decode(encoder.encode('123465'))).toEqual('123465');
expect(decoder.decode(encoder.encode('1234651'))).toEqual('1234651');
expect(decoder.decode(encoder.encode('1234651'))).toEqual('1234651');
expect(decoder.decode(encoder.encode('12346511234651'))).toEqual('12346511234651');
expect(decoder.decode(encoder.encode('123465112346511234651'))).toEqual('123465112346511234651');
expect(decoder.decode(encoder.encode('abc 你好 😊🤣'))).toEqual('abc 你好 😊🤣');
expect(decoder.decode(encoder.encode('abc 你好abc 你好abc 你好 😊🤣'))).toEqual('abc 你好abc 你好abc 你好 😊🤣');
expect(decoder.decode(encoder.encode('水'.repeat(127)))).toEqual('水'.repeat(127));
expect(decoder.decode(encoder.encode('水'.repeat(32767)))).toEqual('水'.repeat(32767));
expect(decoder.decode(encoder.encode('abc 你好 😊🤣'.repeat(1000)))).toEqual('abc 你好 😊🤣'.repeat(1000));
for (let length = 1; length < 1024; length++) {
const expected = 'a'.repeat(length);
const actual = decoder.decode(encoder.encode(expected));
expect(actual).toEqual(expected);
const expected2 = '©'.repeat(length);
const actual2 = decoder.decode(encoder.encode(expected2));
expect(actual2).toEqual(expected2);
const expected3 = '水'.repeat(length);
const actual3 = decoder.decode(encoder.encode(expected3));
expect(actual3).toEqual(expected3);
const expected4 = '😊'.repeat(length);
const actual4 = decoder.decode(encoder.encode(expected4));
expect(actual4).toEqual(expected4);
const bad = new Uint8Array(length);
bad.fill(0xff);
expect(decoder.decode(bad)).toEqual('\uFFFD'.repeat(length));
bad.fill('a'.charCodeAt(0), 0, length - 1);
expect(decoder.decode(bad)).toEqual('a'.repeat(length - 1) + '\uFFFD');
}
{
// 检查所有单字节
for (let index = 0; index < 0xffff; index++) {
// 跳过 Surrogate
if (index >= 0xd800 && index <= 0xdfff) continue;
const expected = String.fromCharCode(index);
const encoded = encoder.encode(expected);
const actual = decoder.decode(encoded);
if (expected !== actual) {
expect(actual).toEqual(expected);
}
}
}
{
// 检查所有代理项
for (let index = 0x1_0000; index < 0x10_ffff; index++) {
const expected = String.fromCodePoint(index);
const actual = decoder.decode(encoder.encode(expected));
if (expected !== actual) expect(actual).toEqual(expected);
}
}
{
// 检查所有 2 字节 ASCII
for (let index = 0; index < 0x80; index++) {
for (let index2 = 0; index2 < 0x80; index2++) {
const expected = String.fromCharCode(index, index2);
const actual = decoder.decode(encoder.encode(expected));
if (expected !== actual) expect(actual).toEqual(expected);
}
}
}
}
test('encode string', () => {
testEncoding(
{
encode(s) {
const encoder = new Encoder();
const buffer = encoder.encode(s);
if (buffer[0] === 67) return buffer.subarray(1);
if (buffer[1] === 105) return buffer.subarray(3);
if (buffer[1] === 73) return buffer.subarray(4);
if (buffer[1] === 108) return buffer.subarray(6);
throw new Error('Invalid buffer');
},
},
new TextDecoder('utf8', { ignoreBOM: true, fatal: false }),
);
});
test('decode string', () => {
testEncoding(new TextEncoder(), {
decode(buffer) {
if (!(buffer instanceof Uint8Array)) return '';
return decode(buffer, 0, buffer.byteLength);
},
});
});
test('decode string js', () => {
testEncoding(new TextEncoder(), {
decode(buffer) {
if (!(buffer instanceof Uint8Array)) return '';
return jsDecode(buffer, 0, buffer.byteLength);
},
});
});
test('decode malformed', () => {
expect(decode(new Uint8Array([0xff, 'a'.charCodeAt(0)]), 0, 2)).toEqual('\uFFFDa');
expect(jsDecode(new Uint8Array([0xff, 'a'.charCodeAt(0)]), 0, 2)).toEqual('\uFFFDa');
});