@cloudpss/ubjson 0.3.0-alpha.22 → 0.3.0-alpha.27

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/test/decode.js CHANGED
@@ -153,11 +153,21 @@ test('decode array (with no-op)', (t) => {
153
153
  t.end();
154
154
  });
155
155
 
156
+ test('decode array (empty)', (t) => {
157
+ t.deepEqual(ubjson.decode(toBuffer('[', ']')), []);
158
+ t.end();
159
+ });
160
+
156
161
  test('decode array (empty, optimized)', (t) => {
157
162
  t.deepEqual(ubjson.decode(toBuffer('[', '#', 'i', 0)), []);
158
163
  t.end();
159
164
  });
160
165
 
166
+ test('decode array (empty, strongly typed, optimized)', (t) => {
167
+ t.deepEqual(ubjson.decode(toBuffer('[', '$', 'i', '#', 'i', 0)), new Int8Array(0));
168
+ t.end();
169
+ });
170
+
161
171
  test('decode array (mixed, optimized)', (t) => {
162
172
  t.deepEqual(ubjson.decode(toBuffer('[', '#', 'i', 3, 'i', 1, 'C', 'a', 'T')), [1, 'a', true]);
163
173
  t.end();
@@ -463,3 +473,19 @@ test('decode object (only null values, optimized)', (t) => {
463
473
  });
464
474
  t.end();
465
475
  });
476
+
477
+ test('decode object (empty key)', (t) => {
478
+ t.deepEqual(ubjson.decode(toBuffer('{', 'i', 0, 'T', '}')), {
479
+ '': true,
480
+ });
481
+ t.end();
482
+ });
483
+
484
+ test('decode object (empty key, optimized)', (t) => {
485
+ t.deepEqual(ubjson.decode(toBuffer('{', '$', 'Z', '#', 'i', 3, 'i', 0, 'i', 1, 'a', 'i', 1, 'b')), {
486
+ '': null,
487
+ a: null,
488
+ b: null,
489
+ });
490
+ t.end();
491
+ });
package/test/e2e.js CHANGED
@@ -11,6 +11,7 @@ test('encode/decode complex object', (t) => {
11
11
  from: ['UBJSON'],
12
12
  colors: [[255, 255, 255], [0, 0, 0], [64, 64, 96], new Uint8Array([255, 0, 1, 2, 3, 127])],
13
13
  domains: {
14
+ '': '',
14
15
  com: 'commercial',
15
16
  org: 'organization',
16
17
  net: 'network',
@@ -56,6 +57,226 @@ test('encode/decode complex object', (t) => {
56
57
  document2: 'long text'.repeat(100000),
57
58
  };
58
59
  const encoded = ubjson.encode(expected);
60
+ const actual = ubjson.decode(Buffer.from(encoded));
61
+ t.deepEqual(actual, expected);
62
+ t.end();
63
+ });
64
+
65
+ test('encode/decode model', (t) => {
66
+ const expected = {
67
+ rid: 'project/CloudPSS/_SubSysPort',
68
+ name: '模块端口',
69
+ description: '',
70
+ tags: [
71
+ 'project:component',
72
+ 'type:30000',
73
+ 'project-group:模块-基础:101',
74
+ 'project-category:component',
75
+ 'project-support:job-definition/cloudpss/emtp',
76
+ 'project-support:job-definition/cloudpss/sfemt',
77
+ 'project-support:job-definition/cloudpss/power-flow',
78
+ ],
79
+ revision: {
80
+ graphic: {
81
+ pins: {
82
+ input: {
83
+ position: {
84
+ x: 0.9999999,
85
+ y: 0.5,
86
+ },
87
+ },
88
+ output: {
89
+ position: {
90
+ x: 0,
91
+ y: 0.5,
92
+ },
93
+ },
94
+ electrical: {
95
+ position: {
96
+ x: 0.9999999,
97
+ y: 0.5,
98
+ },
99
+ },
100
+ },
101
+ attrs: {
102
+ p0: {
103
+ fill: 'var(--fill)',
104
+ stroke: 'var(--stroke)',
105
+ refPath: {
106
+ d: 'm90000 0h-60000a10000 10000 0 0 0 0 20000h60000zm0 10000h20000',
107
+ h: 20000,
108
+ w: 110000,
109
+ },
110
+ fillOpacity: 'var(--fill-opacity)',
111
+ strokeWidth: 'var(--stroke-width)',
112
+ strokeOpacity: 'var(--stroke-opacity)',
113
+ },
114
+ p1: {
115
+ fill: 'var(--fill)',
116
+ stroke: 'var(--stroke)',
117
+ refPath: {
118
+ d: 'm90000 0h-60000a10000 10000 0 0 0 0 20000h60000zm0 10000h20000',
119
+ h: 20000,
120
+ w: 110000,
121
+ },
122
+ fillOpacity: 'var(--fill-opacity)',
123
+ strokeWidth: 'var(--stroke-width)',
124
+ strokeOpacity: 'var(--stroke-opacity)',
125
+ },
126
+ p2: {
127
+ fill: 'transparent',
128
+ stroke: 'var(--stroke)',
129
+ refPath: {
130
+ d: 'm20000 10000m-5000 -5000l5000 5000l-5000 5000',
131
+ h: 20000,
132
+ w: 110000,
133
+ },
134
+ fillOpacity: 'var(--fill-opacity)',
135
+ strokeWidth: 'var(--stroke-width)',
136
+ strokeOpacity: 'var(--stroke-opacity)',
137
+ },
138
+ p3: {
139
+ fill: 'var(--fill)',
140
+ stroke: 'var(--stroke)',
141
+ refPath: {
142
+ d: 'm20000 0h60000a10000 10000 0 0 1 0 20000h-60000zm0 10000h-20000',
143
+ h: 20000,
144
+ w: 110000,
145
+ },
146
+ fillOpacity: 'var(--fill-opacity)',
147
+ strokeWidth: 'var(--stroke-width)',
148
+ strokeOpacity: 'var(--stroke-opacity)',
149
+ },
150
+ p4: {
151
+ fill: 'transparent',
152
+ stroke: 'var(--stroke)',
153
+ refPath: {
154
+ d: 'm110000 10000m-5000 -5000l5000 5000l-5000 5000',
155
+ h: 20000,
156
+ w: 110000,
157
+ },
158
+ fillOpacity: 'var(--fill-opacity)',
159
+ strokeWidth: 'var(--stroke-width)',
160
+ strokeOpacity: 'var(--stroke-opacity)',
161
+ },
162
+ t0: {
163
+ fill: 'var(--spectrum-global-color-orange-600)',
164
+ refX: 0.5,
165
+ refY: 0.5,
166
+ stroke: 'transparent',
167
+ fontSize: 12,
168
+ textAnchor: 'middle',
169
+ },
170
+ },
171
+ width: 110,
172
+ height: 20,
173
+ markup: [
174
+ {
175
+ tagName: 'path',
176
+ selector: 'p0',
177
+ condition:
178
+ "=finder(p, index, array)= equalText(p.key, Key);\n p = $$.revision.pins.find(finder);\n p == undefined ? true : (not equalText(p.connection, 'input') and not equalText(p.connection, 'output'))",
179
+ },
180
+ {
181
+ tagName: 'path',
182
+ selector: 'p1',
183
+ condition:
184
+ "=finder(p, index, array) = equalText(p.key, Key);\n p = $$.revision.pins.find(finder);\n p != undefined ? equalText(p.connection, 'input') :false",
185
+ },
186
+ {
187
+ tagName: 'path',
188
+ selector: 'p2',
189
+ condition:
190
+ "=finder(p, index, array) = equalText(p.key, Key);\n p = $$.revision.pins.find(finder);\n p != undefined ? equalText(p.connection, 'output') : false",
191
+ },
192
+ {
193
+ tagName: 'path',
194
+ selector: 'p3',
195
+ condition:
196
+ "=finder(p, index, array) = equalText(p.key, Key);\n p = $$.revision.pins.find(finder);\n p != undefined ? equalText(p.connection, 'output') : false",
197
+ },
198
+ {
199
+ tagName: 'path',
200
+ selector: 'p4',
201
+ condition:
202
+ "=finder(p, index, array) = equalText(p.key, Key);\n p = $$.revision.pins.find(finder);\n p != undefined ? equalText(p.connection, 'input') :false",
203
+ },
204
+ {
205
+ attrs: {
206
+ y: '0.35em',
207
+ },
208
+ tagName: 'text',
209
+ selector: 't0',
210
+ condition: '',
211
+ textContent: 'Port: $Key',
212
+ },
213
+ ],
214
+ generator: 'x6',
215
+ },
216
+ parameters: [
217
+ {
218
+ name: 'Configuration',
219
+ items: [
220
+ {
221
+ key: 'Key',
222
+ name: 'Pin Key',
223
+ type: 'choice',
224
+ value: '',
225
+ choices:
226
+ '=mapper(p,index,array) = {key: p.key, name: p.key, description: p.description};\n$$.revision.pins.map(mapper)',
227
+ condition: 'true',
228
+ description: '绑定端口',
229
+ },
230
+ ],
231
+ condition: 'true',
232
+ description: 'Configuration',
233
+ },
234
+ ],
235
+ pins: [
236
+ {
237
+ dim: [
238
+ "=finder(p, index, array) = equalText(p.key, 'a');\np = $$.revision.pins.find(finder);\np!=undefined?p.dim[1]:''",
239
+ "=finder(p, index, array) = equalText(p.key, 'a');\np = $$.revision.pins.find(finder);\np!=undefined?p.dim[2]:''",
240
+ ],
241
+ key: 'input',
242
+ data: 'real',
243
+ name: 'Port',
244
+ visible: true,
245
+ condition:
246
+ "=finder(p, index, array) = equalText(p.key, Key);\np = $$.revision.pins.find(finder);\np != undefined ? equalText(p.connection, 'input') :false",
247
+ connection: 'output',
248
+ },
249
+ {
250
+ dim: [
251
+ "=finder(p, index, array) = equalText(p.key, 'a');\np = $$.revision.pins.find(finder);\np!=undefined?p.dim[2]:''",
252
+ "=finder(p, index, array) = equalText(p.key, 'a');\np = $$.revision.pins.find(finder);\np!=undefined?p.dim[2]:''",
253
+ ],
254
+ key: 'output',
255
+ data: 'real',
256
+ name: 'Port',
257
+ visible: true,
258
+ condition:
259
+ "=finder(p, index, array) = equalText(p.key, Key);\np = $$.revision.pins.find(finder);\np != undefined ? equalText(p.connection, 'output') :false",
260
+ connection: 'input',
261
+ },
262
+ {
263
+ dim: [
264
+ "=finder(p, index, array) = equalText(p.key, 'a');\np = $$.revision.pins.find(finder);\np!=undefined?p.dim[2]:''",
265
+ "=finder(p, index, array) = equalText(p.key, 'a');\np = $$.revision.pins.find(finder);\np!=undefined?p.dim[2]:''",
266
+ ],
267
+ key: 'electrical',
268
+ data: 'real',
269
+ name: 'Port',
270
+ visible: true,
271
+ condition:
272
+ "=finder(p, index, array)= equalText(p.key, Key);\np = $$.revision.pins.find(finder);\np == undefined ? true : (not equalText(p.connection, 'input') and not equalText(p.connection, 'output'))",
273
+ connection: 'electrical',
274
+ },
275
+ ],
276
+ documentation: '@[docs](http://docs.cloudpss.net/components/comp_PSS/comp_PSSSystem/BasicComp/SystemPort)',
277
+ },
278
+ };
279
+ const encoded = ubjson.encode(expected);
59
280
  const actual = ubjson.decode(encoded);
60
281
  t.deepEqual(actual, expected);
61
282
  t.end();
@@ -121,7 +342,13 @@ test('encode/decode complex object (no encodeInto)', (t) => {
121
342
  });
122
343
 
123
344
  test('encode/decode large array', (t) => {
124
- t.deepEqual(ubjson.decode(ubjson.encode(new Array(100000))), Array.from({ length: 100000 }).fill(null));
345
+ const array = new Array(100000);
346
+ array[12345] = 'item';
347
+
348
+ const expected = Array.from({ length: 100000 }).fill(null);
349
+ expected[12345] = 'item';
350
+
351
+ t.deepEqual(ubjson.decode(ubjson.encode(array)), expected);
125
352
  t.end();
126
353
  });
127
354
 
package/test/encode.js CHANGED
@@ -128,6 +128,18 @@ test('encode array (empty)', (t) => {
128
128
  t.end();
129
129
  });
130
130
 
131
+ test('encode array (undefined)', (t) => {
132
+ t.deepEqual(toArray(ubjson.encode([undefined])), toArray('[', 'Z', ']'));
133
+ t.end();
134
+ });
135
+
136
+ test('encode array (spares)', (t) => {
137
+ const array = new Array(3);
138
+ array[1] = true;
139
+ t.deepEqual(toArray(ubjson.encode(array)), toArray('[', 'Z', 'T', 'Z', ']'));
140
+ t.end();
141
+ });
142
+
131
143
  test('encode array (mixed)', (t) => {
132
144
  t.deepEqual(toArray(ubjson.encode([1, 'a', true])), toArray('[', 'U', 1, 'C', 'a', 'T', ']'));
133
145
  t.end();
@@ -309,6 +321,11 @@ test('encode object (empty)', (t) => {
309
321
  t.end();
310
322
  });
311
323
 
324
+ test('encode object (empty key)', (t) => {
325
+ t.deepEqual(toArray(ubjson.encode({ '': '' })), toArray('{', 'i', 0, 'S', 'i', 0, '}'));
326
+ t.end();
327
+ });
328
+
312
329
  test('encode object (mixed)', (t) => {
313
330
  t.deepEqual(
314
331
  toArray(ubjson.encode({ a: 1, b: 'a', c: true })),
@@ -337,6 +354,44 @@ test('encode object (skip prototype)', (t) => {
337
354
  t.end();
338
355
  });
339
356
 
357
+ test('encode object (skip symbol)', (t) => {
358
+ const obj = { [Symbol()]: true, a: 1 };
359
+ t.deepEqual(toArray(ubjson.encode(obj)), toArray('{', 'i', 1, 'a', 'U', 1, '}'));
360
+ t.end();
361
+ });
362
+
363
+ test('encode object (skip non-enumerable)', (t) => {
364
+ const obj = {};
365
+ Object.defineProperty(obj, 'a', { value: 1, configurable: true, writable: true });
366
+ t.deepEqual(toArray(ubjson.encode(obj)), toArray('{', '}'));
367
+ t.end();
368
+ });
369
+
370
+ test('encode object (include getter)', (t) => {
371
+ const obj = {};
372
+ Object.defineProperty(obj, 'a', { get: () => 1, enumerable: true });
373
+ t.deepEqual(toArray(ubjson.encode(obj)), toArray('{', 'i', 1, 'a', 'U', 1, '}'));
374
+ t.end();
375
+ });
376
+
377
+ test('encode object (skip undefined)', (t) => {
378
+ const obj = { a: undefined };
379
+ t.deepEqual(toArray(ubjson.encode(obj)), toArray('{', '}'));
380
+ t.end();
381
+ });
382
+
383
+ test('encode object (function) [error]', (t) => {
384
+ const obj = { a: () => {} };
385
+ t.throws(() => ubjson.encode(obj), /Unsupported type \[object Function\]/);
386
+ t.end();
387
+ });
388
+
389
+ test('encode object (include null)', (t) => {
390
+ const obj = { a: null };
391
+ t.deepEqual(toArray(ubjson.encode(obj)), toArray('{', 'i', 1, 'a', 'Z', '}'));
392
+ t.end();
393
+ });
394
+
340
395
  test('encode huge typed array (16K)', (t) => {
341
396
  const obj = new Uint8Array(16 * 1024);
342
397
  t.deepEqual(toArray(ubjson.encode(obj).slice(0, 8)), toArray('[', '$', 'U', '#', 'I', 0x40, 0x00, 0));
@@ -0,0 +1,57 @@
1
+ import test from 'tape';
2
+ import { StringDecoder } from '../dist/string-decoder.js';
3
+
4
+ const decoder = new StringDecoder();
5
+ const encoder = new TextEncoder();
6
+
7
+ test('decode string', (t) => {
8
+ t.equal(decoder.decode(encoder.encode('')), '');
9
+ t.equal(decoder.decode(encoder.encode('p4')), 'p4');
10
+ t.equal(decoder.decode(encoder.encode('t0')), 't0');
11
+ t.equal(decoder.decode(encoder.encode('ab')), 'ab');
12
+ t.equal(decoder.decode(encoder.encode('ba')), 'ba');
13
+ t.equal(decoder.decode(encoder.encode('123456')), '123456');
14
+ t.equal(decoder.decode(encoder.encode('123465')), '123465');
15
+
16
+ {
17
+ // 检查所有单字节
18
+ const actual = new Map();
19
+ const expected = new Map();
20
+ for (let index = 0; index < 0xffff; index++) {
21
+ // 跳过 Surrogate
22
+ if (index >= 0xd800 && index <= 0xdfff) continue;
23
+ const str = String.fromCharCode(index);
24
+ actual.set(index, decoder.decode(encoder.encode(str)));
25
+ expected.set(index, str);
26
+ }
27
+ t.deepEqual(actual, expected);
28
+ }
29
+
30
+ {
31
+ // 检查所有代理项
32
+ const actual = new Map();
33
+ const expected = new Map();
34
+ for (let index = 0x10000; index < 0x10ffff; index++) {
35
+ const str = String.fromCodePoint(index);
36
+ actual.set(index, decoder.decode(encoder.encode(str)));
37
+ expected.set(index, str);
38
+ }
39
+ t.deepEqual(actual, expected);
40
+ }
41
+
42
+ {
43
+ // 检查所有 2 字节 ASCII
44
+ const actual = new Map();
45
+ const expected = new Map();
46
+ for (let index = 0; index < 0x80; index++) {
47
+ for (let index2 = 0; index2 < 0x80; index2++) {
48
+ const key = index * 0xffff + index2;
49
+ const str = String.fromCharCode(index, index2);
50
+ actual.set(key, decoder.decode(encoder.encode(str)));
51
+ expected.set(key, str);
52
+ }
53
+ }
54
+ t.deepEqual(actual, expected);
55
+ }
56
+ t.end();
57
+ });