blob: d2462c6747dcfc69bc238d2bbe55be706baf258d [file] [log] [blame]
Austin Schuh272c6132020-11-14 16:37:52 -08001// Run this using JavaScriptTest.sh
James Kuszmaul8e62b022022-03-22 09:33:25 -07002import assert from 'assert'
3import fs from 'fs'
4import * as flexbuffers from 'flatbuffers/js/flexbuffers'
Austin Schuh272c6132020-11-14 16:37:52 -08005
6function main() {
7 testSingleValueBuffers();
8 testGoldBuffer();
9 testEncode();
10 testIndirectAdd();
11 testIndirectWithCache();
12 testMapBuilder();
13 testRoundTrip();
14 testRoundTripWithBuilder();
15 testDeduplicationOff();
16 testBugWhereOffestWereStoredAsIntInsteadOfUInt();
James Kuszmaul8e62b022022-03-22 09:33:25 -070017
18 console.log('FlexBuffers test: completed successfully');
Austin Schuh272c6132020-11-14 16:37:52 -080019}
20
21function testSingleValueBuffers() {
James Kuszmaul8e62b022022-03-22 09:33:25 -070022 {
Austin Schuh272c6132020-11-14 16:37:52 -080023 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}
268
269function testRoundTripWithBuilder() {
270 const example = {
271 "age": 35,
272 "flags": [true, false, true, true],
273 "weight": 72.5,
274 "name": "Maxim",
275 "address": {
276 "city": "Bla",
277 "zip": "12345",
278 "countryCode": "XX",
279 }
280 };
281
282 const builder = flexbuffers.builder();
283 builder.startMap();
284
285 builder.addKey('age');
286 builder.add(35);
287
288 builder.addKey('flags');
289 builder.startVector();
290 builder.add(true);
291 builder.add(false);
292 builder.add(true);
293 builder.add(true);
294 builder.end();
295
296 builder.addKey("weight");
297 builder.add(72.5);
298
299 builder.addKey("name");
300 builder.add("Maxim");
301
302 builder.addKey("address");
303
304 builder.startMap();
305 builder.addKey("city");
306 builder.add("Bla");
307 builder.addKey("zip");
308 builder.add("12345");
309 builder.addKey("countryCode");
310 builder.add("XX");
311 builder.end();
312
313 builder.end();
314
315 const data = builder.finish();
316 let o = flexbuffers.toObject(data.buffer);
317 assert.deepStrictEqual(o, example);
318
319 let root = flexbuffers.toReference(data.buffer);
320 assert.strictEqual(root.isMap(), true);
321 assert.strictEqual(root.get("age").numericValue(), 35);
322 assert.strictEqual(root.get("age").intValue(), 35);
323 assert.strictEqual(root.get("name").stringValue(), "Maxim");
324 assert.strictEqual(root.get("weight").floatValue(), 72.5);
325 assert.strictEqual(root.get("weight").numericValue(), 72.5);
326 let flags = root.get("flags");
327 assert.strictEqual(flags.isVector(), true);
328 assert.strictEqual(flags.length(), 4);
329 assert.strictEqual(flags.get(0).boolValue(), true);
330 assert.strictEqual(flags.get(1).boolValue(), false);
331 assert.strictEqual(flags.get(2).boolValue(), true);
332 assert.strictEqual(flags.get(3).boolValue(), true);
333
334 let address = root.get("address");
335 assert.strictEqual(address.isMap(), true);
336 assert.strictEqual(address.length(), 3);
337 assert.strictEqual(address.get("city").stringValue(), "Bla");
338 assert.strictEqual(address.get("zip").stringValue(), "12345");
339 assert.strictEqual(address.get("countryCode").stringValue(), "XX");
340}
341
342function testGoldBuffer() {
343 const data = new Uint8Array(fs.readFileSync('gold_flexbuffer_example.bin')).buffer;
344 const b1 = flexbuffers.toReference(data).get("bools").get(1);
345 assert.strictEqual(b1.isBool(), true);
346 assert.strictEqual(b1.boolValue(), false);
347
348 const blob = flexbuffers.toReference(data).get("vec").get(3);
349 assert.strictEqual(blob.isBlob(), true);
350 assert.deepStrictEqual(blob.blobValue(), new Uint8Array([77]));
351
352 const o = flexbuffers.toObject(data);
353 assert.deepStrictEqual(o, {
354 bool: true,
355 bools: [true, false, true, false],
356 bar: [1, 2, 3],
357 bar3: [1, 2, 3],
358 foo: 100,
359 mymap: {foo:'Fred'},
360 vec: [-100, 'Fred', 4, new Uint8Array([77]), false, 4]
361 });
362}
363
364function testBugWhereOffestWereStoredAsIntInsteadOfUInt() {
365 // Reported in https://github.com/google/flatbuffers/issues/5949#issuecomment-688421193
366 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};
367 let data1 = flexbuffers.encode(object);
368 const data = [99, 104, 97, 110, 110, 101, 108, 115, 95, 105, 110, 0,
369 100, 105, 108, 97, 116, 105, 111, 110, 95, 104, 101, 105, 103, 104, 116, 95, 102, 97, 99, 116, 111, 114, 0,
370 100, 105, 108, 97, 116, 105, 111, 110, 95, 119, 105, 100, 116, 104, 95, 102, 97, 99, 116, 111, 114, 0,
371 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,
372 112, 97, 100, 95, 118, 97, 108, 117, 101, 115, 0, 112, 97, 100, 100, 105, 110, 103, 0,
373 115, 116, 114, 105, 100, 101, 95, 104, 101, 105, 103, 104, 116, 0,
374 115, 116, 114, 105, 100, 101, 95, 119, 105, 100, 116, 104, 0,
375 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];
376 let object2 = flexbuffers.toObject(new Uint8Array(data).buffer);
377 let object1 = flexbuffers.toObject(new Uint8Array(data1).buffer);
378 assert.deepStrictEqual(object, object2);
379 assert.deepStrictEqual(object, object1);
380 assert.strictEqual(data.length, data1.length);
381 let ref = flexbuffers.toReference(new Uint8Array(data).buffer);
382 assert.strictEqual(ref.isMap(), true);
383 assert.strictEqual(ref.length(), 8);
384 assert.strictEqual(ref.get("channels_in").numericValue(), 64);
385 assert.strictEqual(ref.get("padding").isNumber(), true);
386}
387
388main();
389