1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// https://developers.google.com/protocol-buffers/ 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions are 7// met: 8// 9// * Redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above 12// copyright notice, this list of conditions and the following disclaimer 13// in the documentation and/or other materials provided with the 14// distribution. 15// * Neither the name of Google Inc. nor the names of its 16// contributors may be used to endorse or promote products derived from 17// this software without specific prior written permission. 18// 19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31/** 32 * @fileoverview Test cases for jspb's helper functions. 33 * 34 * Test suite is written using Jasmine -- see http://jasmine.github.io/ 35 * 36 * @author aappleby@google.com (Austin Appleby) 37 */ 38 39goog.require('goog.crypt.base64'); 40goog.require('goog.testing.asserts'); 41goog.require('jspb.BinaryConstants'); 42goog.require('jspb.BinaryWriter'); 43goog.require('jspb.utils'); 44 45 46/** 47 * @param {number} x 48 * @return {number} 49 */ 50function truncate(x) { 51 var temp = new Float32Array(1); 52 temp[0] = x; 53 return temp[0]; 54} 55 56 57/** 58 * Converts an 64-bit integer in split representation to a 64-bit hash string 59 * (8 bits encoded per character). 60 * @param {number} bitsLow The low 32 bits of the split 64-bit integer. 61 * @param {number} bitsHigh The high 32 bits of the split 64-bit integer. 62 * @return {string} The encoded hash string, 8 bits per character. 63 */ 64function toHashString(bitsLow, bitsHigh) { 65 return String.fromCharCode((bitsLow >>> 0) & 0xFF, 66 (bitsLow >>> 8) & 0xFF, 67 (bitsLow >>> 16) & 0xFF, 68 (bitsLow >>> 24) & 0xFF, 69 (bitsHigh >>> 0) & 0xFF, 70 (bitsHigh >>> 8) & 0xFF, 71 (bitsHigh >>> 16) & 0xFF, 72 (bitsHigh >>> 24) & 0xFF); 73} 74 75 76describe('binaryUtilsTest', function() { 77 /** 78 * Tests lossless binary-to-decimal conversion. 79 */ 80 it('testDecimalConversion', function() { 81 // Check some magic numbers. 82 var result = 83 jspb.utils.joinUnsignedDecimalString(0x89e80001, 0x8ac72304); 84 assertEquals('10000000000000000001', result); 85 86 result = jspb.utils.joinUnsignedDecimalString(0xacd05f15, 0x1b69b4b); 87 assertEquals('123456789123456789', result); 88 89 result = jspb.utils.joinUnsignedDecimalString(0xeb1f0ad2, 0xab54a98c); 90 assertEquals('12345678901234567890', result); 91 92 result = jspb.utils.joinUnsignedDecimalString(0xe3b70cb1, 0x891087b8); 93 assertEquals('9876543210987654321', result); 94 95 // Check limits. 96 result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00000000); 97 assertEquals('0', result); 98 99 result = jspb.utils.joinUnsignedDecimalString(0xFFFFFFFF, 0xFFFFFFFF); 100 assertEquals('18446744073709551615', result); 101 102 // Check each bit of the low dword. 103 for (var i = 0; i < 32; i++) { 104 var low = (1 << i) >>> 0; 105 result = jspb.utils.joinUnsignedDecimalString(low, 0); 106 assertEquals('' + Math.pow(2, i), result); 107 } 108 109 // Check the first 20 bits of the high dword. 110 for (var i = 0; i < 20; i++) { 111 var high = (1 << i) >>> 0; 112 result = jspb.utils.joinUnsignedDecimalString(0, high); 113 assertEquals('' + Math.pow(2, 32 + i), result); 114 } 115 116 // V8's internal double-to-string conversion is inaccurate for values above 117 // 2^52, even if they're representable integers - check the rest of the bits 118 // manually against the correct string representations of 2^N. 119 120 result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00100000); 121 assertEquals('4503599627370496', result); 122 123 result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00200000); 124 assertEquals('9007199254740992', result); 125 126 result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00400000); 127 assertEquals('18014398509481984', result); 128 129 result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00800000); 130 assertEquals('36028797018963968', result); 131 132 result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x01000000); 133 assertEquals('72057594037927936', result); 134 135 result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x02000000); 136 assertEquals('144115188075855872', result); 137 138 result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x04000000); 139 assertEquals('288230376151711744', result); 140 141 result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x08000000); 142 assertEquals('576460752303423488', result); 143 144 result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x10000000); 145 assertEquals('1152921504606846976', result); 146 147 result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x20000000); 148 assertEquals('2305843009213693952', result); 149 150 result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x40000000); 151 assertEquals('4611686018427387904', result); 152 153 result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x80000000); 154 assertEquals('9223372036854775808', result); 155 }); 156 157 158 /** 159 * Going from hash strings to decimal strings should also be lossless. 160 */ 161 it('testHashToDecimalConversion', function() { 162 var result; 163 var convert = jspb.utils.hash64ToDecimalString; 164 165 result = convert(toHashString(0x00000000, 0x00000000), false); 166 assertEquals('0', result); 167 168 result = convert(toHashString(0x00000000, 0x00000000), true); 169 assertEquals('0', result); 170 171 result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), false); 172 assertEquals('18446744073709551615', result); 173 174 result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), true); 175 assertEquals('-1', result); 176 177 result = convert(toHashString(0x00000000, 0x80000000), false); 178 assertEquals('9223372036854775808', result); 179 180 result = convert(toHashString(0x00000000, 0x80000000), true); 181 assertEquals('-9223372036854775808', result); 182 183 result = convert(toHashString(0xacd05f15, 0x01b69b4b), false); 184 assertEquals('123456789123456789', result); 185 186 result = convert(toHashString(~0xacd05f15 + 1, ~0x01b69b4b), true); 187 assertEquals('-123456789123456789', result); 188 189 // And converting arrays of hashes should work the same way. 190 result = jspb.utils.hash64ArrayToDecimalStrings([ 191 toHashString(0xFFFFFFFF, 0xFFFFFFFF), 192 toHashString(0x00000000, 0x80000000), 193 toHashString(0xacd05f15, 0x01b69b4b)], false); 194 assertEquals(3, result.length); 195 assertEquals('18446744073709551615', result[0]); 196 assertEquals('9223372036854775808', result[1]); 197 assertEquals('123456789123456789', result[2]); 198 }); 199 200 /* 201 * Going from decimal strings to hash strings should be lossless. 202 */ 203 it('testDecimalToHashConversion', function() { 204 var result; 205 var convert = jspb.utils.decimalStringToHash64; 206 207 result = convert('0'); 208 assertEquals(String.fromCharCode.apply(null, 209 [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), result); 210 211 result = convert('-1'); 212 assertEquals(String.fromCharCode.apply(null, 213 [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result); 214 215 result = convert('18446744073709551615'); 216 assertEquals(String.fromCharCode.apply(null, 217 [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result); 218 219 result = convert('9223372036854775808'); 220 assertEquals(String.fromCharCode.apply(null, 221 [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]), result); 222 223 result = convert('-9223372036854775808'); 224 assertEquals(String.fromCharCode.apply(null, 225 [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]), result); 226 227 result = convert('123456789123456789'); 228 assertEquals(String.fromCharCode.apply(null, 229 [0x15, 0x5F, 0xD0, 0xAC, 0x4B, 0x9B, 0xB6, 0x01]), result); 230 231 result = convert('-123456789123456789'); 232 assertEquals(String.fromCharCode.apply(null, 233 [0xEB, 0xA0, 0x2F, 0x53, 0xB4, 0x64, 0x49, 0xFE]), result); 234 }); 235 236 /** 237 * Going from hash strings to hex strings should be lossless. 238 */ 239 it('testHashToHexConversion', function() { 240 var result; 241 var convert = jspb.utils.hash64ToHexString; 242 243 result = convert(toHashString(0x00000000, 0x00000000)); 244 assertEquals('0x0000000000000000', result); 245 246 result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF)); 247 assertEquals('0xffffffffffffffff', result); 248 249 result = convert(toHashString(0x12345678, 0x9ABCDEF0)); 250 assertEquals('0x9abcdef012345678', result); 251 }); 252 253 254 /** 255 * Going from hex strings to hash strings should be lossless. 256 */ 257 it('testHexToHashConversion', function() { 258 var result; 259 var convert = jspb.utils.hexStringToHash64; 260 261 result = convert('0x0000000000000000'); 262 assertEquals(String.fromCharCode.apply(null, 263 [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), result); 264 265 result = convert('0xffffffffffffffff'); 266 assertEquals(String.fromCharCode.apply(null, 267 [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result); 268 269 // Hex string is big-endian, hash string is little-endian. 270 result = convert('0x123456789ABCDEF0'); 271 assertEquals(String.fromCharCode.apply(null, 272 [0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]), result); 273 274 // Capitalization should not matter. 275 result = convert('0x0000abcdefABCDEF'); 276 assertEquals(String.fromCharCode.apply(null, 277 [0xEF, 0xCD, 0xAB, 0xEF, 0xCD, 0xAB, 0x00, 0x00]), result); 278 }); 279 280 281 /** 282 * Going from numbers to hash strings should be lossless for up to 53 bits of 283 * precision. 284 */ 285 it('testNumberToHashConversion', function() { 286 var result; 287 var convert = jspb.utils.numberToHash64; 288 289 result = convert(0x0000000000000); 290 assertEquals('0x0000000000000000', jspb.utils.hash64ToHexString(result)); 291 292 result = convert(0xFFFFFFFFFFFFF); 293 assertEquals('0x000fffffffffffff', jspb.utils.hash64ToHexString(result)); 294 295 result = convert(0x123456789ABCD); 296 assertEquals('0x000123456789abcd', jspb.utils.hash64ToHexString(result)); 297 298 result = convert(0xDCBA987654321); 299 assertEquals('0x000dcba987654321', jspb.utils.hash64ToHexString(result)); 300 301 // 53 bits of precision should not be truncated. 302 result = convert(0x10000000000001); 303 assertEquals('0x0010000000000001', jspb.utils.hash64ToHexString(result)); 304 305 // 54 bits of precision should be truncated. 306 result = convert(0x20000000000001); 307 assertNotEquals( 308 '0x0020000000000001', jspb.utils.hash64ToHexString(result)); 309 }); 310 311 312 /** 313 * Sanity check the behavior of Javascript's strings when doing funny things 314 * with unicode characters. 315 */ 316 it('sanityCheckUnicodeStrings', function() { 317 var strings = new Array(65536); 318 319 // All possible unsigned 16-bit values should be storable in a string, they 320 // shouldn't do weird things with the length of the string, and they should 321 // come back out of the string unchanged. 322 for (var i = 0; i < 65536; i++) { 323 strings[i] = 'a' + String.fromCharCode(i) + 'a'; 324 if (3 != strings[i].length) throw 'fail!'; 325 if (i != strings[i].charCodeAt(1)) throw 'fail!'; 326 } 327 328 // Each unicode character should compare equal to itself and not equal to a 329 // different unicode character. 330 for (var i = 0; i < 65536; i++) { 331 if (strings[i] != strings[i]) throw 'fail!'; 332 if (strings[i] == strings[(i + 1) % 65536]) throw 'fail!'; 333 } 334 }); 335 336 337 /** 338 * Tests conversion from 32-bit floating point numbers to split64 numbers. 339 */ 340 it('testFloat32ToSplit64', function() { 341 var f32_eps = jspb.BinaryConstants.FLOAT32_EPS; 342 var f32_min = jspb.BinaryConstants.FLOAT32_MIN; 343 var f32_max = jspb.BinaryConstants.FLOAT32_MAX; 344 345 // NaN. 346 jspb.utils.splitFloat32(NaN); 347 if (!isNaN(jspb.utils.joinFloat32(jspb.utils.split64Low, 348 jspb.utils.split64High))) { 349 throw 'fail!'; 350 } 351 352 /** 353 * @param {number} x 354 * @param {number=} opt_bits 355 */ 356 function test(x, opt_bits) { 357 jspb.utils.splitFloat32(x); 358 if (goog.isDef(opt_bits)) { 359 if (opt_bits != jspb.utils.split64Low) throw 'fail!'; 360 } 361 if (truncate(x) != jspb.utils.joinFloat32(jspb.utils.split64Low, 362 jspb.utils.split64High)) { 363 throw 'fail!'; 364 } 365 } 366 367 // Positive and negative infinity. 368 test(Infinity, 0x7f800000); 369 test(-Infinity, 0xff800000); 370 371 // Positive and negative zero. 372 test(0, 0x00000000); 373 test(-0, 0x80000000); 374 375 // Positive and negative epsilon. 376 test(f32_eps, 0x00000001); 377 test(-f32_eps, 0x80000001); 378 379 // Positive and negative min. 380 test(f32_min, 0x00800000); 381 test(-f32_min, 0x80800000); 382 383 // Positive and negative max. 384 test(f32_max, 0x7F7FFFFF); 385 test(-f32_max, 0xFF7FFFFF); 386 387 // Various positive values. 388 var cursor = f32_eps * 10; 389 while (cursor != Infinity) { 390 test(cursor); 391 cursor *= 1.1; 392 } 393 394 // Various negative values. 395 cursor = -f32_eps * 10; 396 while (cursor != -Infinity) { 397 test(cursor); 398 cursor *= 1.1; 399 } 400 }); 401 402 403 /** 404 * Tests conversion from 64-bit floating point numbers to split64 numbers. 405 */ 406 it('testFloat64ToSplit64', function() { 407 var f64_eps = jspb.BinaryConstants.FLOAT64_EPS; 408 var f64_min = jspb.BinaryConstants.FLOAT64_MIN; 409 var f64_max = jspb.BinaryConstants.FLOAT64_MAX; 410 411 // NaN. 412 jspb.utils.splitFloat64(NaN); 413 if (!isNaN(jspb.utils.joinFloat64(jspb.utils.split64Low, 414 jspb.utils.split64High))) { 415 throw 'fail!'; 416 } 417 418 /** 419 * @param {number} x 420 * @param {number=} opt_highBits 421 * @param {number=} opt_lowBits 422 */ 423 function test(x, opt_highBits, opt_lowBits) { 424 jspb.utils.splitFloat64(x); 425 if (goog.isDef(opt_highBits)) { 426 if (opt_highBits != jspb.utils.split64High) throw 'fail!'; 427 } 428 if (goog.isDef(opt_lowBits)) { 429 if (opt_lowBits != jspb.utils.split64Low) throw 'fail!'; 430 } 431 if (x != jspb.utils.joinFloat64(jspb.utils.split64Low, 432 jspb.utils.split64High)) { 433 throw 'fail!'; 434 } 435 } 436 437 // Positive and negative infinity. 438 test(Infinity, 0x7ff00000, 0x00000000); 439 test(-Infinity, 0xfff00000, 0x00000000); 440 441 // Positive and negative zero. 442 test(0, 0x00000000, 0x00000000); 443 test(-0, 0x80000000, 0x00000000); 444 445 // Positive and negative epsilon. 446 test(f64_eps, 0x00000000, 0x00000001); 447 test(-f64_eps, 0x80000000, 0x00000001); 448 449 // Positive and negative min. 450 test(f64_min, 0x00100000, 0x00000000); 451 test(-f64_min, 0x80100000, 0x00000000); 452 453 // Positive and negative max. 454 test(f64_max, 0x7FEFFFFF, 0xFFFFFFFF); 455 test(-f64_max, 0xFFEFFFFF, 0xFFFFFFFF); 456 457 // Various positive values. 458 var cursor = f64_eps * 10; 459 while (cursor != Infinity) { 460 test(cursor); 461 cursor *= 1.1; 462 } 463 464 // Various negative values. 465 cursor = -f64_eps * 10; 466 while (cursor != -Infinity) { 467 test(cursor); 468 cursor *= 1.1; 469 } 470 }); 471 472 473 /** 474 * Tests counting packed varints. 475 */ 476 it('testCountVarints', function() { 477 var values = []; 478 for (var i = 1; i < 1000000000; i *= 1.1) { 479 values.push(Math.floor(i)); 480 } 481 482 var writer = new jspb.BinaryWriter(); 483 writer.writePackedUint64(1, values); 484 485 var buffer = new Uint8Array(writer.getResultBuffer()); 486 487 // We should have two more varints than we started with - one for the field 488 // tag, one for the packed length. 489 assertEquals(values.length + 2, 490 jspb.utils.countVarints(buffer, 0, buffer.length)); 491 }); 492 493 494 /** 495 * Tests counting matching varint fields. 496 */ 497 it('testCountVarintFields', function() { 498 var writer = new jspb.BinaryWriter(); 499 500 var count = 0; 501 for (var i = 1; i < 1000000000; i *= 1.1) { 502 writer.writeUint64(1, Math.floor(i)); 503 count++; 504 } 505 writer.writeString(2, 'terminator'); 506 507 var buffer = new Uint8Array(writer.getResultBuffer()); 508 assertEquals(count, 509 jspb.utils.countVarintFields(buffer, 0, buffer.length, 1)); 510 511 writer = new jspb.BinaryWriter(); 512 513 count = 0; 514 for (var i = 1; i < 1000000000; i *= 1.1) { 515 writer.writeUint64(123456789, Math.floor(i)); 516 count++; 517 } 518 writer.writeString(2, 'terminator'); 519 520 buffer = new Uint8Array(writer.getResultBuffer()); 521 assertEquals(count, 522 jspb.utils.countVarintFields(buffer, 0, buffer.length, 123456789)); 523 }); 524 525 526 /** 527 * Tests counting matching fixed32 fields. 528 */ 529 it('testCountFixed32Fields', function() { 530 var writer = new jspb.BinaryWriter(); 531 532 var count = 0; 533 for (var i = 1; i < 1000000000; i *= 1.1) { 534 writer.writeFixed32(1, Math.floor(i)); 535 count++; 536 } 537 writer.writeString(2, 'terminator'); 538 539 var buffer = new Uint8Array(writer.getResultBuffer()); 540 assertEquals(count, 541 jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 1)); 542 543 writer = new jspb.BinaryWriter(); 544 545 count = 0; 546 for (var i = 1; i < 1000000000; i *= 1.1) { 547 writer.writeFixed32(123456789, Math.floor(i)); 548 count++; 549 } 550 writer.writeString(2, 'terminator'); 551 552 buffer = new Uint8Array(writer.getResultBuffer()); 553 assertEquals(count, 554 jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 123456789)); 555 }); 556 557 558 /** 559 * Tests counting matching fixed64 fields. 560 */ 561 it('testCountFixed64Fields', function() { 562 var writer = new jspb.BinaryWriter(); 563 564 var count = 0; 565 for (var i = 1; i < 1000000000; i *= 1.1) { 566 writer.writeDouble(1, i); 567 count++; 568 } 569 writer.writeString(2, 'terminator'); 570 571 var buffer = new Uint8Array(writer.getResultBuffer()); 572 assertEquals(count, 573 jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 1)); 574 575 writer = new jspb.BinaryWriter(); 576 577 count = 0; 578 for (var i = 1; i < 1000000000; i *= 1.1) { 579 writer.writeDouble(123456789, i); 580 count++; 581 } 582 writer.writeString(2, 'terminator'); 583 584 buffer = new Uint8Array(writer.getResultBuffer()); 585 assertEquals(count, 586 jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 123456789)); 587 }); 588 589 590 /** 591 * Tests counting matching delimited fields. 592 */ 593 it('testCountDelimitedFields', function() { 594 var writer = new jspb.BinaryWriter(); 595 596 var count = 0; 597 for (var i = 1; i < 1000; i *= 1.1) { 598 writer.writeBytes(1, [Math.floor(i)]); 599 count++; 600 } 601 writer.writeString(2, 'terminator'); 602 603 var buffer = new Uint8Array(writer.getResultBuffer()); 604 assertEquals(count, 605 jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 1)); 606 607 writer = new jspb.BinaryWriter(); 608 609 count = 0; 610 for (var i = 1; i < 1000; i *= 1.1) { 611 writer.writeBytes(123456789, [Math.floor(i)]); 612 count++; 613 } 614 writer.writeString(2, 'terminator'); 615 616 buffer = new Uint8Array(writer.getResultBuffer()); 617 assertEquals(count, 618 jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 123456789)); 619 }); 620 621 622 /** 623 * Tests byte format for debug strings. 624 */ 625 it('testDebugBytesToTextFormat', function() { 626 assertEquals('""', jspb.utils.debugBytesToTextFormat(null)); 627 assertEquals('"\\x00\\x10\\xff"', 628 jspb.utils.debugBytesToTextFormat([0, 16, 255])); 629 }); 630 631 632 /** 633 * Tests converting byte blob sources into byte blobs. 634 */ 635 it('testByteSourceToUint8Array', function() { 636 var convert = jspb.utils.byteSourceToUint8Array; 637 638 var sourceData = []; 639 for (var i = 0; i < 256; i++) { 640 sourceData.push(i); 641 } 642 643 var sourceBytes = new Uint8Array(sourceData); 644 var sourceBuffer = sourceBytes.buffer; 645 var sourceBase64 = goog.crypt.base64.encodeByteArray(sourceData); 646 var sourceString = String.fromCharCode.apply(null, sourceData); 647 648 function check(result) { 649 assertEquals(Uint8Array, result.constructor); 650 assertEquals(sourceData.length, result.length); 651 for (var i = 0; i < result.length; i++) { 652 assertEquals(sourceData[i], result[i]); 653 } 654 } 655 656 // Converting Uint8Arrays into Uint8Arrays should be a no-op. 657 assertEquals(sourceBytes, convert(sourceBytes)); 658 659 // Converting Array.<numbers> into Uint8Arrays should work. 660 check(convert(sourceData)); 661 662 // Converting ArrayBuffers into Uint8Arrays should work. 663 check(convert(sourceBuffer)); 664 665 // Converting base64-encoded strings into Uint8Arrays should work. 666 check(convert(sourceBase64)); 667 }); 668}); 669