xref: /aosp_15_r20/external/flatbuffers/tests/JavaScriptFlexBuffersTest.js (revision 890232f25432b36107d06881e0a25aaa6b473652)
1// Run this using JavaScriptTest.sh
2import assert from 'assert'
3import fs from 'fs'
4import * as flexbuffers from 'flatbuffers/js/flexbuffers'
5
6function main() {
7  testSingleValueBuffers();
8  testGoldBuffer();
9  testEncode();
10  testIndirectAdd();
11  testIndirectWithCache();
12  testMapBuilder();
13  testRoundTrip();
14  testRoundTripWithBuilder();
15  testDeduplicationOff();
16  testBugWhereOffestWereStoredAsIntInsteadOfUInt();
17
18  console.log('FlexBuffers test: completed successfully');
19}
20
21function testSingleValueBuffers() {
22  {
23    const ref = flexbuffers.toReference(new Uint8Array([0, 0, 1]).buffer);
24    assert.strictEqual(true, ref.isNull());
25  }
26
27  function _assert(object, buffer) {
28    assert.deepStrictEqual(flexbuffers.toObject(new Uint8Array(buffer).buffer), object);
29  }
30  _assert(true, [1, 104, 1]);
31  _assert(false, [0, 104, 1]);
32  _assert(25, [25, 4, 1]);
33  _assert(-25, [231, 4, 1]);
34  _assert(230, [230, 8, 1]);
35  _assert(230, [230, 0, 5, 2]);
36  _assert(-1025, [255, 251, 5, 2]);
37  _assert(1025, [1, 4, 9, 2]);
38  _assert(2147483647, [255, 255, 255, 127, 6, 4]);
39  _assert(-2147483648, [0, 0, 0, 128, 6, 4]);
40  _assert(4294967295n, [255, 255, 255, 255, 0, 0, 0, 0, 7, 8]);
41  _assert(9223372036854775807n, [255, 255, 255, 255, 255, 255, 255, 127, 7, 8]);
42  _assert(-9223372036854775808n, [0, 0, 0, 0, 0, 0, 0, 128, 7, 8]);
43  _assert(18446744073709551615n, [255, 255, 255, 255, 255, 255, 255, 255, 11, 8]);
44  _assert(4.5, [0, 0, 144, 64, 14, 4]);
45  _assert(0.10000000149011612, [205, 204, 204, 61, 14, 4]);
46  _assert(0.1, [154, 153, 153, 153, 153, 153, 185, 63, 15, 8]);
47  _assert(-1025, [255, 251, 5, 2]);
48  _assert("Maxim", [5, 77, 97, 120, 105, 109, 0, 6, 20, 1]);
49  _assert("hello ��", [10, 104, 101, 108, 108, 111, 32, 240, 159, 152, 177, 0, 11, 20, 1]);
50  _assert({a:12}, [97, 0, 1, 3, 1, 1, 1, 12, 4, 2, 36, 1]);
51  _assert({"":45, "a": 12}, [0, 97, 0, 2, 4, 4, 2, 1, 2, 45, 12, 4, 4, 4, 36, 1]);
52}
53
54function testEncode() {
55  function _assert(value, buffer) {
56    assert.deepStrictEqual(flexbuffers.encode(value), new Uint8Array(buffer));
57  }
58  _assert(null, [0, 0, 1]);
59  _assert(true, [1, 104, 1]);
60  _assert(false, [0, 104, 1]);
61  _assert(1, [1, 4, 1]);
62  _assert(230, [230, 0, 5, 2]);
63  _assert(1025, [1, 4, 5, 2]);
64  _assert(-1025, [255, 251, 5, 2]);
65  _assert(0x100000001, [1, 0, 0, 0, 1, 0, 0, 0, 7, 8]);
66  _assert(0.1, [154, 153, 153, 153, 153, 153, 185, 63, 15, 8]);
67  _assert(0.5, [0, 0, 0, 63, 14, 4]);
68  _assert(new Uint8Array([1, 2, 3]), [3, 1, 2, 3, 3, 100, 1]);
69  _assert("Maxim", [5, 77, 97, 120, 105, 109, 0, 6, 20, 1]);
70  _assert("hello ��", [10, 104, 101, 108, 108, 111, 32, 240, 159, 152, 177, 0, 11, 20, 1]);
71  _assert([1, 2], [1, 2, 2, 64, 1]);
72  _assert([-1, 256], [255, 255, 0, 1, 4, 65, 1]);
73  _assert([-45, 256000], [211, 255, 255, 255, 0, 232, 3, 0, 8, 66, 1]);
74  _assert([1.1, -256.0], [2, 0, 0, 0, 0, 0, 0, 0, 154, 153, 153, 153, 153, 153, 241, 63, 0, 255, 255, 255, 255, 255, 255, 255, 15, 5, 18, 43, 1]);
75  _assert([1, 2, 4], [1, 2, 4, 3, 76, 1]);
76  _assert([-1, 256, 4], [255, 255, 0, 1, 4, 0, 6, 77, 1]);
77  _assert([[61], 64], [1, 61, 2, 2, 64, 44, 4, 4, 40, 1]);
78  _assert(["foo", "bar", "baz"], [3, 102, 111, 111, 0, 3, 98, 97, 114, 0, 3, 98, 97, 122, 0, 3, 15, 11, 7, 3, 60, 1]);
79  _assert(["foo", "bar", "baz", "foo", "bar", "baz"], [3, 102, 111, 111, 0, 3, 98, 97, 114, 0, 3, 98, 97, 122, 0, 6, 15, 11, 7, 18, 14, 10, 6, 60, 1]);
80  _assert([true, false, true], [3, 1, 0, 1, 3, 144, 1]);
81  _assert(['foo', 1, -5, 1.3, true], [
82    3, 102, 111, 111, 0, 0, 0, 0,
83    5, 0, 0, 0, 0, 0, 0, 0,
84    15, 0, 0, 0, 0, 0, 0, 0,
85    1, 0, 0, 0, 0, 0, 0, 0,
86    251, 255, 255, 255, 255, 255, 255, 255,
87    205, 204, 204, 204, 204, 204, 244, 63,
88    1, 0, 0, 0, 0, 0, 0, 0,
89    20, 4, 4, 15, 104, 45, 43, 1
90  ]);
91  _assert([1, 3.3, 'max', true, null, false], [
92    3, 109, 97, 120, 0, 0, 0, 0,
93    6, 0, 0, 0, 0, 0, 0, 0,
94    1, 0, 0, 0, 0, 0, 0, 0,
95    102, 102, 102, 102, 102, 102, 10, 64,
96    31, 0, 0, 0, 0, 0, 0, 0,
97    1, 0, 0, 0, 0, 0, 0, 0,
98    0, 0, 0, 0, 0, 0, 0, 0,
99    0, 0, 0, 0, 0, 0, 0, 0,
100    4, 15, 20, 104, 0, 104, 54, 43, 1
101  ]);
102  _assert({"a": 12}, [97, 0, 1, 3, 1, 1, 1, 12, 4, 2, 36, 1]);
103  _assert({"a": 12, "":45}, [0, 97, 0, 2, 4, 4, 2, 1, 2, 45, 12, 4, 4, 4, 36, 1]);
104  // JS currently does not support key vector offset sharing
105  _assert([{'something':12}, {'something': 45}], [
106    115, 111, 109, 101, 116, 104, 105, 110, 103, 0,
107    1, 11, 1, 1, 1, 12, 4, 6, 1, 1, 45, 4, 2, 8, 4, 36, 36, 4, 40, 1
108  ]);
109}
110
111function testDeduplicationOff() {
112  let buffer = flexbuffers.encode([{'something':12}, {'something': 45}], 1, true, true, false);
113  assert.deepStrictEqual(buffer, new Uint8Array([
114    115, 111, 109, 101, 116, 104, 105, 110, 103,
115    0,   1,  11,   1,   1,   1,  12,   4,   1,
116    18,   1,   1,   1,  45,   4,   2,  10,   4,
117    36,  36,   4,  40,   1
118  ]));
119
120  buffer = flexbuffers.encode([{'something':12}, {'something': 45}], 1, true, false, false);
121  assert.deepStrictEqual(buffer, new Uint8Array([
122    115, 111, 109, 101, 116, 104, 105, 110, 103,   0,
123    1,  11,   1,   1,   1,  12,   4, 115, 111, 109,
124    101, 116, 104, 105, 110, 103,   0,   1,  11,   1,
125    1,   1,  45,   4,   2,  20,   4,  36,  36,   4,
126    40,   1
127  ]));
128
129  buffer = flexbuffers.encode(['something', 'something', 'dark'], 1, true, false, false);
130  assert.deepStrictEqual(buffer, new Uint8Array([
131    9, 115, 111, 109, 101, 116, 104,
132    105, 110, 103,   0,   4, 100,  97,
133    114, 107,   0,   3,  17,  18,   8,
134    3,  60,   1
135  ]));
136
137  buffer = flexbuffers.encode(['something', 'something', 'dark'], 1, false, false, false);
138  assert.deepStrictEqual(buffer, new Uint8Array([
139    9, 115, 111, 109, 101, 116, 104, 105, 110,
140    103,   0,   9, 115, 111, 109, 101, 116, 104,
141    105, 110, 103,   0,   4, 100,  97, 114, 107,
142    0,   3,  28,  18,   8,   3,  60,   1
143  ]));
144}
145
146function testIndirectAdd() {
147  function _assertInt(buffer, value, indirect = false, cache = false) {
148    const builder = flexbuffers.builder();
149    builder.addInt(value, indirect, cache);
150    const data = builder.finish();
151    assert.deepStrictEqual(data, new Uint8Array(buffer));
152  }
153  function _assertUInt(buffer, value, indirect = false, cache = false) {
154    const builder = flexbuffers.builder();
155    builder.addUInt(value, indirect, cache);
156    const data = builder.finish();
157    assert.deepStrictEqual(data, new Uint8Array(buffer));
158  }
159  function _assertFloat(buffer, value, indirect = false, cache = false) {
160    const builder = flexbuffers.builder();
161    builder.addFloat(value, indirect, cache);
162    const data = builder.finish();
163    assert.deepStrictEqual(data, new Uint8Array(buffer));
164  }
165  _assertInt([0, 4, 1], 0);
166  _assertInt([0, 1, 24, 1], 0, true);
167  _assertInt([255, 0, 5, 2], 255);
168
169  _assertUInt([0, 8, 1], 0);
170  _assertUInt([0, 1, 28, 1], 0, true);
171  _assertUInt([255, 8, 1], 255);
172
173  _assertUInt([185, 115, 175, 118, 250, 84, 8, 0, 11, 8], 2345234523452345);
174  _assertUInt([185, 115, 175, 118, 250, 84, 8, 0, 8, 31, 1], 2345234523452345, true);
175  _assertInt([185, 115, 175, 118, 250, 84, 8, 0, 7, 8], 2345234523452345);
176  _assertInt([185, 115, 175, 118, 250, 84, 8, 0, 8, 27, 1], 2345234523452345, true);
177
178  _assertFloat([154, 153, 153, 153, 153, 153, 185, 63, 15, 8], 0.1);
179  _assertFloat([154, 153, 153, 153, 153, 153, 185, 63, 8, 35, 1], 0.1, true);
180  _assertFloat([0, 0, 0, 0, 14, 4], 0);
181  _assertFloat([0, 0, 0, 0, 4, 34, 1], 0, true);
182}
183
184function testIndirectWithCache() {
185  function _assertInt(buffer, values) {
186    const builder = flexbuffers.builder();
187    builder.startVector();
188    values.forEach(v => {
189      builder.addInt(v, true, true)
190    });
191    builder.end();
192    const data = builder.finish();
193    assert.deepStrictEqual(data, new Uint8Array(buffer));
194  }
195
196  function _assertUInt(buffer, values) {
197    const builder = flexbuffers.builder();
198    builder.startVector();
199    values.forEach(v => {
200      builder.addUInt(v, true, true);
201    });
202    builder.end();
203    const data = builder.finish();
204    assert.deepStrictEqual(data, new Uint8Array(buffer));
205  }
206
207  function _assertFloat(buffer, values) {
208    const builder = flexbuffers.builder();
209    builder.startVector();
210    values.forEach(v => {
211      builder.addFloat(v, true, true);
212    });
213    builder.end();
214    const data = builder.finish();
215    assert.deepStrictEqual(data, new Uint8Array(buffer));
216  }
217
218  _assertInt(
219    [185, 115, 175, 118, 250, 84, 8, 0, 4, 9, 10, 11, 12, 27, 27, 27, 27, 8, 40, 1],
220    [2345234523452345, 2345234523452345, 2345234523452345, 2345234523452345]
221  );
222
223  _assertUInt(
224    [185, 115, 175, 118, 250, 84, 8, 0, 4, 9, 10, 11, 12, 31, 31, 31, 31, 8, 40, 1],
225    [2345234523452345, 2345234523452345, 2345234523452345, 2345234523452345]
226  );
227
228  _assertFloat(
229    [154, 153, 153, 153, 153, 153, 185, 63, 4, 9, 10, 11, 12, 35, 35, 35, 35, 8, 40, 1],
230    [0.1, 0.1, 0.1, 0.1]
231  );
232}
233
234function testMapBuilder() {
235  const builder = flexbuffers.builder();
236  builder.startMap();
237  builder.addKey('a');
238  builder.add(12);
239  builder.addKey('');
240  builder.add(45);
241  builder.end();
242  const data = builder.finish();
243  assert.deepStrictEqual(data, new Uint8Array([97, 0, 0, 2, 2, 5, 2, 1, 2, 45, 12, 4, 4, 4, 36, 1]));
244}
245
246function testRoundTrip() {
247  const example = {
248    "age": 35,
249    "flags": [true, false, true, true],
250    "weight": 72.5,
251    "name": "Maxim",
252    "address": {
253      "city": "Bla",
254      "zip": "12345",
255      "countryCode": "XX",
256    }
257  };
258
259  function _assert(value) {
260    let buffer = flexbuffers.encode(value, 1);
261    let o = flexbuffers.toObject(buffer.buffer);
262    assert.deepStrictEqual(o, value);
263  }
264
265  _assert(example);
266  _assert(0x100000001n);
267  _assert({ test_number: 72.6 })
268}
269
270function testRoundTripWithBuilder() {
271  const example = {
272    "age": 35,
273    "flags": [true, false, true, true],
274    "weight": 72.5,
275    "name": "Maxim",
276    "address": {
277      "city": "Bla",
278      "zip": "12345",
279      "countryCode": "XX",
280    }
281  };
282
283  const builder = flexbuffers.builder();
284  builder.startMap();
285
286  builder.addKey('age');
287  builder.add(35);
288
289  builder.addKey('flags');
290  builder.startVector();
291  builder.add(true);
292  builder.add(false);
293  builder.add(true);
294  builder.add(true);
295  builder.end();
296
297  builder.addKey("weight");
298  builder.add(72.5);
299
300  builder.addKey("name");
301  builder.add("Maxim");
302
303  builder.addKey("address");
304
305  builder.startMap();
306  builder.addKey("city");
307  builder.add("Bla");
308  builder.addKey("zip");
309  builder.add("12345");
310  builder.addKey("countryCode");
311  builder.add("XX");
312  builder.end();
313
314  builder.end();
315
316  const data = builder.finish();
317  let o = flexbuffers.toObject(data.buffer);
318  assert.deepStrictEqual(o, example);
319
320  let root = flexbuffers.toReference(data.buffer);
321  assert.strictEqual(root.isMap(), true);
322  assert.strictEqual(root.get("age").numericValue(), 35);
323  assert.strictEqual(root.get("age").intValue(), 35);
324  assert.strictEqual(root.get("name").stringValue(), "Maxim");
325  assert.strictEqual(root.get("weight").floatValue(), 72.5);
326  assert.strictEqual(root.get("weight").numericValue(), 72.5);
327  let flags = root.get("flags");
328  assert.strictEqual(flags.isVector(), true);
329  assert.strictEqual(flags.length(), 4);
330  assert.strictEqual(flags.get(0).boolValue(), true);
331  assert.strictEqual(flags.get(1).boolValue(), false);
332  assert.strictEqual(flags.get(2).boolValue(), true);
333  assert.strictEqual(flags.get(3).boolValue(), true);
334
335  let address = root.get("address");
336  assert.strictEqual(address.isMap(), true);
337  assert.strictEqual(address.length(), 3);
338  assert.strictEqual(address.get("city").stringValue(), "Bla");
339  assert.strictEqual(address.get("zip").stringValue(), "12345");
340  assert.strictEqual(address.get("countryCode").stringValue(), "XX");
341}
342
343function testGoldBuffer() {
344  const data = new Uint8Array(fs.readFileSync('gold_flexbuffer_example.bin')).buffer;
345  const b1 = flexbuffers.toReference(data).get("bools").get(1);
346  assert.strictEqual(b1.isBool(), true);
347  assert.strictEqual(b1.boolValue(), false);
348
349  const blob = flexbuffers.toReference(data).get("vec").get(3);
350  assert.strictEqual(blob.isBlob(), true);
351  assert.deepStrictEqual(blob.blobValue(), new Uint8Array([77]));
352
353  const o = flexbuffers.toObject(data);
354  assert.deepStrictEqual(o, {
355    bool: true,
356    bools: [true, false, true, false],
357    bar: [1, 2, 3],
358    bar3: [1, 2, 3],
359    foo: 100,
360    mymap: {foo:'Fred'},
361    vec: [-100, 'Fred', 4, new Uint8Array([77]), false, 4]
362  });
363}
364
365function testBugWhereOffestWereStoredAsIntInsteadOfUInt() {
366  // Reported in https://github.com/google/flatbuffers/issues/5949#issuecomment-688421193
367  const object = {'channels_in': 64, 'dilation_height_factor': 1, 'dilation_width_factor': 1, 'fused_activation_function': 1, 'pad_values': 1, 'padding': 0, 'stride_height': 1, 'stride_width': 1};
368  let data1 = flexbuffers.encode(object);
369  const data = [99, 104, 97, 110, 110, 101, 108, 115, 95, 105, 110, 0,
370    100, 105, 108, 97, 116, 105, 111, 110, 95, 104, 101, 105, 103, 104, 116, 95, 102, 97, 99, 116, 111, 114, 0,
371    100, 105, 108, 97, 116, 105, 111, 110, 95, 119, 105, 100, 116, 104, 95, 102, 97, 99, 116, 111, 114, 0,
372    102, 117, 115, 101, 100, 95, 97, 99, 116, 105, 118, 97, 116, 105, 111, 110, 95, 102, 117, 110, 99, 116, 105, 111, 110, 0,
373    112, 97, 100, 95, 118, 97, 108, 117, 101, 115, 0, 112, 97, 100, 100, 105, 110, 103, 0,
374    115, 116, 114, 105, 100, 101, 95, 104, 101, 105, 103, 104, 116, 0,
375    115, 116, 114, 105, 100, 101, 95, 119, 105, 100, 116, 104, 0,
376    8, 130, 119, 97, 76, 51, 41, 34, 21, 8, 1, 8, 64, 1, 1, 1, 1, 0, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 16, 36, 1];
377  let object2 = flexbuffers.toObject(new Uint8Array(data).buffer);
378  let object1 = flexbuffers.toObject(new Uint8Array(data1).buffer);
379  assert.deepStrictEqual(object, object2);
380  assert.deepStrictEqual(object, object1);
381  assert.strictEqual(data.length, data1.length);
382  let ref = flexbuffers.toReference(new Uint8Array(data).buffer);
383  assert.strictEqual(ref.isMap(), true);
384  assert.strictEqual(ref.length(), 8);
385  assert.strictEqual(ref.get("channels_in").numericValue(), 64);
386  assert.strictEqual(ref.get("padding").isNumber(), true);
387}
388
389main();
390
391