@cloudpss/ubjson
Version:
Opinionated UBJSON encoder/decoder for CloudPSS.
117 lines (110 loc) • 3.28 kB
JavaScript
import { Readable } from 'node:stream';
import { encodeMany, decodeMany } from '../../dist/stream/index.js';
import { buffer } from 'node:stream/consumers';
import { finished } from 'node:stream/promises';
/**
* iterableToAsyncIterable
* @template T
* @param {Iterable<T>} iterable - iterable
* @returns {AsyncIterable<T>} async iterable
*/
function iterableToAsyncIterable(iterable) {
return {
[Symbol.asyncIterator]: () => {
const iterator = iterable[Symbol.iterator]();
return {
// eslint-disable-next-line unicorn/no-useless-promise-resolve-reject
next: async () => Promise.resolve(iterator.next()),
};
},
};
}
/**
* asyncIterableToArray
* @template T
* @param {AsyncIterable<T>} asyncIterable - async iterable
* @returns {Promise<Array<T>>} array
*/
async function asyncIterableToArray(asyncIterable) {
const array = [];
for await (const item of asyncIterable) {
array.push(item);
}
return array;
}
test('encode/decode many', async () => {
const data = [
{
a: 1,
b: 2,
c: 3,
d: 4,
e: 5,
},
1,
null,
'x',
true,
[1, 2, 3],
Uint8Array.of(3, 3, 1),
];
const encoded = await buffer(encodeMany(iterableToAsyncIterable(data)));
const decoded = await asyncIterableToArray(
decodeMany(/** @type {ReadableStream<Uint8Array>} */ (Readable.toWeb(Readable.from([encoded])))),
);
expect(decoded).toEqual([
{
a: 1,
b: 2,
c: 3,
d: 4,
e: 5,
},
1,
// null is not allowed in stream
'x',
true,
[1, 2, 3],
Uint8Array.of(3, 3, 1),
]);
});
test('encode/decode many with invalid value', async () => {
await expect(async () => {
const readable = Readable.fromWeb(/** @type {any} */ (encodeMany(iterableToAsyncIterable([1, () => 1]))));
const f = finished(readable);
readable.resume();
await f;
}).rejects.toThrow(/Unsupported type Function/);
});
test('encode/decode many with error', async () => {
// await expect(async () => {
// try {
// const stream = encodeMany(
// (async function* () {
// yield 1;
// await Promise.resolve();
// // throw new Error('xx');
// })(),
// );
// const f = finished(/** @type {any} */ (stream));
// for await (const _ of stream) {
// //
// }
// await f;
// } catch (ex) {
// console.log(ex);
// }
// }).rejects.toThrow('xx');
});
test('encode/decode many with undefined', async () => {
const data = [1, null, undefined, [undefined]];
const encoded = await buffer(encodeMany(iterableToAsyncIterable(data)));
const decoded = await asyncIterableToArray(
decodeMany(/** @type {ReadableStream<Uint8Array>} */ (Readable.toWeb(Readable.from([encoded])))),
);
expect(decoded).toEqual([
1,
// null is not allowed in stream
[null],
]);
});