1/** 2 * @fileoverview Tests for kernel.js. 3 */ 4goog.module('protobuf.runtime.KernelTest'); 5 6goog.setTestOnly(); 7 8const ByteString = goog.require('protobuf.ByteString'); 9const Int64 = goog.require('protobuf.Int64'); 10const InternalMessage = goog.require('protobuf.binary.InternalMessage'); 11const Kernel = goog.require('protobuf.runtime.Kernel'); 12const TestMessage = goog.require('protobuf.testing.binary.TestMessage'); 13// Note to the reader: 14// Since the lazy accessor behavior changes with the checking level some of the 15// tests in this file have to know which checking level is enable to make 16// correct assertions. 17const {CHECK_BOUNDS, CHECK_CRITICAL_STATE, CHECK_CRITICAL_TYPE, CHECK_TYPE, MAX_FIELD_NUMBER} = goog.require('protobuf.internal.checks'); 18 19/** 20 * @param {...number} bytes 21 * @return {!ArrayBuffer} 22 */ 23function createArrayBuffer(...bytes) { 24 return new Uint8Array(bytes).buffer; 25} 26 27describe('Kernel', () => { 28 it('encodes none for the empty input', () => { 29 const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); 30 expect(accessor.serialize()).toEqual(new ArrayBuffer(0)); 31 }); 32 33 it('encodes and decodes max field number', () => { 34 const accessor = Kernel.fromArrayBuffer( 35 createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x0F, 0x01)); 36 expect(accessor.getBoolWithDefault(MAX_FIELD_NUMBER)).toBe(true); 37 accessor.setBool(MAX_FIELD_NUMBER, false); 38 expect(accessor.serialize()) 39 .toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x0F, 0x00)); 40 }); 41 42 it('uses the default pivot point', () => { 43 const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); 44 expect(accessor.getPivot()).toBe(24); 45 }); 46 47 it('makes the pivot point configurable', () => { 48 const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0), 50); 49 expect(accessor.getPivot()).toBe(50); 50 }); 51}); 52 53describe('Kernel hasFieldNumber', () => { 54 it('returns false for empty input', () => { 55 const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); 56 expect(accessor.hasFieldNumber(1)).toBe(false); 57 }); 58 59 it('returns true for non-empty input', () => { 60 const bytes = createArrayBuffer(0x08, 0x01); 61 const accessor = Kernel.fromArrayBuffer(bytes); 62 expect(accessor.hasFieldNumber(1)).toBe(true); 63 }); 64 65 it('returns false for empty array', () => { 66 const accessor = Kernel.createEmpty(); 67 accessor.setPackedBoolIterable(1, []); 68 expect(accessor.hasFieldNumber(1)).toBe(false); 69 }); 70 71 it('returns true for non-empty array', () => { 72 const accessor = Kernel.createEmpty(); 73 accessor.setPackedBoolIterable(1, [true]); 74 expect(accessor.hasFieldNumber(1)).toBe(true); 75 }); 76 77 it('updates value after write', () => { 78 const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); 79 expect(accessor.hasFieldNumber(1)).toBe(false); 80 accessor.setBool(1, false); 81 expect(accessor.hasFieldNumber(1)).toBe(true); 82 }); 83}); 84 85describe('Kernel clear field does', () => { 86 it('clear the field set', () => { 87 const accessor = Kernel.createEmpty(); 88 accessor.setBool(1, true); 89 accessor.clearField(1); 90 91 expect(accessor.hasFieldNumber(1)).toEqual(false); 92 expect(accessor.serialize()).toEqual(new ArrayBuffer(0)); 93 expect(accessor.getBoolWithDefault(1)).toEqual(false); 94 }); 95 96 it('clear the field decoded', () => { 97 const bytes = createArrayBuffer(0x08, 0x01); 98 const accessor = Kernel.fromArrayBuffer(bytes); 99 accessor.clearField(1); 100 101 expect(accessor.hasFieldNumber(1)).toEqual(false); 102 expect(accessor.serialize()).toEqual(new ArrayBuffer(0)); 103 expect(accessor.getBoolWithDefault(1)).toEqual(false); 104 }); 105 106 it('clear the field read', () => { 107 const bytes = createArrayBuffer(0x08, 0x01); 108 const accessor = Kernel.fromArrayBuffer(bytes); 109 expect(accessor.getBoolWithDefault(1)).toEqual(true); 110 accessor.clearField(1); 111 112 expect(accessor.hasFieldNumber(1)).toEqual(false); 113 expect(accessor.serialize()).toEqual(new ArrayBuffer(0)); 114 expect(accessor.getBoolWithDefault(1)).toEqual(false); 115 }); 116 117 it('clear set and copied fields without affecting the old', () => { 118 const accessor = Kernel.createEmpty(); 119 accessor.setBool(1, true); 120 121 const clonedAccessor = accessor.shallowCopy(); 122 clonedAccessor.clearField(1); 123 124 expect(accessor.hasFieldNumber(1)).toEqual(true); 125 expect(accessor.getBoolWithDefault(1)).toEqual(true); 126 expect(clonedAccessor.hasFieldNumber(1)).toEqual(false); 127 expect(clonedAccessor.serialize()).toEqual(new ArrayBuffer(0)); 128 expect(clonedAccessor.getBoolWithDefault(1)).toEqual(false); 129 }); 130 131 it('clear decoded and copied fields without affecting the old', () => { 132 const bytes = createArrayBuffer(0x08, 0x01); 133 const accessor = Kernel.fromArrayBuffer(bytes); 134 135 const clonedAccessor = accessor.shallowCopy(); 136 clonedAccessor.clearField(1); 137 138 expect(accessor.hasFieldNumber(1)).toEqual(true); 139 expect(accessor.getBoolWithDefault(1)).toEqual(true); 140 expect(clonedAccessor.hasFieldNumber(1)).toEqual(false); 141 expect(clonedAccessor.serialize()).toEqual(new ArrayBuffer(0)); 142 expect(clonedAccessor.getBoolWithDefault(1)).toEqual(false); 143 }); 144 145 it('clear read and copied fields without affecting the old', () => { 146 const bytes = createArrayBuffer(0x08, 0x01); 147 const accessor = Kernel.fromArrayBuffer(bytes); 148 expect(accessor.getBoolWithDefault(1)).toEqual(true); 149 150 const clonedAccessor = accessor.shallowCopy(); 151 clonedAccessor.clearField(1); 152 153 expect(accessor.hasFieldNumber(1)).toEqual(true); 154 expect(accessor.getBoolWithDefault(1)).toEqual(true); 155 expect(clonedAccessor.hasFieldNumber(1)).toEqual(false); 156 expect(clonedAccessor.serialize()).toEqual(new ArrayBuffer(0)); 157 expect(clonedAccessor.getBoolWithDefault(1)).toEqual(false); 158 }); 159 160 it('clear the max field number', () => { 161 const accessor = Kernel.createEmpty(); 162 accessor.setBool(MAX_FIELD_NUMBER, true); 163 164 accessor.clearField(MAX_FIELD_NUMBER); 165 166 expect(accessor.hasFieldNumber(MAX_FIELD_NUMBER)).toEqual(false); 167 expect(accessor.getBoolWithDefault(MAX_FIELD_NUMBER)).toEqual(false); 168 }); 169}); 170 171describe('Kernel shallow copy does', () => { 172 it('work for singular fields', () => { 173 const accessor = Kernel.createEmpty(); 174 accessor.setBool(1, true); 175 accessor.setBool(MAX_FIELD_NUMBER, true); 176 const clonedAccessor = accessor.shallowCopy(); 177 expect(clonedAccessor.getBoolWithDefault(1)).toEqual(true); 178 expect(clonedAccessor.getBoolWithDefault(MAX_FIELD_NUMBER)).toEqual(true); 179 180 accessor.setBool(1, false); 181 accessor.setBool(MAX_FIELD_NUMBER, false); 182 expect(clonedAccessor.getBoolWithDefault(1)).toEqual(true); 183 expect(clonedAccessor.getBoolWithDefault(MAX_FIELD_NUMBER)).toEqual(true); 184 }); 185 186 it('work for repeated fields', () => { 187 const accessor = Kernel.createEmpty(); 188 189 accessor.addUnpackedBoolIterable(2, [true, true]); 190 191 const clonedAccessor = accessor.shallowCopy(); 192 193 // Modify a repeated field after clone 194 accessor.addUnpackedBoolElement(2, true); 195 196 const array = Array.from(clonedAccessor.getRepeatedBoolIterable(2)); 197 expect(array).toEqual([true, true]); 198 }); 199 200 it('work for repeated fields', () => { 201 const accessor = Kernel.createEmpty(); 202 203 accessor.addUnpackedBoolIterable(2, [true, true]); 204 205 const clonedAccessor = accessor.shallowCopy(); 206 207 // Modify a repeated field after clone 208 accessor.addUnpackedBoolElement(2, true); 209 210 const array = Array.from(clonedAccessor.getRepeatedBoolIterable(2)); 211 expect(array).toEqual([true, true]); 212 }); 213 214 it('return the correct bytes after serialization', () => { 215 const bytes = createArrayBuffer(0x08, 0x01, 0x10, 0x01); 216 const accessor = Kernel.fromArrayBuffer(bytes, /* pivot= */ 1); 217 const clonedAccessor = accessor.shallowCopy(); 218 219 accessor.setBool(1, false); 220 221 expect(clonedAccessor.getBoolWithDefault(1)).toEqual(true); 222 expect(clonedAccessor.serialize()).toEqual(bytes); 223 }); 224}); 225 226describe('Kernel for singular boolean does', () => { 227 it('return false for the empty input', () => { 228 const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); 229 expect(accessor.getBoolWithDefault( 230 /* fieldNumber= */ 1)) 231 .toBe(false); 232 }); 233 234 it('return the value from the input', () => { 235 const bytes = createArrayBuffer(0x08, 0x01); 236 const accessor = Kernel.fromArrayBuffer(bytes); 237 expect(accessor.getBoolWithDefault( 238 /* fieldNumber= */ 1)) 239 .toBe(true); 240 }); 241 242 it('encode the value from the input', () => { 243 const bytes = createArrayBuffer(0x08, 0x01); 244 const accessor = Kernel.fromArrayBuffer(bytes); 245 expect(accessor.serialize()).toEqual(bytes); 246 }); 247 248 it('encode the value from the input after read', () => { 249 const bytes = createArrayBuffer(0x08, 0x01); 250 const accessor = Kernel.fromArrayBuffer(bytes); 251 accessor.getBoolWithDefault( 252 /* fieldNumber= */ 1); 253 expect(accessor.serialize()).toEqual(bytes); 254 }); 255 256 it('return the value from multiple inputs', () => { 257 const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); 258 const accessor = Kernel.fromArrayBuffer(bytes); 259 expect(accessor.getBoolWithDefault( 260 /* fieldNumber= */ 1)) 261 .toBe(false); 262 }); 263 264 it('encode the value from multiple inputs', () => { 265 const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); 266 const accessor = Kernel.fromArrayBuffer(bytes); 267 expect(accessor.serialize()).toEqual(bytes); 268 }); 269 270 it('encode the value from multiple inputs after read', () => { 271 const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); 272 const accessor = Kernel.fromArrayBuffer(bytes); 273 accessor.getBoolWithDefault(/* fieldNumber= */ 1); 274 expect(accessor.serialize()).toEqual(bytes); 275 }); 276 277 it('return the value from setter', () => { 278 const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); 279 const accessor = Kernel.fromArrayBuffer(bytes); 280 accessor.setBool(1, true); 281 expect(accessor.getBoolWithDefault( 282 /* fieldNumber= */ 1)) 283 .toBe(true); 284 }); 285 286 it('encode the value from setter', () => { 287 const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); 288 const accessor = Kernel.fromArrayBuffer(bytes); 289 const newBytes = createArrayBuffer(0x08, 0x01); 290 accessor.setBool(1, true); 291 expect(accessor.serialize()).toEqual(newBytes); 292 }); 293 294 it('return the bool value from cache', () => { 295 const bytes = createArrayBuffer(0x08, 0x01); 296 const accessor = Kernel.fromArrayBuffer(bytes); 297 expect(accessor.getBoolWithDefault( 298 /* fieldNumber= */ 1)) 299 .toBe(true); 300 // Make sure the value is cached. 301 bytes[1] = 0x00; 302 expect(accessor.getBoolWithDefault( 303 /* fieldNumber= */ 1)) 304 .toBe(true); 305 }); 306 307 it('fail when getting bool value with other wire types', () => { 308 const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 309 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); 310 if (CHECK_CRITICAL_TYPE) { 311 expect(() => { 312 accessor.getBoolWithDefault(/* fieldNumber= */ 1); 313 }).toThrowError('Expected wire type: 0 but found: 1'); 314 } else { 315 // Note in unchecked mode we produce invalid output for invalid inputs. 316 // This test just documents our behavior in those cases. 317 // These values might change at any point and are not considered 318 // what the implementation should be doing here. 319 expect(accessor.getBoolWithDefault( 320 /* fieldNumber= */ 1)) 321 .toBe(true); 322 } 323 }); 324 325 it('fail when setting bool value with out-of-range field number', () => { 326 const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); 327 if (CHECK_TYPE) { 328 expect(() => accessor.setBool(MAX_FIELD_NUMBER + 1, false)) 329 .toThrowError('Field number is out of range: 536870912'); 330 } else { 331 // Note in unchecked mode we produce invalid output for invalid inputs. 332 // This test just documents our behavior in those cases. 333 // These values might change at any point and are not considered 334 // what the implementation should be doing here. 335 accessor.setBool(MAX_FIELD_NUMBER + 1, false); 336 expect(accessor.getBoolWithDefault(MAX_FIELD_NUMBER + 1)).toBe(false); 337 } 338 }); 339 340 it('fail when setting bool value with number value', () => { 341 const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); 342 const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); 343 if (CHECK_CRITICAL_TYPE) { 344 expect(() => accessor.setBool(1, fakeBoolean)) 345 .toThrowError('Must be a boolean, but got: 2'); 346 } else { 347 // Note in unchecked mode we produce invalid output for invalid inputs. 348 // This test just documents our behavior in those cases. 349 // These values might change at any point and are not considered 350 // what the implementation should be doing here. 351 accessor.setBool(1, fakeBoolean); 352 expect(accessor.getBoolWithDefault( 353 /* fieldNumber= */ 1)) 354 .toBe(2); 355 } 356 }); 357}); 358 359describe('Kernel for singular message does', () => { 360 it('return message from the input', () => { 361 const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); 362 const accessor = Kernel.fromArrayBuffer(bytes); 363 const msg = accessor.getMessageOrNull(1, TestMessage.instanceCreator); 364 expect(msg.getBoolWithDefault(1, false)).toBe(true); 365 }); 366 367 it('return message from the input when pivot is set', () => { 368 const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); 369 const accessor = Kernel.fromArrayBuffer(bytes, /* pivot= */ 0); 370 const msg = accessor.getMessageOrNull(1, TestMessage.instanceCreator); 371 expect(msg.getBoolWithDefault(1, false)).toBe(true); 372 }); 373 374 it('encode message from the input', () => { 375 const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); 376 const accessor = Kernel.fromArrayBuffer(bytes); 377 expect(accessor.serialize()).toEqual(bytes); 378 }); 379 380 it('encode message from the input after read', () => { 381 const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); 382 const accessor = Kernel.fromArrayBuffer(bytes); 383 accessor.getMessageOrNull(1, TestMessage.instanceCreator); 384 expect(accessor.serialize()).toEqual(bytes); 385 }); 386 387 it('return message from multiple inputs', () => { 388 const bytes = 389 createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x10, 0x01); 390 const accessor = Kernel.fromArrayBuffer(bytes); 391 const msg = accessor.getMessageOrNull(1, TestMessage.instanceCreator); 392 expect(msg.getBoolWithDefault(1, false)).toBe(true); 393 expect(msg.getBoolWithDefault(2, false)).toBe(true); 394 }); 395 396 it('encode message from multiple inputs', () => { 397 const bytes = 398 createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x10, 0x01); 399 const accessor = Kernel.fromArrayBuffer(bytes); 400 expect(accessor.serialize()).toEqual(bytes); 401 }); 402 403 it('encode message merged from multiple inputs after read', () => { 404 const bytes = 405 createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x10, 0x01); 406 const expected = createArrayBuffer(0x0A, 0x04, 0x08, 0x01, 0x10, 0x01); 407 const accessor = Kernel.fromArrayBuffer(bytes); 408 accessor.getMessageOrNull(1, TestMessage.instanceCreator); 409 expect(accessor.serialize()).toEqual(expected); 410 }); 411 412 it('return null for generic accessor', () => { 413 const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); 414 const accessor = Kernel.fromArrayBuffer(bytes); 415 const accessor1 = accessor.getMessageAccessorOrNull(7); 416 expect(accessor1).toBe(null); 417 }); 418 419 it('return null for generic accessor when pivot is set', () => { 420 const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); 421 const accessor = Kernel.fromArrayBuffer(bytes); 422 const accessor1 = accessor.getMessageAccessorOrNull(7, /* pivot= */ 0); 423 expect(accessor1).toBe(null); 424 }); 425 426 it('return generic accessor from the input', () => { 427 const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); 428 const accessor = Kernel.fromArrayBuffer(bytes); 429 const accessor1 = accessor.getMessageAccessorOrNull(1); 430 expect(accessor1.getBoolWithDefault(1, false)).toBe(true); 431 // Second call returns a new instance, isn't cached. 432 const accessor2 = accessor.getMessageAccessorOrNull(1); 433 expect(accessor2.getBoolWithDefault(1, false)).toBe(true); 434 expect(accessor2).not.toBe(accessor1); 435 }); 436 437 it('return generic accessor from the cached input', () => { 438 const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); 439 const accessor = Kernel.fromArrayBuffer(bytes); 440 const wrappedMessage = 441 accessor.getMessageOrNull(1, TestMessage.instanceCreator); 442 443 // Returns accessor from the cached wrapper instance. 444 const accessor1 = accessor.getMessageAccessorOrNull(1); 445 expect(accessor1.getBoolWithDefault(1, false)).toBe(true); 446 expect(accessor1).toBe( 447 (/** @type {!InternalMessage} */ (wrappedMessage)).internalGetKernel()); 448 449 // Second call returns exact same instance. 450 const accessor2 = accessor.getMessageAccessorOrNull(1); 451 expect(accessor2.getBoolWithDefault(1, false)).toBe(true); 452 expect(accessor2).toBe( 453 (/** @type {!InternalMessage} */ (wrappedMessage)).internalGetKernel()); 454 expect(accessor2).toBe(accessor1); 455 }); 456 457 it('return message from setter', () => { 458 const bytes = createArrayBuffer(0x08, 0x01); 459 const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); 460 const subaccessor = Kernel.fromArrayBuffer(bytes); 461 const submsg1 = new TestMessage(subaccessor); 462 accessor.setMessage(1, submsg1); 463 const submsg2 = accessor.getMessage(1, TestMessage.instanceCreator); 464 expect(submsg1).toBe(submsg2); 465 }); 466 467 it('encode message from setter', () => { 468 const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); 469 const subaccessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); 470 const subsubaccessor = 471 Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); 472 const subsubmsg = new TestMessage(subsubaccessor); 473 subaccessor.setMessage(1, subsubmsg); 474 const submsg = new TestMessage(subaccessor); 475 accessor.setMessage(1, submsg); 476 const expected = createArrayBuffer(0x0A, 0x04, 0x0A, 0x02, 0x08, 0x01); 477 expect(accessor.serialize()).toEqual(expected); 478 }); 479 480 it('encode message with multiple submessage from setter', () => { 481 const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); 482 const subaccessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); 483 const subsubaccessor1 = 484 Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); 485 const subsubaccessor2 = 486 Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x02)); 487 488 const subsubmsg1 = new TestMessage(subsubaccessor1); 489 const subsubmsg2 = new TestMessage(subsubaccessor2); 490 491 subaccessor.setMessage(1, subsubmsg1); 492 subaccessor.setMessage(2, subsubmsg2); 493 494 const submsg = new TestMessage(subaccessor); 495 accessor.setMessage(1, submsg); 496 497 const expected = createArrayBuffer( 498 0x0A, 0x08, 0x0A, 0x02, 0x08, 0x01, 0x12, 0x02, 0x08, 0x02); 499 expect(accessor.serialize()).toEqual(expected); 500 }); 501 502 it('leave hasFieldNumber unchanged after getMessageOrNull', () => { 503 const accessor = Kernel.createEmpty(); 504 expect(accessor.hasFieldNumber(1)).toBe(false); 505 expect(accessor.getMessageOrNull(1, TestMessage.instanceCreator)) 506 .toBe(null); 507 expect(accessor.hasFieldNumber(1)).toBe(false); 508 }); 509 510 it('serialize changes to submessages made with getMessageOrNull', () => { 511 const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); 512 const accessor = Kernel.fromArrayBuffer(intTwoBytes); 513 const mutableSubMessage = 514 accessor.getMessageOrNull(1, TestMessage.instanceCreator); 515 mutableSubMessage.setInt32(1, 10); 516 const intTenBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x0A); 517 expect(accessor.serialize()).toEqual(intTenBytes); 518 }); 519 520 it('serialize additions to submessages made with getMessageOrNull', () => { 521 const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); 522 const accessor = Kernel.fromArrayBuffer(intTwoBytes); 523 const mutableSubMessage = 524 accessor.getMessageOrNull(1, TestMessage.instanceCreator); 525 mutableSubMessage.setInt32(2, 3); 526 // Sub message contains the original field, plus the new one. 527 expect(accessor.serialize()) 528 .toEqual(createArrayBuffer(0x0A, 0x04, 0x08, 0x02, 0x10, 0x03)); 529 }); 530 531 it('fail with getMessageOrNull if immutable message exist in cache', () => { 532 const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); 533 const accessor = Kernel.fromArrayBuffer(intTwoBytes); 534 535 const readOnly = accessor.getMessage(1, TestMessage.instanceCreator); 536 if (CHECK_TYPE) { 537 expect(() => accessor.getMessageOrNull(1, TestMessage.instanceCreator)) 538 .toThrow(); 539 } else { 540 const mutableSubMessage = 541 accessor.getMessageOrNull(1, TestMessage.instanceCreator); 542 // The instance returned by getMessageOrNull is the exact same instance. 543 expect(mutableSubMessage).toBe(readOnly); 544 545 // Serializing the submessage does not write the changes 546 mutableSubMessage.setInt32(1, 0); 547 expect(accessor.serialize()).toEqual(intTwoBytes); 548 } 549 }); 550 551 it('change hasFieldNumber after getMessageAttach', () => { 552 const accessor = Kernel.createEmpty(); 553 expect(accessor.hasFieldNumber(1)).toBe(false); 554 expect(accessor.getMessageAttach(1, TestMessage.instanceCreator)) 555 .not.toBe(null); 556 expect(accessor.hasFieldNumber(1)).toBe(true); 557 }); 558 559 it('change hasFieldNumber after getMessageAttach when pivot is set', () => { 560 const accessor = Kernel.createEmpty(); 561 expect(accessor.hasFieldNumber(1)).toBe(false); 562 expect(accessor.getMessageAttach( 563 1, TestMessage.instanceCreator, /* pivot= */ 1)) 564 .not.toBe(null); 565 expect(accessor.hasFieldNumber(1)).toBe(true); 566 }); 567 568 it('serialize submessages made with getMessageAttach', () => { 569 const accessor = Kernel.createEmpty(); 570 const mutableSubMessage = 571 accessor.getMessageAttach(1, TestMessage.instanceCreator); 572 mutableSubMessage.setInt32(1, 10); 573 const intTenBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x0A); 574 expect(accessor.serialize()).toEqual(intTenBytes); 575 }); 576 577 it('serialize additions to submessages using getMessageAttach', () => { 578 const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); 579 const accessor = Kernel.fromArrayBuffer(intTwoBytes); 580 const mutableSubMessage = 581 accessor.getMessageAttach(1, TestMessage.instanceCreator); 582 mutableSubMessage.setInt32(2, 3); 583 // Sub message contains the original field, plus the new one. 584 expect(accessor.serialize()) 585 .toEqual(createArrayBuffer(0x0A, 0x04, 0x08, 0x02, 0x10, 0x03)); 586 }); 587 588 it('fail with getMessageAttach if immutable message exist in cache', () => { 589 const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); 590 const accessor = Kernel.fromArrayBuffer(intTwoBytes); 591 592 const readOnly = accessor.getMessage(1, TestMessage.instanceCreator); 593 if (CHECK_TYPE) { 594 expect(() => accessor.getMessageAttach(1, TestMessage.instanceCreator)) 595 .toThrow(); 596 } else { 597 const mutableSubMessage = 598 accessor.getMessageAttach(1, TestMessage.instanceCreator); 599 // The instance returned by getMessageOrNull is the exact same instance. 600 expect(mutableSubMessage).toBe(readOnly); 601 602 // Serializing the submessage does not write the changes 603 mutableSubMessage.setInt32(1, 0); 604 expect(accessor.serialize()).toEqual(intTwoBytes); 605 } 606 }); 607 608 it('read default message return empty message with getMessage', () => { 609 const bytes = new ArrayBuffer(0); 610 const accessor = Kernel.fromArrayBuffer(bytes); 611 expect(accessor.getMessage(1, TestMessage.instanceCreator)).toBeTruthy(); 612 expect(accessor.getMessage(1, TestMessage.instanceCreator).serialize()) 613 .toEqual(bytes); 614 }); 615 616 it('read default message return null with getMessageOrNull', () => { 617 const bytes = new ArrayBuffer(0); 618 const accessor = Kernel.fromArrayBuffer(bytes); 619 expect(accessor.getMessageOrNull(1, TestMessage.instanceCreator)) 620 .toBe(null); 621 }); 622 623 it('read message preserve reference equality', () => { 624 const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); 625 const accessor = Kernel.fromArrayBuffer(bytes); 626 const msg1 = accessor.getMessageOrNull(1, TestMessage.instanceCreator); 627 const msg2 = accessor.getMessageOrNull(1, TestMessage.instanceCreator); 628 const msg3 = accessor.getMessageAttach(1, TestMessage.instanceCreator); 629 expect(msg1).toBe(msg2); 630 expect(msg1).toBe(msg3); 631 }); 632 633 it('fail when getting message with other wire types', () => { 634 const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); 635 expect(() => accessor.getMessageOrNull(1, TestMessage.instanceCreator)) 636 .toThrow(); 637 }); 638 639 it('fail when submessage has incomplete data', () => { 640 const accessor = 641 Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x08)); 642 expect(() => accessor.getMessageOrNull(1, TestMessage.instanceCreator)) 643 .toThrow(); 644 }); 645 646 it('fail when mutable submessage has incomplete data', () => { 647 const accessor = 648 Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x08)); 649 expect(() => accessor.getMessageAttach(1, TestMessage.instanceCreator)) 650 .toThrow(); 651 }); 652 653 it('fail when getting message with null instance constructor', () => { 654 const accessor = 655 Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x02, 0x08, 0x01)); 656 const nullMessage = /** @type {function(!Kernel):!TestMessage} */ 657 (/** @type {*} */ (null)); 658 expect(() => accessor.getMessageOrNull(1, nullMessage)).toThrow(); 659 }); 660 661 it('fail when setting message value with null value', () => { 662 const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); 663 const fakeMessage = /** @type {!TestMessage} */ (/** @type {*} */ (null)); 664 if (CHECK_CRITICAL_TYPE) { 665 expect(() => accessor.setMessage(1, fakeMessage)) 666 .toThrowError('Given value is not a message instance: null'); 667 } else { 668 // Note in unchecked mode we produce invalid output for invalid inputs. 669 // This test just documents our behavior in those cases. 670 // These values might change at any point and are not considered 671 // what the implementation should be doing here. 672 accessor.setMessage(1, fakeMessage); 673 expect(accessor.getMessageOrNull( 674 /* fieldNumber= */ 1, TestMessage.instanceCreator)) 675 .toBeNull(); 676 } 677 }); 678}); 679 680describe('Bytes access', () => { 681 const simpleByteString = ByteString.fromArrayBuffer(createArrayBuffer(1)); 682 683 it('returns default value for empty input', () => { 684 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 685 expect(accessor.getBytesWithDefault(1)).toEqual(ByteString.EMPTY); 686 }); 687 688 it('returns the default from parameter', () => { 689 const defaultByteString = ByteString.fromArrayBuffer(createArrayBuffer(1)); 690 const returnValue = ByteString.fromArrayBuffer(createArrayBuffer(1)); 691 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 692 expect(accessor.getBytesWithDefault(1, defaultByteString)) 693 .toEqual(returnValue); 694 }); 695 696 it('decodes value from wire', () => { 697 const accessor = 698 Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x01)); 699 expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); 700 }); 701 702 it('decodes value from wire with multple values being present', () => { 703 const accessor = Kernel.fromArrayBuffer( 704 createArrayBuffer(0x0A, 0x01, 0x00, 0x0A, 0x01, 0x01)); 705 expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); 706 }); 707 708 it('fails when getting value with other wire types', () => { 709 const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 710 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01)); 711 if (CHECK_CRITICAL_TYPE) { 712 expect(() => { 713 accessor.getBytesWithDefault(1); 714 }).toThrowError('Expected wire type: 2 but found: 1'); 715 } else { 716 // Note in unchecked mode we produce invalid output for invalid inputs. 717 // This test just documents our behavior in those cases. 718 // These values might change at any point and are not considered 719 // what the implementation should be doing here. 720 const arrayBuffer = createArrayBuffer(1); 721 expect(accessor.getBytesWithDefault(1)) 722 .toEqual(ByteString.fromArrayBuffer(arrayBuffer)); 723 } 724 }); 725 726 it('throws in getter for invalid fieldNumber', () => { 727 if (CHECK_BOUNDS) { 728 expect( 729 () => Kernel.createEmpty().getBytesWithDefault(-1, simpleByteString)) 730 .toThrowError('Field number is out of range: -1'); 731 } else { 732 expect(Kernel.createEmpty().getBytesWithDefault(-1, simpleByteString)) 733 .toEqual(simpleByteString); 734 } 735 }); 736 737 it('returns the value from setter', () => { 738 const bytes = createArrayBuffer(0x0A, 0x01, 0x00); 739 const accessor = Kernel.fromArrayBuffer(bytes); 740 accessor.setBytes(1, simpleByteString); 741 expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); 742 }); 743 744 it('encode the value from setter', () => { 745 const bytes = createArrayBuffer(0x0A, 0x01, 0x00); 746 const accessor = Kernel.fromArrayBuffer(bytes); 747 const newBytes = createArrayBuffer(0x0A, 0x01, 0x01); 748 accessor.setBytes(1, simpleByteString); 749 expect(accessor.serialize()).toEqual(newBytes); 750 }); 751 752 it('returns value from cache', () => { 753 const bytes = createArrayBuffer(0x0A, 0x01, 0x01); 754 const accessor = Kernel.fromArrayBuffer(bytes); 755 expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); 756 // Make sure the value is cached. 757 bytes[2] = 0x00; 758 expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); 759 }); 760 761 it('throws in setter for invalid fieldNumber', () => { 762 if (CHECK_BOUNDS) { 763 expect(() => Kernel.createEmpty().setBytes(-1, simpleByteString)) 764 .toThrowError('Field number is out of range: -1'); 765 } else { 766 const accessor = Kernel.createEmpty(); 767 accessor.setBytes(-1, simpleByteString); 768 expect(accessor.getBytesWithDefault(-1)).toEqual(simpleByteString); 769 } 770 }); 771 772 it('throws in setter for invalid value', () => { 773 if (CHECK_CRITICAL_TYPE) { 774 expect( 775 () => Kernel.createEmpty().setBytes( 776 1, /** @type {!ByteString} */ (/** @type {*} */ (null)))) 777 .toThrow(); 778 } else { 779 const accessor = Kernel.createEmpty(); 780 accessor.setBytes( 781 1, /** @type {!ByteString} */ (/** @type {*} */ (null))); 782 expect(accessor.getBytesWithDefault(1)).toEqual(null); 783 } 784 }); 785}); 786 787describe('Fixed32 access', () => { 788 it('returns default value for empty input', () => { 789 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 790 expect(accessor.getFixed32WithDefault(1)).toEqual(0); 791 }); 792 793 it('returns the default from parameter', () => { 794 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 795 expect(accessor.getFixed32WithDefault(1, 2)).toEqual(2); 796 }); 797 798 it('decodes value from wire', () => { 799 const accessor = 800 Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00)); 801 expect(accessor.getFixed32WithDefault(1)).toEqual(1); 802 }); 803 804 it('decodes value from wire with multple values being present', () => { 805 const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 806 0x0D, 0x01, 0x00, 0x80, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00)); 807 expect(accessor.getFixed32WithDefault(1)).toEqual(2); 808 }); 809 810 it('fails when getting value with other wire types', () => { 811 const accessor = 812 Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); 813 if (CHECK_CRITICAL_TYPE) { 814 expect(() => { 815 accessor.getFixed32WithDefault(1); 816 }).toThrowError('Expected wire type: 5 but found: 0'); 817 } else { 818 // Note in unchecked mode we produce invalid output for invalid inputs. 819 // This test just documents our behavior in those cases. 820 // These values might change at any point and are not considered 821 // what the implementation should be doing here. 822 expect(accessor.getFixed32WithDefault(1)).toEqual(8421504); 823 } 824 }); 825 826 it('throws in getter for invalid fieldNumber', () => { 827 if (CHECK_BOUNDS) { 828 expect(() => Kernel.createEmpty().getFixed32WithDefault(-1, 1)) 829 .toThrowError('Field number is out of range: -1'); 830 } else { 831 expect(Kernel.createEmpty().getFixed32WithDefault(-1, 1)).toEqual(1); 832 } 833 }); 834 835 it('returns the value from setter', () => { 836 const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); 837 const accessor = Kernel.fromArrayBuffer(bytes); 838 accessor.setFixed32(1, 2); 839 expect(accessor.getFixed32WithDefault(1)).toEqual(2); 840 }); 841 842 it('encode the value from setter', () => { 843 const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); 844 const accessor = Kernel.fromArrayBuffer(bytes); 845 const newBytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00); 846 accessor.setFixed32(1, 0); 847 expect(accessor.serialize()).toEqual(newBytes); 848 }); 849 850 it('returns value from cache', () => { 851 const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); 852 const accessor = Kernel.fromArrayBuffer(bytes); 853 expect(accessor.getFixed32WithDefault(1)).toBe(1); 854 // Make sure the value is cached. 855 bytes[2] = 0x00; 856 expect(accessor.getFixed32WithDefault(1)).toBe(1); 857 }); 858 859 it('throws in setter for invalid fieldNumber', () => { 860 if (CHECK_BOUNDS) { 861 expect(() => Kernel.createEmpty().setFixed32(-1, 1)) 862 .toThrowError('Field number is out of range: -1'); 863 } else { 864 const accessor = Kernel.createEmpty(); 865 accessor.setFixed32(-1, 1); 866 expect(accessor.getFixed32WithDefault(-1)).toEqual(1); 867 } 868 }); 869 870 it('throws in setter for invalid value', () => { 871 if (CHECK_CRITICAL_TYPE) { 872 expect( 873 () => Kernel.createEmpty().setFixed32( 874 1, /** @type {number} */ (/** @type {*} */ (null)))) 875 .toThrow(); 876 } else { 877 const accessor = Kernel.createEmpty(); 878 accessor.setFixed32(1, /** @type {number} */ (/** @type {*} */ (null))); 879 expect(accessor.getFixed32WithDefault(1)).toEqual(null); 880 } 881 }); 882 883 it('throws in setter for negative value', () => { 884 if (CHECK_CRITICAL_TYPE) { 885 expect(() => Kernel.createEmpty().setFixed32(1, -1)).toThrow(); 886 } else { 887 const accessor = Kernel.createEmpty(); 888 accessor.setFixed32(1, -1); 889 expect(accessor.getFixed32WithDefault(1)).toEqual(-1); 890 } 891 }); 892}); 893 894describe('Fixed64 access', () => { 895 it('returns default value for empty input', () => { 896 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 897 expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(0)); 898 }); 899 900 it('returns the default from parameter', () => { 901 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 902 expect(accessor.getFixed64WithDefault(1, Int64.fromInt(2))) 903 .toEqual(Int64.fromInt(2)); 904 }); 905 906 it('decodes value from wire', () => { 907 const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 908 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); 909 expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(1)); 910 }); 911 912 it('decodes value from wire with multple values being present', () => { 913 const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 914 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x00, 915 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); 916 expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(2)); 917 }); 918 919 if (CHECK_CRITICAL_STATE) { 920 it('fails when getting value with other wire types', () => { 921 const accessor = Kernel.fromArrayBuffer( 922 createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); 923 expect(() => { 924 accessor.getFixed64WithDefault(1); 925 }).toThrow(); 926 }); 927 } 928 929 it('throws in getter for invalid fieldNumber', () => { 930 if (CHECK_BOUNDS) { 931 expect( 932 () => 933 Kernel.createEmpty().getFixed64WithDefault(-1, Int64.fromInt(1))) 934 .toThrowError('Field number is out of range: -1'); 935 } else { 936 expect(Kernel.createEmpty().getFixed64WithDefault(-1, Int64.fromInt(1))) 937 .toEqual(Int64.fromInt(1)); 938 } 939 }); 940 941 it('returns the value from setter', () => { 942 const bytes = 943 createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 944 const accessor = Kernel.fromArrayBuffer(bytes); 945 accessor.setFixed64(1, Int64.fromInt(2)); 946 expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(2)); 947 }); 948 949 it('encode the value from setter', () => { 950 const bytes = 951 createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 952 const accessor = Kernel.fromArrayBuffer(bytes); 953 const newBytes = 954 createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 955 accessor.setFixed64(1, Int64.fromInt(0)); 956 expect(accessor.serialize()).toEqual(newBytes); 957 }); 958 959 it('returns value from cache', () => { 960 const bytes = 961 createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 962 const accessor = Kernel.fromArrayBuffer(bytes); 963 expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(1)); 964 // Make sure the value is cached. 965 bytes[2] = 0x00; 966 expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(1)); 967 }); 968 969 it('throws in setter for invalid fieldNumber', () => { 970 if (CHECK_BOUNDS) { 971 expect(() => Kernel.createEmpty().setFixed64(-1, Int64.fromInt(1))) 972 .toThrowError('Field number is out of range: -1'); 973 } else { 974 const accessor = Kernel.createEmpty(); 975 accessor.setFixed64(-1, Int64.fromInt(1)); 976 expect(accessor.getFixed64WithDefault(-1)).toEqual(Int64.fromInt(1)); 977 } 978 }); 979 980 it('throws in setter for invalid value', () => { 981 if (CHECK_CRITICAL_TYPE) { 982 expect( 983 () => Kernel.createEmpty().setSfixed64( 984 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) 985 .toThrow(); 986 } else { 987 const accessor = Kernel.createEmpty(); 988 accessor.setFixed64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); 989 expect(accessor.getFixed64WithDefault(1)).toEqual(null); 990 } 991 }); 992}); 993 994describe('Float access', () => { 995 it('returns default value for empty input', () => { 996 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 997 expect(accessor.getFloatWithDefault(1)).toEqual(0); 998 }); 999 1000 it('returns the default from parameter', () => { 1001 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1002 expect(accessor.getFloatWithDefault(1, 2)).toEqual(2); 1003 }); 1004 1005 it('decodes value from wire', () => { 1006 const accessor = 1007 Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x80, 0x3F)); 1008 expect(accessor.getFloatWithDefault(1)).toEqual(1); 1009 }); 1010 1011 it('decodes value from wire with multple values being present', () => { 1012 const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 1013 0x0D, 0x00, 0x00, 0x80, 0x3F, 0x0D, 0x00, 0x00, 0x80, 0xBF)); 1014 expect(accessor.getFloatWithDefault(1)).toEqual(-1); 1015 }); 1016 1017 if (CHECK_CRITICAL_STATE) { 1018 it('fails when getting float value with other wire types', () => { 1019 const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 1020 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F)); 1021 expect(() => { 1022 accessor.getFloatWithDefault(1); 1023 }).toThrow(); 1024 }); 1025 } 1026 1027 1028 it('throws in getter for invalid fieldNumber', () => { 1029 if (CHECK_BOUNDS) { 1030 expect(() => Kernel.createEmpty().getFloatWithDefault(-1, 1)) 1031 .toThrowError('Field number is out of range: -1'); 1032 } else { 1033 expect(Kernel.createEmpty().getFloatWithDefault(-1, 1)).toEqual(1); 1034 } 1035 }); 1036 1037 it('returns the value from setter', () => { 1038 const bytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x80, 0x3F); 1039 const accessor = Kernel.fromArrayBuffer(bytes); 1040 accessor.setFloat(1, 1.6); 1041 expect(accessor.getFloatWithDefault(1)).toEqual(Math.fround(1.6)); 1042 }); 1043 1044 it('encode the value from setter', () => { 1045 const bytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x80, 0x3F); 1046 const accessor = Kernel.fromArrayBuffer(bytes); 1047 const newBytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00); 1048 accessor.setFloat(1, 0); 1049 expect(accessor.serialize()).toEqual(newBytes); 1050 }); 1051 1052 it('returns float value from cache', () => { 1053 const bytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x80, 0x3F); 1054 const accessor = Kernel.fromArrayBuffer(bytes); 1055 expect(accessor.getFloatWithDefault(1)).toBe(1); 1056 // Make sure the value is cached. 1057 bytes[2] = 0x00; 1058 expect(accessor.getFloatWithDefault(1)).toBe(1); 1059 }); 1060 1061 it('throws in setter for invalid fieldNumber', () => { 1062 if (CHECK_BOUNDS) { 1063 expect(() => Kernel.createEmpty().setFloat(-1, 1)) 1064 .toThrowError('Field number is out of range: -1'); 1065 } else { 1066 const accessor = Kernel.createEmpty(); 1067 accessor.setFloat(-1, 1); 1068 expect(accessor.getFloatWithDefault(-1)).toEqual(1); 1069 } 1070 }); 1071 1072 it('throws in setter for invalid value', () => { 1073 if (CHECK_CRITICAL_TYPE) { 1074 expect( 1075 () => Kernel.createEmpty().setFloat( 1076 1, /** @type {number} */ (/** @type {*} */ (null)))) 1077 .toThrow(); 1078 } else { 1079 const accessor = Kernel.createEmpty(); 1080 accessor.setFloat(1, /** @type {number} */ (/** @type {*} */ (null))); 1081 expect(accessor.getFloatWithDefault(1)).toEqual(0); 1082 } 1083 }); 1084 1085 it('throws in setter for value outside of float32 precision', () => { 1086 if (CHECK_CRITICAL_TYPE) { 1087 expect(() => Kernel.createEmpty().setFloat(1, Number.MAX_VALUE)) 1088 .toThrow(); 1089 } else { 1090 const accessor = Kernel.createEmpty(); 1091 accessor.setFloat(1, Number.MAX_VALUE); 1092 expect(accessor.getFloatWithDefault(1)).toEqual(Infinity); 1093 } 1094 }); 1095}); 1096 1097describe('Int32 access', () => { 1098 it('returns default value for empty input', () => { 1099 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1100 expect(accessor.getInt32WithDefault(1)).toEqual(0); 1101 }); 1102 1103 it('returns the default from parameter', () => { 1104 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1105 expect(accessor.getInt32WithDefault(1, 2)).toEqual(2); 1106 }); 1107 1108 it('decodes value from wire', () => { 1109 const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); 1110 expect(accessor.getInt32WithDefault(1)).toEqual(1); 1111 }); 1112 1113 it('decodes value from wire with multple values being present', () => { 1114 const accessor = 1115 Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); 1116 expect(accessor.getInt32WithDefault(1)).toEqual(2); 1117 }); 1118 1119 it('fails when getting value with other wire types', () => { 1120 const accessor = 1121 Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); 1122 if (CHECK_CRITICAL_TYPE) { 1123 expect(() => { 1124 accessor.getInt32WithDefault(1); 1125 }).toThrowError('Expected wire type: 0 but found: 5'); 1126 } else { 1127 // Note in unchecked mode we produce invalid output for invalid inputs. 1128 // This test just documents our behavior in those cases. 1129 // These values might change at any point and are not considered 1130 // what the implementation should be doing here. 1131 expect(accessor.getInt32WithDefault(1)).toEqual(0); 1132 } 1133 }); 1134 1135 it('throws in getter for invalid fieldNumber', () => { 1136 if (CHECK_BOUNDS) { 1137 expect(() => Kernel.createEmpty().getInt32WithDefault(-1, 1)) 1138 .toThrowError('Field number is out of range: -1'); 1139 } else { 1140 expect(Kernel.createEmpty().getInt32WithDefault(-1, 1)).toEqual(1); 1141 } 1142 }); 1143 1144 it('returns the value from setter', () => { 1145 const bytes = createArrayBuffer(0x08, 0x01); 1146 const accessor = Kernel.fromArrayBuffer(bytes); 1147 accessor.setInt32(1, 2); 1148 expect(accessor.getInt32WithDefault(1)).toEqual(2); 1149 }); 1150 1151 it('encode the value from setter', () => { 1152 const bytes = createArrayBuffer(0x08, 0x01); 1153 const accessor = Kernel.fromArrayBuffer(bytes); 1154 const newBytes = createArrayBuffer(0x08, 0x00); 1155 accessor.setInt32(1, 0); 1156 expect(accessor.serialize()).toEqual(newBytes); 1157 }); 1158 1159 it('returns value from cache', () => { 1160 const bytes = createArrayBuffer(0x08, 0x01); 1161 const accessor = Kernel.fromArrayBuffer(bytes); 1162 expect(accessor.getInt32WithDefault(1)).toBe(1); 1163 // Make sure the value is cached. 1164 bytes[2] = 0x00; 1165 expect(accessor.getInt32WithDefault(1)).toBe(1); 1166 }); 1167 1168 it('throws in setter for invalid fieldNumber', () => { 1169 if (CHECK_BOUNDS) { 1170 expect(() => Kernel.createEmpty().setInt32(-1, 1)) 1171 .toThrowError('Field number is out of range: -1'); 1172 } else { 1173 const accessor = Kernel.createEmpty(); 1174 accessor.setInt32(-1, 1); 1175 expect(accessor.getInt32WithDefault(-1)).toEqual(1); 1176 } 1177 }); 1178 1179 it('throws in setter for invalid value', () => { 1180 if (CHECK_CRITICAL_TYPE) { 1181 expect( 1182 () => Kernel.createEmpty().setInt32( 1183 1, /** @type {number} */ (/** @type {*} */ (null)))) 1184 .toThrow(); 1185 } else { 1186 const accessor = Kernel.createEmpty(); 1187 accessor.setInt32(1, /** @type {number} */ (/** @type {*} */ (null))); 1188 expect(accessor.getInt32WithDefault(1)).toEqual(null); 1189 } 1190 }); 1191}); 1192 1193describe('Int64 access', () => { 1194 it('returns default value for empty input', () => { 1195 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1196 expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(0)); 1197 }); 1198 1199 it('returns the default from parameter', () => { 1200 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1201 expect(accessor.getInt64WithDefault(1, Int64.fromInt(2))) 1202 .toEqual(Int64.fromInt(2)); 1203 }); 1204 1205 it('decodes value from wire', () => { 1206 const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); 1207 expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(1)); 1208 }); 1209 1210 it('decodes value from wire with multple values being present', () => { 1211 const accessor = 1212 Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); 1213 expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(2)); 1214 }); 1215 1216 it('fails when getting value with other wire types', () => { 1217 const accessor = 1218 Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); 1219 if (CHECK_CRITICAL_TYPE) { 1220 expect(() => { 1221 accessor.getInt64WithDefault(1); 1222 }).toThrowError('Expected wire type: 0 but found: 5'); 1223 } else { 1224 // Note in unchecked mode we produce invalid output for invalid inputs. 1225 // This test just documents our behavior in those cases. 1226 // These values might change at any point and are not considered 1227 // what the implementation should be doing here. 1228 expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(0)); 1229 } 1230 }); 1231 1232 it('throws in getter for invalid fieldNumber', () => { 1233 if (CHECK_BOUNDS) { 1234 expect( 1235 () => Kernel.createEmpty().getInt64WithDefault(-1, Int64.fromInt(1))) 1236 .toThrowError('Field number is out of range: -1'); 1237 } else { 1238 expect(Kernel.createEmpty().getInt64WithDefault(-1, Int64.fromInt(1))) 1239 .toEqual(Int64.fromInt(1)); 1240 } 1241 }); 1242 1243 it('returns the value from setter', () => { 1244 const bytes = createArrayBuffer(0x08, 0x01); 1245 const accessor = Kernel.fromArrayBuffer(bytes); 1246 accessor.setInt64(1, Int64.fromInt(2)); 1247 expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(2)); 1248 }); 1249 1250 it('encode the value from setter', () => { 1251 const bytes = createArrayBuffer(0x08, 0x01); 1252 const accessor = Kernel.fromArrayBuffer(bytes); 1253 const newBytes = createArrayBuffer(0x08, 0x00); 1254 accessor.setInt64(1, Int64.fromInt(0)); 1255 expect(accessor.serialize()).toEqual(newBytes); 1256 }); 1257 1258 it('returns value from cache', () => { 1259 const bytes = createArrayBuffer(0x08, 0x01); 1260 const accessor = Kernel.fromArrayBuffer(bytes); 1261 expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(1)); 1262 // Make sure the value is cached. 1263 bytes[2] = 0x00; 1264 expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(1)); 1265 }); 1266 1267 it('throws in setter for invalid fieldNumber', () => { 1268 if (CHECK_BOUNDS) { 1269 expect(() => Kernel.createEmpty().setInt64(-1, Int64.fromInt(1))) 1270 .toThrowError('Field number is out of range: -1'); 1271 } else { 1272 const accessor = Kernel.createEmpty(); 1273 accessor.setInt64(-1, Int64.fromInt(1)); 1274 expect(accessor.getInt64WithDefault(-1)).toEqual(Int64.fromInt(1)); 1275 } 1276 }); 1277 1278 it('throws in setter for invalid value', () => { 1279 if (CHECK_CRITICAL_TYPE) { 1280 expect( 1281 () => Kernel.createEmpty().setInt64( 1282 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) 1283 .toThrow(); 1284 } else { 1285 const accessor = Kernel.createEmpty(); 1286 accessor.setInt64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); 1287 expect(accessor.getInt64WithDefault(1)).toEqual(null); 1288 } 1289 }); 1290}); 1291 1292describe('Sfixed32 access', () => { 1293 it('returns default value for empty input', () => { 1294 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1295 expect(accessor.getSfixed32WithDefault(1)).toEqual(0); 1296 }); 1297 1298 it('returns the default from parameter', () => { 1299 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1300 expect(accessor.getSfixed32WithDefault(1, 2)).toEqual(2); 1301 }); 1302 1303 it('decodes value from wire', () => { 1304 const accessor = 1305 Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00)); 1306 expect(accessor.getSfixed32WithDefault(1)).toEqual(1); 1307 }); 1308 1309 it('decodes value from wire with multple values being present', () => { 1310 const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 1311 0x0D, 0x01, 0x00, 0x80, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00)); 1312 expect(accessor.getSfixed32WithDefault(1)).toEqual(2); 1313 }); 1314 1315 it('fails when getting value with other wire types', () => { 1316 const accessor = 1317 Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); 1318 if (CHECK_CRITICAL_TYPE) { 1319 expect(() => { 1320 accessor.getSfixed32WithDefault(1); 1321 }).toThrowError('Expected wire type: 5 but found: 0'); 1322 } else { 1323 // Note in unchecked mode we produce invalid output for invalid inputs. 1324 // This test just documents our behavior in those cases. 1325 // These values might change at any point and are not considered 1326 // what the implementation should be doing here. 1327 expect(accessor.getSfixed32WithDefault(1)).toEqual(8421504); 1328 } 1329 }); 1330 1331 it('throws in getter for invalid fieldNumber', () => { 1332 if (CHECK_BOUNDS) { 1333 expect(() => Kernel.createEmpty().getSfixed32WithDefault(-1, 1)) 1334 .toThrowError('Field number is out of range: -1'); 1335 } else { 1336 expect(Kernel.createEmpty().getSfixed32WithDefault(-1, 1)).toEqual(1); 1337 } 1338 }); 1339 1340 it('returns the value from setter', () => { 1341 const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); 1342 const accessor = Kernel.fromArrayBuffer(bytes); 1343 accessor.setSfixed32(1, 2); 1344 expect(accessor.getSfixed32WithDefault(1)).toEqual(2); 1345 }); 1346 1347 it('encode the value from setter', () => { 1348 const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); 1349 const accessor = Kernel.fromArrayBuffer(bytes); 1350 const newBytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00); 1351 accessor.setSfixed32(1, 0); 1352 expect(accessor.serialize()).toEqual(newBytes); 1353 }); 1354 1355 it('returns value from cache', () => { 1356 const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); 1357 const accessor = Kernel.fromArrayBuffer(bytes); 1358 expect(accessor.getSfixed32WithDefault(1)).toBe(1); 1359 // Make sure the value is cached. 1360 bytes[2] = 0x00; 1361 expect(accessor.getSfixed32WithDefault(1)).toBe(1); 1362 }); 1363 1364 it('throws in setter for invalid fieldNumber', () => { 1365 if (CHECK_BOUNDS) { 1366 expect(() => Kernel.createEmpty().setSfixed32(-1, 1)) 1367 .toThrowError('Field number is out of range: -1'); 1368 } else { 1369 const accessor = Kernel.createEmpty(); 1370 accessor.setSfixed32(-1, 1); 1371 expect(accessor.getSfixed32WithDefault(-1)).toEqual(1); 1372 } 1373 }); 1374 1375 it('throws in setter for invalid value', () => { 1376 if (CHECK_CRITICAL_TYPE) { 1377 expect( 1378 () => Kernel.createEmpty().setSfixed32( 1379 1, /** @type {number} */ (/** @type {*} */ (null)))) 1380 .toThrow(); 1381 } else { 1382 const accessor = Kernel.createEmpty(); 1383 accessor.setSfixed32(1, /** @type {number} */ (/** @type {*} */ (null))); 1384 expect(accessor.getSfixed32WithDefault(1)).toEqual(null); 1385 } 1386 }); 1387}); 1388 1389describe('Sfixed64 access', () => { 1390 it('returns default value for empty input', () => { 1391 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1392 expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(0)); 1393 }); 1394 1395 it('returns the default from parameter', () => { 1396 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1397 expect(accessor.getSfixed64WithDefault(1, Int64.fromInt(2))) 1398 .toEqual(Int64.fromInt(2)); 1399 }); 1400 1401 it('decodes value from wire', () => { 1402 const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 1403 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); 1404 expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(1)); 1405 }); 1406 1407 it('decodes value from wire with multple values being present', () => { 1408 const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 1409 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x00, 1410 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); 1411 expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(2)); 1412 }); 1413 1414 if (CHECK_CRITICAL_STATE) { 1415 it('fails when getting value with other wire types', () => { 1416 const accessor = Kernel.fromArrayBuffer( 1417 createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); 1418 expect(() => { 1419 accessor.getSfixed64WithDefault(1); 1420 }).toThrow(); 1421 }); 1422 } 1423 1424 it('throws in getter for invalid fieldNumber', () => { 1425 if (CHECK_BOUNDS) { 1426 expect( 1427 () => 1428 Kernel.createEmpty().getSfixed64WithDefault(-1, Int64.fromInt(1))) 1429 .toThrowError('Field number is out of range: -1'); 1430 } else { 1431 expect(Kernel.createEmpty().getSfixed64WithDefault(-1, Int64.fromInt(1))) 1432 .toEqual(Int64.fromInt(1)); 1433 } 1434 }); 1435 1436 it('returns the value from setter', () => { 1437 const bytes = 1438 createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 1439 const accessor = Kernel.fromArrayBuffer(bytes); 1440 accessor.setSfixed64(1, Int64.fromInt(2)); 1441 expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(2)); 1442 }); 1443 1444 it('encode the value from setter', () => { 1445 const bytes = 1446 createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 1447 const accessor = Kernel.fromArrayBuffer(bytes); 1448 const newBytes = 1449 createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 1450 accessor.setSfixed64(1, Int64.fromInt(0)); 1451 expect(accessor.serialize()).toEqual(newBytes); 1452 }); 1453 1454 it('returns value from cache', () => { 1455 const bytes = 1456 createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 1457 const accessor = Kernel.fromArrayBuffer(bytes); 1458 expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(1)); 1459 // Make sure the value is cached. 1460 bytes[2] = 0x00; 1461 expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(1)); 1462 }); 1463 1464 it('throws in setter for invalid fieldNumber', () => { 1465 if (CHECK_BOUNDS) { 1466 expect(() => Kernel.createEmpty().setSfixed64(-1, Int64.fromInt(1))) 1467 .toThrowError('Field number is out of range: -1'); 1468 } else { 1469 const accessor = Kernel.createEmpty(); 1470 accessor.setSfixed64(-1, Int64.fromInt(1)); 1471 expect(accessor.getSfixed64WithDefault(-1)).toEqual(Int64.fromInt(1)); 1472 } 1473 }); 1474 1475 it('throws in setter for invalid value', () => { 1476 if (CHECK_CRITICAL_TYPE) { 1477 expect( 1478 () => Kernel.createEmpty().setSfixed64( 1479 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) 1480 .toThrow(); 1481 } else { 1482 const accessor = Kernel.createEmpty(); 1483 accessor.setSfixed64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); 1484 expect(accessor.getSfixed64WithDefault(1)).toEqual(null); 1485 } 1486 }); 1487}); 1488 1489describe('Sint32 access', () => { 1490 it('returns default value for empty input', () => { 1491 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1492 expect(accessor.getSint32WithDefault(1)).toEqual(0); 1493 }); 1494 1495 it('returns the default from parameter', () => { 1496 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1497 expect(accessor.getSint32WithDefault(1, 2)).toEqual(2); 1498 }); 1499 1500 it('decodes value from wire', () => { 1501 const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x02)); 1502 expect(accessor.getSint32WithDefault(1)).toEqual(1); 1503 }); 1504 1505 it('decodes value from wire with multple values being present', () => { 1506 const accessor = 1507 Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x03, 0x08, 0x02)); 1508 expect(accessor.getSint32WithDefault(1)).toEqual(1); 1509 }); 1510 1511 it('fails when getting value with other wire types', () => { 1512 const accessor = 1513 Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); 1514 if (CHECK_CRITICAL_TYPE) { 1515 expect(() => { 1516 accessor.getSint32WithDefault(1); 1517 }).toThrowError('Expected wire type: 0 but found: 5'); 1518 } else { 1519 // Note in unchecked mode we produce invalid output for invalid inputs. 1520 // This test just documents our behavior in those cases. 1521 // These values might change at any point and are not considered 1522 // what the implementation should be doing here. 1523 expect(accessor.getSint32WithDefault(1)).toEqual(0); 1524 } 1525 }); 1526 1527 it('throws in getter for invalid fieldNumber', () => { 1528 if (CHECK_BOUNDS) { 1529 expect(() => Kernel.createEmpty().getSint32WithDefault(-1, 1)) 1530 .toThrowError('Field number is out of range: -1'); 1531 } else { 1532 expect(Kernel.createEmpty().getSint32WithDefault(-1, 1)).toEqual(1); 1533 } 1534 }); 1535 1536 it('returns the value from setter', () => { 1537 const bytes = createArrayBuffer(0x08, 0x01); 1538 const accessor = Kernel.fromArrayBuffer(bytes); 1539 accessor.setSint32(1, 2); 1540 expect(accessor.getSint32WithDefault(1)).toEqual(2); 1541 }); 1542 1543 it('encode the value from setter', () => { 1544 const bytes = createArrayBuffer(0x08, 0x01); 1545 const accessor = Kernel.fromArrayBuffer(bytes); 1546 const newBytes = createArrayBuffer(0x08, 0x00); 1547 accessor.setSint32(1, 0); 1548 expect(accessor.serialize()).toEqual(newBytes); 1549 }); 1550 1551 it('returns value from cache', () => { 1552 const bytes = createArrayBuffer(0x08, 0x02); 1553 const accessor = Kernel.fromArrayBuffer(bytes); 1554 expect(accessor.getSint32WithDefault(1)).toBe(1); 1555 // Make sure the value is cached. 1556 bytes[2] = 0x00; 1557 expect(accessor.getSint32WithDefault(1)).toBe(1); 1558 }); 1559 1560 it('throws in setter for invalid fieldNumber', () => { 1561 if (CHECK_BOUNDS) { 1562 expect(() => Kernel.createEmpty().setSint32(-1, 1)) 1563 .toThrowError('Field number is out of range: -1'); 1564 } else { 1565 const accessor = Kernel.createEmpty(); 1566 accessor.setSint32(-1, 1); 1567 expect(accessor.getSint32WithDefault(-1)).toEqual(1); 1568 } 1569 }); 1570 1571 it('throws in setter for invalid value', () => { 1572 if (CHECK_CRITICAL_TYPE) { 1573 expect( 1574 () => Kernel.createEmpty().setSint32( 1575 1, /** @type {number} */ (/** @type {*} */ (null)))) 1576 .toThrow(); 1577 } else { 1578 const accessor = Kernel.createEmpty(); 1579 accessor.setSint32(1, /** @type {number} */ (/** @type {*} */ (null))); 1580 expect(accessor.getSint32WithDefault(1)).toEqual(null); 1581 } 1582 }); 1583}); 1584 1585describe('SInt64 access', () => { 1586 it('returns default value for empty input', () => { 1587 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1588 expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(0)); 1589 }); 1590 1591 it('returns the default from parameter', () => { 1592 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1593 expect(accessor.getSint64WithDefault(1, Int64.fromInt(2))) 1594 .toEqual(Int64.fromInt(2)); 1595 }); 1596 1597 it('decodes value from wire', () => { 1598 const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x02)); 1599 expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1)); 1600 }); 1601 1602 it('decodes value from wire with multple values being present', () => { 1603 const accessor = 1604 Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); 1605 expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1)); 1606 }); 1607 1608 it('fails when getting value with other wire types', () => { 1609 const accessor = 1610 Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); 1611 if (CHECK_CRITICAL_TYPE) { 1612 expect(() => { 1613 accessor.getSint64WithDefault(1); 1614 }).toThrowError('Expected wire type: 0 but found: 5'); 1615 } else { 1616 // Note in unchecked mode we produce invalid output for invalid inputs. 1617 // This test just documents our behavior in those cases. 1618 // These values might change at any point and are not considered 1619 // what the implementation should be doing here. 1620 expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(0)); 1621 } 1622 }); 1623 1624 it('throws in getter for invalid fieldNumber', () => { 1625 if (CHECK_BOUNDS) { 1626 expect( 1627 () => Kernel.createEmpty().getSint64WithDefault(-1, Int64.fromInt(1))) 1628 .toThrowError('Field number is out of range: -1'); 1629 } else { 1630 expect(Kernel.createEmpty().getSint64WithDefault(-1, Int64.fromInt(1))) 1631 .toEqual(Int64.fromInt(1)); 1632 } 1633 }); 1634 1635 it('returns the value from setter', () => { 1636 const bytes = createArrayBuffer(0x08, 0x01); 1637 const accessor = Kernel.fromArrayBuffer(bytes); 1638 accessor.setSint64(1, Int64.fromInt(2)); 1639 expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(2)); 1640 }); 1641 1642 it('encode the value from setter', () => { 1643 const bytes = createArrayBuffer(0x08, 0x01); 1644 const accessor = Kernel.fromArrayBuffer(bytes); 1645 const newBytes = createArrayBuffer(0x08, 0x00); 1646 accessor.setSint64(1, Int64.fromInt(0)); 1647 expect(accessor.serialize()).toEqual(newBytes); 1648 }); 1649 1650 it('returns value from cache', () => { 1651 const bytes = createArrayBuffer(0x08, 0x02); 1652 const accessor = Kernel.fromArrayBuffer(bytes); 1653 expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1)); 1654 // Make sure the value is cached. 1655 bytes[1] = 0x00; 1656 expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1)); 1657 }); 1658 1659 it('throws in setter for invalid fieldNumber', () => { 1660 if (CHECK_BOUNDS) { 1661 expect(() => Kernel.createEmpty().setSint64(-1, Int64.fromInt(1))) 1662 .toThrowError('Field number is out of range: -1'); 1663 } else { 1664 const accessor = Kernel.createEmpty(); 1665 accessor.setInt64(-1, Int64.fromInt(1)); 1666 expect(accessor.getSint64WithDefault(-1)).toEqual(Int64.fromInt(1)); 1667 } 1668 }); 1669 1670 it('throws in setter for invalid value', () => { 1671 if (CHECK_CRITICAL_TYPE) { 1672 expect( 1673 () => Kernel.createEmpty().setSint64( 1674 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) 1675 .toThrow(); 1676 } else { 1677 const accessor = Kernel.createEmpty(); 1678 accessor.setSint64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); 1679 expect(accessor.getSint64WithDefault(1)).toEqual(null); 1680 } 1681 }); 1682}); 1683 1684describe('String access', () => { 1685 it('returns empty string for the empty input', () => { 1686 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1687 expect(accessor.getStringWithDefault(1)).toEqual(''); 1688 }); 1689 1690 it('returns the default for the empty input', () => { 1691 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1692 expect(accessor.getStringWithDefault(1, 'bar')).toEqual('bar'); 1693 }); 1694 1695 it('decodes value from wire', () => { 1696 const accessor = 1697 Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x61)); 1698 expect(accessor.getStringWithDefault(1)).toEqual('a'); 1699 }); 1700 1701 it('decodes value from wire with multple values being present', () => { 1702 const accessor = Kernel.fromArrayBuffer( 1703 createArrayBuffer(0x0A, 0x01, 0x60, 0x0A, 0x01, 0x61)); 1704 expect(accessor.getStringWithDefault(1)).toEqual('a'); 1705 }); 1706 1707 if (CHECK_CRITICAL_STATE) { 1708 it('fails when getting string value with other wire types', () => { 1709 const accessor = 1710 Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x02, 0x08, 0x08)); 1711 expect(() => { 1712 accessor.getStringWithDefault(1); 1713 }).toThrow(); 1714 }); 1715 } 1716 1717 1718 it('throws in getter for invalid fieldNumber', () => { 1719 if (CHECK_BOUNDS) { 1720 expect(() => Kernel.createEmpty().getStringWithDefault(-1, 'a')) 1721 .toThrowError('Field number is out of range: -1'); 1722 } else { 1723 expect(Kernel.createEmpty().getStringWithDefault(-1, 'a')).toEqual('a'); 1724 } 1725 }); 1726 1727 it('returns the value from setter', () => { 1728 const bytes = createArrayBuffer(0x0A, 0x01, 0x61); 1729 const accessor = Kernel.fromArrayBuffer(bytes); 1730 accessor.setString(1, 'b'); 1731 expect(accessor.getStringWithDefault(1)).toEqual('b'); 1732 }); 1733 1734 it('encode the value from setter', () => { 1735 const bytes = createArrayBuffer(0x0A, 0x01, 0x61); 1736 const accessor = Kernel.fromArrayBuffer(bytes); 1737 const newBytes = createArrayBuffer(0x0A, 0x01, 0x62); 1738 accessor.setString(1, 'b'); 1739 expect(accessor.serialize()).toEqual(newBytes); 1740 }); 1741 1742 it('returns string value from cache', () => { 1743 const bytes = createArrayBuffer(0x0A, 0x01, 0x61); 1744 const accessor = Kernel.fromArrayBuffer(bytes); 1745 expect(accessor.getStringWithDefault(1)).toBe('a'); 1746 // Make sure the value is cached. 1747 bytes[2] = 0x00; 1748 expect(accessor.getStringWithDefault(1)).toBe('a'); 1749 }); 1750 1751 it('throws in setter for invalid fieldNumber', () => { 1752 if (CHECK_TYPE) { 1753 expect(() => Kernel.createEmpty().setString(-1, 'a')) 1754 .toThrowError('Field number is out of range: -1'); 1755 } else { 1756 const accessor = Kernel.createEmpty(); 1757 accessor.setString(-1, 'a'); 1758 expect(accessor.getStringWithDefault(-1)).toEqual('a'); 1759 } 1760 }); 1761 1762 it('throws in setter for invalid value', () => { 1763 if (CHECK_CRITICAL_TYPE) { 1764 expect( 1765 () => Kernel.createEmpty().setString( 1766 1, /** @type {string} */ (/** @type {*} */ (null)))) 1767 .toThrowError('Must be string, but got: null'); 1768 } else { 1769 const accessor = Kernel.createEmpty(); 1770 accessor.setString(1, /** @type {string} */ (/** @type {*} */ (null))); 1771 expect(accessor.getStringWithDefault(1)).toEqual(null); 1772 } 1773 }); 1774}); 1775 1776describe('Uint32 access', () => { 1777 it('returns default value for empty input', () => { 1778 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1779 expect(accessor.getUint32WithDefault(1)).toEqual(0); 1780 }); 1781 1782 it('returns the default from parameter', () => { 1783 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1784 expect(accessor.getUint32WithDefault(1, 2)).toEqual(2); 1785 }); 1786 1787 it('decodes value from wire', () => { 1788 const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); 1789 expect(accessor.getUint32WithDefault(1)).toEqual(1); 1790 }); 1791 1792 it('decodes value from wire with multple values being present', () => { 1793 const accessor = 1794 Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); 1795 expect(accessor.getUint32WithDefault(1)).toEqual(2); 1796 }); 1797 1798 it('fails when getting value with other wire types', () => { 1799 const accessor = 1800 Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); 1801 if (CHECK_CRITICAL_TYPE) { 1802 expect(() => { 1803 accessor.getUint32WithDefault(1); 1804 }).toThrowError('Expected wire type: 0 but found: 5'); 1805 } else { 1806 // Note in unchecked mode we produce invalid output for invalid inputs. 1807 // This test just documents our behavior in those cases. 1808 // These values might change at any point and are not considered 1809 // what the implementation should be doing here. 1810 expect(accessor.getUint32WithDefault(1)).toEqual(0); 1811 } 1812 }); 1813 1814 it('throws in getter for invalid fieldNumber', () => { 1815 if (CHECK_BOUNDS) { 1816 expect(() => Kernel.createEmpty().getUint32WithDefault(-1, 1)) 1817 .toThrowError('Field number is out of range: -1'); 1818 } else { 1819 expect(Kernel.createEmpty().getUint32WithDefault(-1, 1)).toEqual(1); 1820 } 1821 }); 1822 1823 it('returns the value from setter', () => { 1824 const bytes = createArrayBuffer(0x08, 0x01); 1825 const accessor = Kernel.fromArrayBuffer(bytes); 1826 accessor.setUint32(1, 2); 1827 expect(accessor.getUint32WithDefault(1)).toEqual(2); 1828 }); 1829 1830 it('encode the value from setter', () => { 1831 const bytes = createArrayBuffer(0x08, 0x01); 1832 const accessor = Kernel.fromArrayBuffer(bytes); 1833 const newBytes = createArrayBuffer(0x08, 0x00); 1834 accessor.setUint32(1, 0); 1835 expect(accessor.serialize()).toEqual(newBytes); 1836 }); 1837 1838 it('returns value from cache', () => { 1839 const bytes = createArrayBuffer(0x08, 0x01); 1840 const accessor = Kernel.fromArrayBuffer(bytes); 1841 expect(accessor.getUint32WithDefault(1)).toBe(1); 1842 // Make sure the value is cached. 1843 bytes[2] = 0x00; 1844 expect(accessor.getUint32WithDefault(1)).toBe(1); 1845 }); 1846 1847 it('throws in setter for invalid fieldNumber', () => { 1848 if (CHECK_BOUNDS) { 1849 expect(() => Kernel.createEmpty().setInt32(-1, 1)) 1850 .toThrowError('Field number is out of range: -1'); 1851 } else { 1852 const accessor = Kernel.createEmpty(); 1853 accessor.setUint32(-1, 1); 1854 expect(accessor.getUint32WithDefault(-1)).toEqual(1); 1855 } 1856 }); 1857 1858 it('throws in setter for invalid value', () => { 1859 if (CHECK_CRITICAL_TYPE) { 1860 expect( 1861 () => Kernel.createEmpty().setUint32( 1862 1, /** @type {number} */ (/** @type {*} */ (null)))) 1863 .toThrow(); 1864 } else { 1865 const accessor = Kernel.createEmpty(); 1866 accessor.setUint32(1, /** @type {number} */ (/** @type {*} */ (null))); 1867 expect(accessor.getUint32WithDefault(1)).toEqual(null); 1868 } 1869 }); 1870 1871 it('throws in setter for negative value', () => { 1872 if (CHECK_CRITICAL_TYPE) { 1873 expect(() => Kernel.createEmpty().setUint32(1, -1)).toThrow(); 1874 } else { 1875 const accessor = Kernel.createEmpty(); 1876 accessor.setUint32(1, -1); 1877 expect(accessor.getUint32WithDefault(1)).toEqual(-1); 1878 } 1879 }); 1880}); 1881 1882describe('Uint64 access', () => { 1883 it('returns default value for empty input', () => { 1884 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1885 expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(0)); 1886 }); 1887 1888 it('returns the default from parameter', () => { 1889 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1890 expect(accessor.getUint64WithDefault(1, Int64.fromInt(2))) 1891 .toEqual(Int64.fromInt(2)); 1892 }); 1893 1894 it('decodes value from wire', () => { 1895 const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); 1896 expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(1)); 1897 }); 1898 1899 it('decodes value from wire with multple values being present', () => { 1900 const accessor = 1901 Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); 1902 expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(2)); 1903 }); 1904 1905 it('fails when getting value with other wire types', () => { 1906 const accessor = 1907 Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); 1908 if (CHECK_CRITICAL_TYPE) { 1909 expect(() => { 1910 accessor.getUint64WithDefault(1); 1911 }).toThrowError('Expected wire type: 0 but found: 5'); 1912 } else { 1913 // Note in unchecked mode we produce invalid output for invalid inputs. 1914 // This test just documents our behavior in those cases. 1915 // These values might change at any point and are not considered 1916 // what the implementation should be doing here. 1917 expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(0)); 1918 } 1919 }); 1920 1921 it('throws in getter for invalid fieldNumber', () => { 1922 if (CHECK_BOUNDS) { 1923 expect( 1924 () => Kernel.createEmpty().getUint64WithDefault(-1, Int64.fromInt(1))) 1925 .toThrowError('Field number is out of range: -1'); 1926 } else { 1927 expect(Kernel.createEmpty().getUint64WithDefault(-1, Int64.fromInt(1))) 1928 .toEqual(Int64.fromInt(1)); 1929 } 1930 }); 1931 1932 it('returns the value from setter', () => { 1933 const bytes = createArrayBuffer(0x08, 0x01); 1934 const accessor = Kernel.fromArrayBuffer(bytes); 1935 accessor.setUint64(1, Int64.fromInt(2)); 1936 expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(2)); 1937 }); 1938 1939 it('encode the value from setter', () => { 1940 const bytes = createArrayBuffer(0x08, 0x01); 1941 const accessor = Kernel.fromArrayBuffer(bytes); 1942 const newBytes = createArrayBuffer(0x08, 0x00); 1943 accessor.setUint64(1, Int64.fromInt(0)); 1944 expect(accessor.serialize()).toEqual(newBytes); 1945 }); 1946 1947 it('returns value from cache', () => { 1948 const bytes = createArrayBuffer(0x08, 0x01); 1949 const accessor = Kernel.fromArrayBuffer(bytes); 1950 expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(1)); 1951 // Make sure the value is cached. 1952 bytes[2] = 0x00; 1953 expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(1)); 1954 }); 1955 1956 it('throws in setter for invalid fieldNumber', () => { 1957 if (CHECK_BOUNDS) { 1958 expect(() => Kernel.createEmpty().setUint64(-1, Int64.fromInt(1))) 1959 .toThrowError('Field number is out of range: -1'); 1960 } else { 1961 const accessor = Kernel.createEmpty(); 1962 accessor.setUint64(-1, Int64.fromInt(1)); 1963 expect(accessor.getUint64WithDefault(-1)).toEqual(Int64.fromInt(1)); 1964 } 1965 }); 1966 1967 it('throws in setter for invalid value', () => { 1968 if (CHECK_CRITICAL_TYPE) { 1969 expect( 1970 () => Kernel.createEmpty().setUint64( 1971 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) 1972 .toThrow(); 1973 } else { 1974 const accessor = Kernel.createEmpty(); 1975 accessor.setUint64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); 1976 expect(accessor.getUint64WithDefault(1)).toEqual(null); 1977 } 1978 }); 1979}); 1980 1981describe('Double access', () => { 1982 it('returns default value for empty input', () => { 1983 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1984 expect(accessor.getDoubleWithDefault(1)).toEqual(0); 1985 }); 1986 1987 it('returns the default from parameter', () => { 1988 const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); 1989 expect(accessor.getDoubleWithDefault(1, 2)).toEqual(2); 1990 }); 1991 1992 it('decodes value from wire', () => { 1993 const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 1994 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F)); 1995 expect(accessor.getDoubleWithDefault(1)).toEqual(1); 1996 }); 1997 1998 1999 it('decodes value from wire with multple values being present', () => { 2000 const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 2001 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x09, 0x00, 0x00, 2002 0x00, 0x00, 0x00, 0x00, 0xF0, 0xBF)); 2003 expect(accessor.getDoubleWithDefault(1)).toEqual(-1); 2004 }); 2005 2006 if (CHECK_CRITICAL_STATE) { 2007 it('fails when getting double value with other wire types', () => { 2008 const accessor = Kernel.fromArrayBuffer( 2009 createArrayBuffer(0x0D, 0x00, 0x00, 0xF0, 0x3F)); 2010 expect(() => { 2011 accessor.getDoubleWithDefault(1); 2012 }).toThrow(); 2013 }); 2014 } 2015 2016 2017 it('throws in getter for invalid fieldNumber', () => { 2018 if (CHECK_BOUNDS) { 2019 expect(() => Kernel.createEmpty().getDoubleWithDefault(-1, 1)) 2020 .toThrowError('Field number is out of range: -1'); 2021 } else { 2022 expect(Kernel.createEmpty().getDoubleWithDefault(-1, 1)).toEqual(1); 2023 } 2024 }); 2025 2026 it('returns the value from setter', () => { 2027 const bytes = 2028 createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F); 2029 const accessor = Kernel.fromArrayBuffer(bytes); 2030 accessor.setDouble(1, 2); 2031 expect(accessor.getDoubleWithDefault(1)).toEqual(2); 2032 }); 2033 2034 it('encode the value from setter', () => { 2035 const bytes = 2036 createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F); 2037 const accessor = Kernel.fromArrayBuffer(bytes); 2038 const newBytes = 2039 createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); 2040 accessor.setDouble(1, 0); 2041 expect(accessor.serialize()).toEqual(newBytes); 2042 }); 2043 2044 it('returns string value from cache', () => { 2045 const bytes = 2046 createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F); 2047 const accessor = Kernel.fromArrayBuffer(bytes); 2048 expect(accessor.getDoubleWithDefault(1)).toBe(1); 2049 // Make sure the value is cached. 2050 bytes[2] = 0x00; 2051 expect(accessor.getDoubleWithDefault(1)).toBe(1); 2052 }); 2053 2054 it('throws in setter for invalid fieldNumber', () => { 2055 if (CHECK_BOUNDS) { 2056 expect(() => Kernel.createEmpty().setDouble(-1, 1)) 2057 .toThrowError('Field number is out of range: -1'); 2058 } else { 2059 const accessor = Kernel.createEmpty(); 2060 accessor.setDouble(-1, 1); 2061 expect(accessor.getDoubleWithDefault(-1)).toEqual(1); 2062 } 2063 }); 2064 2065 it('throws in setter for invalid value', () => { 2066 if (CHECK_CRITICAL_TYPE) { 2067 expect( 2068 () => Kernel.createEmpty().setDouble( 2069 1, /** @type {number} */ (/** @type {*} */ (null)))) 2070 .toThrowError('Must be a number, but got: null'); 2071 } else { 2072 const accessor = Kernel.createEmpty(); 2073 accessor.setDouble(1, /** @type {number} */ (/** @type {*} */ (null))); 2074 expect(accessor.getDoubleWithDefault(1)).toEqual(null); 2075 } 2076 }); 2077}); 2078 2079describe('Kernel for singular group does', () => { 2080 it('return group from the input', () => { 2081 const bytes = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); 2082 const accessor = Kernel.fromArrayBuffer(bytes); 2083 const msg = accessor.getGroupOrNull(1, TestMessage.instanceCreator); 2084 expect(msg.getBoolWithDefault(1, false)).toBe(true); 2085 }); 2086 2087 it('return group from the input when pivot is set', () => { 2088 const bytes = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); 2089 const accessor = Kernel.fromArrayBuffer(bytes); 2090 const msg = accessor.getGroupOrNull(1, TestMessage.instanceCreator, 0); 2091 expect(msg.getBoolWithDefault(1, false)).toBe(true); 2092 }); 2093 2094 it('encode group from the input', () => { 2095 const bytes = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); 2096 const accessor = Kernel.fromArrayBuffer(bytes); 2097 expect(accessor.serialize()).toEqual(bytes); 2098 }); 2099 2100 it('encode group from the input after read', () => { 2101 const bytes = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); 2102 const accessor = Kernel.fromArrayBuffer(bytes); 2103 accessor.getGroupOrNull(1, TestMessage.instanceCreator); 2104 expect(accessor.serialize()).toEqual(bytes); 2105 }); 2106 2107 it('return last group from multiple inputs', () => { 2108 const bytes = 2109 createArrayBuffer(0x0B, 0x08, 0x00, 0x0C, 0x0B, 0x08, 0x01, 0x0C); 2110 const accessor = Kernel.fromArrayBuffer(bytes); 2111 const msg = accessor.getGroupOrNull(1, TestMessage.instanceCreator); 2112 expect(msg.getBoolWithDefault(1, false)).toBe(true); 2113 }); 2114 2115 it('removes duplicated group when serializing', () => { 2116 const bytes = 2117 createArrayBuffer(0x0B, 0x08, 0x00, 0x0C, 0x0B, 0x08, 0x01, 0x0C); 2118 const accessor = Kernel.fromArrayBuffer(bytes); 2119 accessor.getGroupOrNull(1, TestMessage.instanceCreator); 2120 expect(accessor.serialize()) 2121 .toEqual(createArrayBuffer(0x0B, 0x08, 0x01, 0x0C)); 2122 }); 2123 2124 it('encode group from multiple inputs', () => { 2125 const bytes = 2126 createArrayBuffer(0x0B, 0x08, 0x00, 0x0C, 0x0B, 0x08, 0x01, 0x0C); 2127 const accessor = Kernel.fromArrayBuffer(bytes); 2128 expect(accessor.serialize()).toEqual(bytes); 2129 }); 2130 2131 it('encode group after read', () => { 2132 const bytes = 2133 createArrayBuffer(0x0B, 0x08, 0x00, 0x0C, 0x0B, 0x08, 0x01, 0x0C); 2134 const expected = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); 2135 const accessor = Kernel.fromArrayBuffer(bytes); 2136 accessor.getGroupOrNull(1, TestMessage.instanceCreator); 2137 expect(accessor.serialize()).toEqual(expected); 2138 }); 2139 2140 it('return group from setter', () => { 2141 const bytes = createArrayBuffer(0x08, 0x01); 2142 const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); 2143 const subaccessor = Kernel.fromArrayBuffer(bytes); 2144 const submsg1 = new TestMessage(subaccessor); 2145 accessor.setGroup(1, submsg1); 2146 const submsg2 = accessor.getGroup(1, TestMessage.instanceCreator); 2147 expect(submsg1).toBe(submsg2); 2148 }); 2149 2150 it('encode group from setter', () => { 2151 const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); 2152 const subaccessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); 2153 const submsg = new TestMessage(subaccessor); 2154 accessor.setGroup(1, submsg); 2155 const expected = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); 2156 expect(accessor.serialize()).toEqual(expected); 2157 }); 2158 2159 it('leave hasFieldNumber unchanged after getGroupOrNull', () => { 2160 const accessor = Kernel.createEmpty(); 2161 expect(accessor.hasFieldNumber(1)).toBe(false); 2162 expect(accessor.getGroupOrNull(1, TestMessage.instanceCreator)).toBe(null); 2163 expect(accessor.hasFieldNumber(1)).toBe(false); 2164 }); 2165 2166 it('serialize changes to subgroups made with getGroupsOrNull', () => { 2167 const intTwoBytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); 2168 const accessor = Kernel.fromArrayBuffer(intTwoBytes); 2169 const mutableSubMessage = 2170 accessor.getGroupOrNull(1, TestMessage.instanceCreator); 2171 mutableSubMessage.setInt32(1, 10); 2172 const intTenBytes = createArrayBuffer(0x0B, 0x08, 0x0A, 0x0C); 2173 expect(accessor.serialize()).toEqual(intTenBytes); 2174 }); 2175 2176 it('serialize additions to subgroups made with getGroupOrNull', () => { 2177 const intTwoBytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); 2178 const accessor = Kernel.fromArrayBuffer(intTwoBytes); 2179 const mutableSubMessage = 2180 accessor.getGroupOrNull(1, TestMessage.instanceCreator); 2181 mutableSubMessage.setInt32(2, 3); 2182 // Sub group contains the original field, plus the new one. 2183 expect(accessor.serialize()) 2184 .toEqual(createArrayBuffer(0x0B, 0x08, 0x02, 0x10, 0x03, 0x0C)); 2185 }); 2186 2187 it('fail with getGroupOrNull if immutable group exist in cache', () => { 2188 const intTwoBytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); 2189 const accessor = Kernel.fromArrayBuffer(intTwoBytes); 2190 2191 const readOnly = accessor.getGroup(1, TestMessage.instanceCreator); 2192 if (CHECK_TYPE) { 2193 expect(() => accessor.getGroupOrNull(1, TestMessage.instanceCreator)) 2194 .toThrow(); 2195 } else { 2196 const mutableSubGropu = 2197 accessor.getGroupOrNull(1, TestMessage.instanceCreator); 2198 // The instance returned by getGroupOrNull is the exact same instance. 2199 expect(mutableSubGropu).toBe(readOnly); 2200 2201 // Serializing the subgroup does not write the changes 2202 mutableSubGropu.setInt32(1, 0); 2203 expect(accessor.serialize()).toEqual(intTwoBytes); 2204 } 2205 }); 2206 2207 it('change hasFieldNumber after getGroupAttach', () => { 2208 const accessor = Kernel.createEmpty(); 2209 expect(accessor.hasFieldNumber(1)).toBe(false); 2210 expect(accessor.getGroupAttach(1, TestMessage.instanceCreator)) 2211 .not.toBe(null); 2212 expect(accessor.hasFieldNumber(1)).toBe(true); 2213 }); 2214 2215 it('change hasFieldNumber after getGroupAttach when pivot is set', () => { 2216 const accessor = Kernel.createEmpty(); 2217 expect(accessor.hasFieldNumber(1)).toBe(false); 2218 expect( 2219 accessor.getGroupAttach(1, TestMessage.instanceCreator, /* pivot= */ 1)) 2220 .not.toBe(null); 2221 expect(accessor.hasFieldNumber(1)).toBe(true); 2222 }); 2223 2224 it('serialize subgroups made with getGroupAttach', () => { 2225 const accessor = Kernel.createEmpty(); 2226 const mutableSubGroup = 2227 accessor.getGroupAttach(1, TestMessage.instanceCreator); 2228 mutableSubGroup.setInt32(1, 10); 2229 const intTenBytes = createArrayBuffer(0x0B, 0x08, 0x0A, 0x0C); 2230 expect(accessor.serialize()).toEqual(intTenBytes); 2231 }); 2232 2233 it('serialize additions to subgroups using getMessageAttach', () => { 2234 const intTwoBytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); 2235 const accessor = Kernel.fromArrayBuffer(intTwoBytes); 2236 const mutableSubGroup = 2237 accessor.getGroupAttach(1, TestMessage.instanceCreator); 2238 mutableSubGroup.setInt32(2, 3); 2239 // Sub message contains the original field, plus the new one. 2240 expect(accessor.serialize()) 2241 .toEqual(createArrayBuffer(0x0B, 0x08, 0x02, 0x10, 0x03, 0x0C)); 2242 }); 2243 2244 it('fail with getGroupAttach if immutable message exist in cache', () => { 2245 const intTwoBytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); 2246 const accessor = Kernel.fromArrayBuffer(intTwoBytes); 2247 2248 const readOnly = accessor.getGroup(1, TestMessage.instanceCreator); 2249 if (CHECK_TYPE) { 2250 expect(() => accessor.getGroupAttach(1, TestMessage.instanceCreator)) 2251 .toThrow(); 2252 } else { 2253 const mutableSubGroup = 2254 accessor.getGroupAttach(1, TestMessage.instanceCreator); 2255 // The instance returned by getMessageOrNull is the exact same instance. 2256 expect(mutableSubGroup).toBe(readOnly); 2257 2258 // Serializing the submessage does not write the changes 2259 mutableSubGroup.setInt32(1, 0); 2260 expect(accessor.serialize()).toEqual(intTwoBytes); 2261 } 2262 }); 2263 2264 it('read default group return empty group with getGroup', () => { 2265 const bytes = new ArrayBuffer(0); 2266 const accessor = Kernel.fromArrayBuffer(bytes); 2267 expect(accessor.getGroup(1, TestMessage.instanceCreator)).toBeTruthy(); 2268 expect(accessor.getGroup(1, TestMessage.instanceCreator).serialize()) 2269 .toEqual(bytes); 2270 }); 2271 2272 it('read default group return null with getGroupOrNull', () => { 2273 const bytes = new ArrayBuffer(0); 2274 const accessor = Kernel.fromArrayBuffer(bytes); 2275 expect(accessor.getGroupOrNull(1, TestMessage.instanceCreator)).toBe(null); 2276 }); 2277 2278 it('read group preserve reference equality', () => { 2279 const bytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); 2280 const accessor = Kernel.fromArrayBuffer(bytes); 2281 const msg1 = accessor.getGroupOrNull(1, TestMessage.instanceCreator); 2282 const msg2 = accessor.getGroupOrNull(1, TestMessage.instanceCreator); 2283 const msg3 = accessor.getGroupAttach(1, TestMessage.instanceCreator); 2284 expect(msg1).toBe(msg2); 2285 expect(msg1).toBe(msg3); 2286 }); 2287 2288 it('fail when getting group with null instance constructor', () => { 2289 const accessor = 2290 Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x02, 0x08, 0x01)); 2291 const nullMessage = /** @type {function(!Kernel):!TestMessage} */ 2292 (/** @type {*} */ (null)); 2293 expect(() => accessor.getGroupOrNull(1, nullMessage)).toThrow(); 2294 }); 2295 2296 it('fail when setting group value with null value', () => { 2297 const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); 2298 const fakeMessage = /** @type {!TestMessage} */ (/** @type {*} */ (null)); 2299 if (CHECK_CRITICAL_TYPE) { 2300 expect(() => accessor.setGroup(1, fakeMessage)) 2301 .toThrowError('Given value is not a message instance: null'); 2302 } else { 2303 // Note in unchecked mode we produce invalid output for invalid inputs. 2304 // This test just documents our behavior in those cases. 2305 // These values might change at any point and are not considered 2306 // what the implementation should be doing here. 2307 accessor.setMessage(1, fakeMessage); 2308 expect(accessor.getGroupOrNull( 2309 /* fieldNumber= */ 1, TestMessage.instanceCreator)) 2310 .toBeNull(); 2311 } 2312 }); 2313 2314 it('reads group in a longer buffer', () => { 2315 const bytes = createArrayBuffer( 2316 0x12, 0x20, // 32 length delimited 2317 0x00, // random values for padding start 2318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2321 0x00, // random values for padding end 2322 0x0B, // Group tag 2323 0x08, 0x02, 0x0C); 2324 const accessor = Kernel.fromArrayBuffer(bytes); 2325 const msg1 = accessor.getGroupOrNull(1, TestMessage.instanceCreator); 2326 const msg2 = accessor.getGroupOrNull(1, TestMessage.instanceCreator); 2327 expect(msg1).toBe(msg2); 2328 }); 2329}); 2330