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