blob: 04e670c2e7794e150fa93d7b6398e056d22f2ff6 [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'
Austin Schuh2dd86a92022-09-14 21:19:23 -07004import * as flexbuffers from 'flatbuffers/js/flexbuffers.js'
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);
Austin Schuh2dd86a92022-09-14 21:19:23 -0700267 _assert({ test_number: 72.6 })
Austin Schuh272c6132020-11-14 16:37:52 -0800268}
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() {
Austin Schuh2dd86a92022-09-14 21:19:23 -0700344 const data = new Uint8Array(fs.readFileSync('../gold_flexbuffer_example.bin')).buffer;
Austin Schuh272c6132020-11-14 16:37:52 -0800345 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