@cloudpss/ubjson 0.3.11 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common/decoder.d.ts +7 -3
- package/dist/common/decoder.js +9 -1
- package/dist/common/decoder.js.map +1 -1
- package/dist/common/encoder.js +2 -1
- package/dist/common/encoder.js.map +1 -1
- package/dist/common/string-decoder.js +2 -1
- package/dist/common/string-decoder.js.map +1 -1
- package/dist/decoder.d.ts +2 -0
- package/dist/decoder.js +3 -0
- package/dist/decoder.js.map +1 -0
- package/dist/encoder.d.ts +1 -0
- package/dist/encoder.js +35 -39
- package/dist/encoder.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/rxjs/decoder.d.ts +3 -0
- package/dist/rxjs/decoder.js +68 -0
- package/dist/rxjs/decoder.js.map +1 -0
- package/dist/rxjs/encoder.d.ts +3 -0
- package/dist/rxjs/encoder.js +28 -0
- package/dist/rxjs/encoder.js.map +1 -0
- package/dist/rxjs/index.d.ts +2 -0
- package/dist/rxjs/index.js +3 -0
- package/dist/rxjs/index.js.map +1 -0
- package/dist/stream/decoder.d.ts +13 -0
- package/dist/stream/decoder.js +52 -0
- package/dist/stream/decoder.js.map +1 -0
- package/dist/stream/encoder.d.ts +6 -11
- package/dist/stream/encoder.js +15 -78
- package/dist/stream/encoder.js.map +1 -1
- package/dist/stream/index.d.ts +8 -1
- package/dist/stream/index.js +27 -2
- package/dist/stream/index.js.map +1 -1
- package/dist/stream-helper/decoder.d.ts +8 -0
- package/dist/stream-helper/decoder.js +13 -0
- package/dist/stream-helper/decoder.js.map +1 -0
- package/dist/stream-helper/encoder.d.ts +12 -0
- package/dist/stream-helper/encoder.js +57 -0
- package/dist/stream-helper/encoder.js.map +1 -0
- package/package.json +5 -2
- package/src/common/decoder.ts +13 -4
- package/src/common/encoder.ts +2 -1
- package/src/common/string-decoder.ts +3 -1
- package/src/decoder.ts +3 -0
- package/src/encoder.ts +34 -38
- package/src/index.ts +1 -1
- package/src/rxjs/decoder.ts +65 -0
- package/src/rxjs/encoder.ts +27 -0
- package/src/rxjs/index.ts +2 -0
- package/src/stream/decoder.ts +54 -0
- package/src/stream/encoder.ts +16 -76
- package/src/stream/index.ts +30 -3
- package/src/stream-helper/decoder.ts +15 -0
- package/src/stream-helper/encoder.ts +56 -0
- package/tests/encode.js +13 -2
- package/tests/rxjs/decode.js +535 -0
- package/tests/rxjs/encode.js +412 -0
- package/tests/stream/decode.js +502 -0
- package/tests/stream/encode.js +13 -11
- package/tests/string-encoding.js +21 -1
- package/tests/tsconfig.json +0 -8
- package/tsconfig.json +0 -7
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests from https://bitbucket.org/shelacek/ubjson
|
|
3
|
+
*/
|
|
4
|
+
import { jest } from '@jest/globals';
|
|
5
|
+
import { Readable } from 'node:stream';
|
|
6
|
+
import { decoder as decodeStream, decode as decodeAsync } from '../../dist/stream/index.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {Uint8Array} data
|
|
10
|
+
*/
|
|
11
|
+
async function decode(data) {
|
|
12
|
+
const readable = Readable.from([data], { objectMode: false });
|
|
13
|
+
return decodeAsync(readable);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {import("stream").Transform} stream
|
|
18
|
+
*/
|
|
19
|
+
function eos(stream) {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
stream.on('error', reject);
|
|
22
|
+
stream.on('end', resolve);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {...string | number} args
|
|
28
|
+
* @returns {Uint8Array}
|
|
29
|
+
*/
|
|
30
|
+
function toBuffer(...args) {
|
|
31
|
+
return Uint8Array.from(args, (x) => (typeof x == 'number' ? x : x.charCodeAt(0)));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
test('decode unsupported type', async () => {
|
|
35
|
+
await expect(() => decode(toBuffer('!'))).rejects.toThrow();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('decode undefined', async () => {
|
|
39
|
+
expect(await decode(toBuffer('N'))).toBeUndefined();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('decode undefined (multiple noop)', async () => {
|
|
43
|
+
expect(await decode(toBuffer('N', 'N', 'N'))).toBeUndefined();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('decode undefined (empty buffer)', async () => {
|
|
47
|
+
expect(await decode(toBuffer())).toBeUndefined();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('decode null', async () => {
|
|
51
|
+
// null is not allowed in a stream, will be decoded as undefined
|
|
52
|
+
expect(await decode(toBuffer('Z'))).toBeUndefined();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('decode true', async () => {
|
|
56
|
+
expect(await decode(toBuffer('T'))).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('decode false', async () => {
|
|
60
|
+
expect(await decode(toBuffer('F'))).toBe(false);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('decode int8', async () => {
|
|
64
|
+
expect(await decode(toBuffer('i', 100))).toBe(100);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('decode uint8', async () => {
|
|
68
|
+
expect(await decode(toBuffer('U', 200))).toBe(200);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('decode int16', async () => {
|
|
72
|
+
expect(await decode(toBuffer('I', 0x12, 0x34))).toBe(0x1234);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test('decode int32', async () => {
|
|
76
|
+
expect(await decode(toBuffer('l', 0x12, 0x34, 0x56, 0x78))).toBe(0x12345678);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('decode int64 [error]', async () => {
|
|
80
|
+
await expect(() => decode(toBuffer('L', 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0))).rejects.toThrow();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('decode float32', async () => {
|
|
84
|
+
expect(await decode(toBuffer('d', 0x3f, 0x80, 0x80, 0x00))).toBe(1.00390625);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('decode float64', async () => {
|
|
88
|
+
expect(await decode(toBuffer('D', 0x40, 0xf8, 0x6a, 0x00, 0x10, 0x00, 0x00, 0x00))).toBe(100000.00390625);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('decode high-precision number [error]', async () => {
|
|
92
|
+
await expect(() => decode(toBuffer('H', 'i', 3, '1', '.', '1'))).rejects.toThrow();
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test('decode char', async () => {
|
|
96
|
+
expect(await decode(toBuffer('C', 'a'))).toBe('a');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test('decode string', async () => {
|
|
100
|
+
expect(await decode(toBuffer('S', 'i', 6, 'u', 'b', 'j', 's', 'o', 'n'))).toBe('ubjson');
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test('decode empty string', async () => {
|
|
104
|
+
expect(await decode(toBuffer('S', 'i', 0))).toBe('');
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test('decode string (bad size) [error]', async () => {
|
|
108
|
+
await expect(() => decode(toBuffer('S', 'i', 0xff, 'x'))).rejects.toThrow(/Invalid length/);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('decode string (unexpected eof) [error]', async () => {
|
|
112
|
+
await expect(() => decode(toBuffer('S', 'i', 2, 'x'))).rejects.toThrow(/Unexpected EOF/);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test('decode ascii string', async () => {
|
|
116
|
+
const header = toBuffer('S', 'I', 0x3f, 0xff);
|
|
117
|
+
const payload = new Uint8Array(0x3fff + header.byteLength).fill('a'.charCodeAt(0));
|
|
118
|
+
payload.set(header);
|
|
119
|
+
expect(await decode(payload)).toBe('a'.repeat(0x3fff));
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test('decode ascii string [huge]', async () => {
|
|
123
|
+
const header = toBuffer('S', 'I', 0x7f, 0xff);
|
|
124
|
+
const payload = new Uint8Array(0x7fff + header.byteLength).fill('a'.charCodeAt(0));
|
|
125
|
+
payload.set(header);
|
|
126
|
+
expect(await decode(payload)).toBe('a'.repeat(0x7fff));
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test('decode huge string', async () => {
|
|
130
|
+
expect(await decode(toBuffer('S', 'l', 0x00, 0x00, 0x00, 6, 'u', 'b', 'j', 's', 'o', 'n'))).toBe('ubjson');
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test('decode huge string [error]', async () => {
|
|
134
|
+
await expect(() => decode(toBuffer('S', 'L', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 'x'))).rejects.toThrow(
|
|
135
|
+
/Unsupported type int64/,
|
|
136
|
+
);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('decode array', async () => {
|
|
140
|
+
expect(await decode(toBuffer('[', 'i', 1, 'i', 2, 'i', 3, ']'))).toEqual([1, 2, 3]);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
test('decode array (with no-op)', async () => {
|
|
144
|
+
expect(await decode(toBuffer('[', 'i', 1, 'N', 'i', 2, 'i', 3, 'N', ']'))).toEqual([1, 2, 3]);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test('decode array (empty)', async () => {
|
|
148
|
+
expect(await decode(toBuffer('[', ']'))).toEqual([]);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test('decode array (empty, optimized)', async () => {
|
|
152
|
+
expect(await decode(toBuffer('[', '#', 'i', 0))).toEqual([]);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test('decode array (empty, strongly typed, optimized)', async () => {
|
|
156
|
+
expect(await decode(toBuffer('[', '$', 'i', '#', 'i', 0))).toEqual(new Int8Array(0));
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test('decode array (mixed, optimized)', async () => {
|
|
160
|
+
expect(await decode(toBuffer('[', '#', 'i', 3, 'i', 1, 'C', 'a', 'T'))).toEqual([1, 'a', true]);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test('decode array (strongly typed, optimized)', async () => {
|
|
164
|
+
expect(await decode(toBuffer('[', '$', 'i', '#', 'i', 3, 1, 2, 3))).toEqual(new Int8Array([1, 2, 3]));
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test('decode array (strongly typed, empty, optimized)', async () => {
|
|
168
|
+
expect(await decode(toBuffer('[', '$', 'i', '#', 'i', 0))).toEqual(new Int8Array([]));
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test('decode N-D array (strongly typed, optimized)', async () => {
|
|
172
|
+
expect(
|
|
173
|
+
await decode(
|
|
174
|
+
toBuffer('[', '$', '[', '#', 'i', 2, '$', 'i', '#', 'i', 3, 1, 2, 3, '$', 'i', '#', 'i', 3, 4, 5, 6),
|
|
175
|
+
),
|
|
176
|
+
).toEqual([new Int8Array([1, 2, 3]), new Int8Array([4, 5, 6])]);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test('decode array of objects (optimized)', async () => {
|
|
180
|
+
expect(
|
|
181
|
+
await decode(
|
|
182
|
+
toBuffer(
|
|
183
|
+
'[',
|
|
184
|
+
'$',
|
|
185
|
+
'{',
|
|
186
|
+
'#',
|
|
187
|
+
'i',
|
|
188
|
+
2,
|
|
189
|
+
'$',
|
|
190
|
+
'i',
|
|
191
|
+
'#',
|
|
192
|
+
'i',
|
|
193
|
+
3,
|
|
194
|
+
'i',
|
|
195
|
+
1,
|
|
196
|
+
'a',
|
|
197
|
+
1,
|
|
198
|
+
'i',
|
|
199
|
+
1,
|
|
200
|
+
'b',
|
|
201
|
+
2,
|
|
202
|
+
'i',
|
|
203
|
+
1,
|
|
204
|
+
'c',
|
|
205
|
+
3,
|
|
206
|
+
'$',
|
|
207
|
+
'i',
|
|
208
|
+
'#',
|
|
209
|
+
'i',
|
|
210
|
+
3,
|
|
211
|
+
'i',
|
|
212
|
+
1,
|
|
213
|
+
'd',
|
|
214
|
+
4,
|
|
215
|
+
'i',
|
|
216
|
+
1,
|
|
217
|
+
'e',
|
|
218
|
+
5,
|
|
219
|
+
'i',
|
|
220
|
+
1,
|
|
221
|
+
'f',
|
|
222
|
+
6,
|
|
223
|
+
),
|
|
224
|
+
),
|
|
225
|
+
).toEqual([
|
|
226
|
+
{ a: 1, b: 2, c: 3 },
|
|
227
|
+
{ d: 4, e: 5, f: 6 },
|
|
228
|
+
]);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
test('decode array of objects of arrays (optimized)', async () => {
|
|
232
|
+
expect(
|
|
233
|
+
await decode(
|
|
234
|
+
toBuffer(
|
|
235
|
+
'[',
|
|
236
|
+
'$',
|
|
237
|
+
'{',
|
|
238
|
+
'#',
|
|
239
|
+
'i',
|
|
240
|
+
2,
|
|
241
|
+
'$',
|
|
242
|
+
'[',
|
|
243
|
+
'#',
|
|
244
|
+
'i',
|
|
245
|
+
2,
|
|
246
|
+
'i',
|
|
247
|
+
1,
|
|
248
|
+
'a',
|
|
249
|
+
'$',
|
|
250
|
+
'i',
|
|
251
|
+
'#',
|
|
252
|
+
'i',
|
|
253
|
+
2,
|
|
254
|
+
1,
|
|
255
|
+
2,
|
|
256
|
+
'i',
|
|
257
|
+
1,
|
|
258
|
+
'b',
|
|
259
|
+
'$',
|
|
260
|
+
'i',
|
|
261
|
+
'#',
|
|
262
|
+
'i',
|
|
263
|
+
2,
|
|
264
|
+
3,
|
|
265
|
+
4,
|
|
266
|
+
'$',
|
|
267
|
+
'[',
|
|
268
|
+
'#',
|
|
269
|
+
'i',
|
|
270
|
+
2,
|
|
271
|
+
'i',
|
|
272
|
+
1,
|
|
273
|
+
'c',
|
|
274
|
+
'$',
|
|
275
|
+
'i',
|
|
276
|
+
'#',
|
|
277
|
+
'i',
|
|
278
|
+
2,
|
|
279
|
+
5,
|
|
280
|
+
6,
|
|
281
|
+
'i',
|
|
282
|
+
1,
|
|
283
|
+
'd',
|
|
284
|
+
'$',
|
|
285
|
+
'i',
|
|
286
|
+
'#',
|
|
287
|
+
'i',
|
|
288
|
+
2,
|
|
289
|
+
7,
|
|
290
|
+
8,
|
|
291
|
+
),
|
|
292
|
+
),
|
|
293
|
+
).toEqual([
|
|
294
|
+
{ a: new Int8Array([1, 2]), b: new Int8Array([3, 4]) },
|
|
295
|
+
{ c: new Int8Array([5, 6]), d: new Int8Array([7, 8]) },
|
|
296
|
+
]);
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
test('decode array (strongly typed, unexpected eof, optimized)', async () => {
|
|
300
|
+
await expect(() => decode(toBuffer('[', '$', 'i', '#', 'i', 3, 1, 2))).rejects.toThrow();
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
test('decode array (strongly typed, invalid length value, optimized)', async () => {
|
|
304
|
+
await expect(() => decode(toBuffer('[', '$', 'i', '#', 'i', -1))).rejects.toThrow();
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
test('decode array (strongly typed, invalid length type, optimized)', async () => {
|
|
308
|
+
await expect(() => decode(toBuffer('[', '$', 'i', '#', 'C', '0'))).rejects.toThrow();
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
test('decode array (strongly typed, malformed, optimized)', async () => {
|
|
312
|
+
await expect(() => decode(toBuffer('[', '$', 'i', 1, 2, 3, ']'))).rejects.toThrow();
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
test('decode array (only null values, optimized)', async () => {
|
|
316
|
+
expect(await decode(toBuffer('[', '$', 'Z', '#', 'i', 3))).toEqual([null, null, null]);
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
test('decode array (only true values, optimized)', async () => {
|
|
320
|
+
expect(await decode(toBuffer('[', '$', 'T', '#', 'i', 3))).toEqual([true, true, true]);
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
test('decode array (only false values, optimized)', async () => {
|
|
324
|
+
expect(await decode(toBuffer('[', '$', 'F', '#', 'i', 3))).toEqual([false, false, false]);
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
test('decode array (int8, strongly typed, optimized) [use typed array]', async () => {
|
|
328
|
+
const actual = await decode(toBuffer('[', '$', 'i', '#', 'i', 2, 0x12, 0xfe));
|
|
329
|
+
expect(actual).toBeInstanceOf(Int8Array);
|
|
330
|
+
expect(actual).toEqual(Int8Array.from([18, -2]));
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
test('decode array (uint8, strongly typed, optimized) [use typed array]', async () => {
|
|
334
|
+
const actual = await decode(toBuffer('[', '$', 'U', '#', 'i', 2, 0x12, 0xfe));
|
|
335
|
+
expect(actual).toBeInstanceOf(Uint8Array);
|
|
336
|
+
expect(actual).toEqual(Uint8Array.from([18, 254]));
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
test('decode array (int16, strongly typed, optimized) [use typed array]', async () => {
|
|
340
|
+
const actual = await decode(toBuffer('[', '$', 'I', '#', 'i', 2, 0x12, 0x34, 0xfe, 0xdc));
|
|
341
|
+
expect(actual).toBeInstanceOf(Int16Array);
|
|
342
|
+
expect(actual).toEqual(Int16Array.from([4660, -292]));
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
test('decode array (int32, strongly typed, optimized) [use typed array]', async () => {
|
|
346
|
+
const actual = await decode(toBuffer('[', '$', 'l', '#', 'i', 2, 0x12, 0x34, 0x56, 0x78, 0xfe, 0xdc, 0xba, 0x98));
|
|
347
|
+
expect(actual).toBeInstanceOf(Int32Array);
|
|
348
|
+
expect(actual).toEqual(Int32Array.from([305419896, -19088744]));
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
test('decode array (int64, strongly typed, optimized) [use typed array]', async () => {
|
|
352
|
+
await expect(() =>
|
|
353
|
+
decode(toBuffer('[', '$', 'L', '#', 'i', 1, 0x12, 0x34, 0x56, 0x78, 0xfe, 0xdc, 0xba, 0x98)),
|
|
354
|
+
).rejects.toThrow();
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
test('decode array (float32, strongly typed, optimized) [use typed array]', async () => {
|
|
358
|
+
const actual = await decode(toBuffer('[', '$', 'd', '#', 'i', 2, 0x3e, 0x80, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00));
|
|
359
|
+
expect(actual).toBeInstanceOf(Float32Array);
|
|
360
|
+
expect(actual).toEqual(Float32Array.from([0.25, 0.125]));
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
test('decode array (float64, strongly typed, optimized) [use typed array]', async () => {
|
|
364
|
+
const actual = await decode(
|
|
365
|
+
toBuffer(
|
|
366
|
+
'[',
|
|
367
|
+
'$',
|
|
368
|
+
'D',
|
|
369
|
+
'#',
|
|
370
|
+
'i',
|
|
371
|
+
2,
|
|
372
|
+
0x3f,
|
|
373
|
+
0xd0,
|
|
374
|
+
0x00,
|
|
375
|
+
0x00,
|
|
376
|
+
0x00,
|
|
377
|
+
0x00,
|
|
378
|
+
0x00,
|
|
379
|
+
0x00,
|
|
380
|
+
0x3f,
|
|
381
|
+
0xc0,
|
|
382
|
+
0x00,
|
|
383
|
+
0x00,
|
|
384
|
+
0x00,
|
|
385
|
+
0x00,
|
|
386
|
+
0x00,
|
|
387
|
+
0x00,
|
|
388
|
+
),
|
|
389
|
+
);
|
|
390
|
+
expect(actual).toBeInstanceOf(Float64Array);
|
|
391
|
+
expect(actual).toEqual(Float64Array.from([0.25, 0.125]));
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
test('decode object', async () => {
|
|
395
|
+
expect(await decode(toBuffer('{', 'i', 1, 'a', 'i', 1, 'i', 1, 'b', 'i', 2, 'i', 1, 'c', 'i', 3, '}'))).toEqual({
|
|
396
|
+
a: 1,
|
|
397
|
+
b: 2,
|
|
398
|
+
c: 3,
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
test('decode object (with no-op)', async () => {
|
|
403
|
+
expect(
|
|
404
|
+
await decode(
|
|
405
|
+
toBuffer('N', '{', 'N', 'i', 1, 'a', 'i', 1, 'i', 1, 'b', 'N', 'i', 2, 'i', 1, 'c', 'i', 3, 'N', '}', 'N'),
|
|
406
|
+
),
|
|
407
|
+
).toEqual({ a: 1, b: 2, c: 3 });
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
test('decode array (empty, optimized)', async () => {
|
|
411
|
+
expect(await decode(toBuffer('{', '#', 'i', 0))).toEqual({});
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
test('decode object (mixed, optimized)', async () => {
|
|
415
|
+
expect(
|
|
416
|
+
await decode(toBuffer('{', '#', 'i', 3, 'i', 1, 'a', 'i', 1, 'i', 1, 'b', 'C', 'a', 'i', 1, 'c', 'T')),
|
|
417
|
+
).toEqual({
|
|
418
|
+
a: 1,
|
|
419
|
+
b: 'a',
|
|
420
|
+
c: true,
|
|
421
|
+
});
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
test('decode object (strongly typed, optimized)', async () => {
|
|
425
|
+
expect(await decode(toBuffer('{', '$', 'i', '#', 'i', 3, 'i', 1, 'a', 1, 'i', 1, 'b', 2, 'i', 1, 'c', 3))).toEqual({
|
|
426
|
+
a: 1,
|
|
427
|
+
b: 2,
|
|
428
|
+
c: 3,
|
|
429
|
+
});
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
test('decode object (only null values, optimized)', async () => {
|
|
433
|
+
expect(await decode(toBuffer('{', '$', 'Z', '#', 'i', 3, 'i', 1, 'a', 'i', 1, 'b', 'i', 1, 'c'))).toEqual({
|
|
434
|
+
a: null,
|
|
435
|
+
b: null,
|
|
436
|
+
c: null,
|
|
437
|
+
});
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
test('decode object (empty key)', async () => {
|
|
441
|
+
expect(await decode(toBuffer('{', 'i', 0, 'T', '}'))).toEqual({
|
|
442
|
+
'': true,
|
|
443
|
+
});
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
test('decode object (empty key, optimized)', async () => {
|
|
447
|
+
expect(await decode(toBuffer('{', '$', 'Z', '#', 'i', 3, 'i', 0, 'i', 1, 'a', 'i', 1, 'b'))).toEqual({
|
|
448
|
+
'': null,
|
|
449
|
+
a: null,
|
|
450
|
+
b: null,
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
test('decode stream', async () => {
|
|
455
|
+
const stream = decodeStream();
|
|
456
|
+
// while decoding streaming, N will be regarded as a no-op, rather than an undefined value
|
|
457
|
+
const onData = jest.fn();
|
|
458
|
+
stream.on('data', onData);
|
|
459
|
+
stream.write(toBuffer('N', 'Z', 'N', 'N', 'T', 'N', 'N', 'F', 'N', 'N'));
|
|
460
|
+
stream.write(toBuffer('N', 'N'));
|
|
461
|
+
stream.write(toBuffer('I', 0x12));
|
|
462
|
+
stream.write(toBuffer(0x34, 'N', 'N', 'N'));
|
|
463
|
+
stream.end();
|
|
464
|
+
await eos(stream);
|
|
465
|
+
expect(onData).toBeCalledTimes(3);
|
|
466
|
+
expect(onData).nthCalledWith(1, true);
|
|
467
|
+
expect(onData).nthCalledWith(2, false);
|
|
468
|
+
expect(onData).nthCalledWith(3, 0x1234);
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
test('decode bad stream [error]', async () => {
|
|
472
|
+
const stream = decodeStream();
|
|
473
|
+
// while decoding streaming, N will be regarded as a no-op, rather than an undefined value
|
|
474
|
+
const onData = jest.fn();
|
|
475
|
+
stream.on('data', onData);
|
|
476
|
+
stream.write(toBuffer('N', 'Z', 'N', 'N', 'T', 'N', 'N', 'F', 'N', 'N'));
|
|
477
|
+
stream.write(toBuffer('N', 'N'));
|
|
478
|
+
stream.write(toBuffer('I', 0x12));
|
|
479
|
+
stream.write(toBuffer(0x34, '!', 'N'));
|
|
480
|
+
stream.write(toBuffer('I', 0x12, 0x34, 'N'));
|
|
481
|
+
stream.end();
|
|
482
|
+
await expect(eos(stream)).rejects.toThrow(/Unexpected marker/);
|
|
483
|
+
expect(onData).toBeCalledTimes(3);
|
|
484
|
+
expect(onData).nthCalledWith(1, true);
|
|
485
|
+
expect(onData).nthCalledWith(2, false);
|
|
486
|
+
expect(onData).nthCalledWith(3, 0x1234);
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
test('decode partial stream [error]', async () => {
|
|
490
|
+
const stream = decodeStream();
|
|
491
|
+
// while decoding streaming, N will be regarded as a no-op, rather than an undefined value
|
|
492
|
+
const onData = jest.fn();
|
|
493
|
+
stream.on('data', onData);
|
|
494
|
+
stream.write(toBuffer('N', 'Z', 'N', 'N', 'T', 'N', 'N', 'F', 'N', 'N'));
|
|
495
|
+
stream.write(toBuffer('N', 'N'));
|
|
496
|
+
stream.write(toBuffer('I', 0x12));
|
|
497
|
+
stream.end();
|
|
498
|
+
await expect(eos(stream)).rejects.toThrow(/Unexpected EOF/);
|
|
499
|
+
expect(onData).toBeCalledTimes(2);
|
|
500
|
+
expect(onData).nthCalledWith(1, true);
|
|
501
|
+
expect(onData).nthCalledWith(2, false);
|
|
502
|
+
});
|
package/tests/stream/encode.js
CHANGED
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tests from https://bitbucket.org/shelacek/ubjson
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
import { encode } from '../../dist/stream/index.js';
|
|
4
|
+
import { buffer } from 'node:stream/consumers';
|
|
5
|
+
import { encode, encoder } from '../../dist/stream/index.js';
|
|
6
6
|
import { decode, encode as encodeRef } from '../../dist/index.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @param {unknown} value
|
|
10
10
|
*/
|
|
11
11
|
function encodeAsync(value) {
|
|
12
|
-
return
|
|
13
|
-
const reader = encode(value);
|
|
14
|
-
let result = Buffer.alloc(0);
|
|
15
|
-
reader.on('error', reject);
|
|
16
|
-
reader.on('end', () => resolve(result));
|
|
17
|
-
reader.on('data', (chunk) => {
|
|
18
|
-
result = Buffer.concat([result, chunk]);
|
|
19
|
-
});
|
|
20
|
-
});
|
|
12
|
+
return buffer(encode(value));
|
|
21
13
|
}
|
|
22
14
|
|
|
23
15
|
/**
|
|
@@ -383,3 +375,13 @@ test('encode huge data (256M + 1) [error]', async () => {
|
|
|
383
375
|
const obj = [new Uint8Array(256 * 1024 * 1024 + 1)];
|
|
384
376
|
await expect(() => encodeAsync(obj)).rejects.toThrow(/Buffer has exceed max size/);
|
|
385
377
|
});
|
|
378
|
+
|
|
379
|
+
test('encode stream', async () => {
|
|
380
|
+
const stream = encoder();
|
|
381
|
+
stream.write(undefined);
|
|
382
|
+
stream.write(true);
|
|
383
|
+
stream.write(false);
|
|
384
|
+
stream.end();
|
|
385
|
+
const result = await buffer(stream);
|
|
386
|
+
expect(toArray(result)).toEqual(toArray('N', 'T', 'F'));
|
|
387
|
+
});
|
package/tests/string-encoding.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { StringEncoder } from '../dist/common/string-encoder.js';
|
|
2
|
-
import { StringDecoder } from '../dist/common/string-decoder.js';
|
|
2
|
+
import { StringDecoder, decodeJs } from '../dist/common/string-decoder.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
*
|
|
@@ -69,3 +69,23 @@ test('decode string', () => {
|
|
|
69
69
|
})(),
|
|
70
70
|
);
|
|
71
71
|
});
|
|
72
|
+
|
|
73
|
+
test('decode string js', () => {
|
|
74
|
+
testEncoding(
|
|
75
|
+
new TextEncoder(),
|
|
76
|
+
new (class extends StringDecoder {
|
|
77
|
+
/**
|
|
78
|
+
* @override
|
|
79
|
+
* @param {Uint8Array} buffer
|
|
80
|
+
*/
|
|
81
|
+
decode(buffer) {
|
|
82
|
+
return decodeJs(buffer, 0, buffer.byteLength);
|
|
83
|
+
}
|
|
84
|
+
})(),
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('decode malformed', () => {
|
|
89
|
+
const decoder = new StringDecoder();
|
|
90
|
+
expect(decoder.decode(new Uint8Array([0xff, 'a'.charCodeAt(0)]), 0, 2)).toEqual('\ufffda');
|
|
91
|
+
});
|
package/tests/tsconfig.json
DELETED