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